about summary refs log tree commit diff stats
path: root/client/Archipelago/keyboard.gd
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2025-09-06 09:20:28 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2025-09-06 09:20:28 -0400
commitbb4b16ca06c70cf263424955713c91117f2f1813 (patch)
tree1f234246ad48a2472904e92a6ff48fc7f13e1c49 /client/Archipelago/keyboard.gd
parentebda0b634c2396338b86b45128bf507c967e88a7 (diff)
downloadlingo2-archipelago-bb4b16ca06c70cf263424955713c91117f2f1813.tar.gz
lingo2-archipelago-bb4b16ca06c70cf263424955713c91117f2f1813.tar.bz2
lingo2-archipelago-bb4b16ca06c70cf263424955713c91117f2f1813.zip
[Client] Handle letter shuffle
Cyan doors are not handled properly yet.
Diffstat (limited to 'client/Archipelago/keyboard.gd')
-rw-r--r--client/Archipelago/keyboard.gd170
1 files changed, 170 insertions, 0 deletions
diff --git a/client/Archipelago/keyboard.gd b/client/Archipelago/keyboard.gd new file mode 100644 index 0000000..e43ec9f --- /dev/null +++ b/client/Archipelago/keyboard.gd
@@ -0,0 +1,170 @@
1extends Node
2
3const kALL_LETTERS = "abcdefghjiklmnopqrstuvwxyz"
4
5var letters_saved = {}
6var letters_in_keyholders = []
7var letters_dynamic = {}
8var keyholder_state = {}
9
10var filename = ""
11
12
13func _init():
14 reset()
15
16
17func reset():
18 letters_saved.clear()
19 letters_in_keyholders.clear()
20 letters_dynamic.clear()
21 keyholder_state.clear()
22
23
24func load_seed():
25 var ap = global.get_node("Archipelago")
26
27 reset()
28
29 filename = "user://archipelago_keys/%s_%d" % [ap.client._seed, ap.client._slot]
30
31 if FileAccess.file_exists(filename):
32 var ap_file = FileAccess.open(filename, FileAccess.READ)
33 var localdata = []
34 if ap_file != null:
35 localdata = ap_file.get_var(true)
36 ap_file.close()
37
38 if typeof(localdata) != TYPE_ARRAY:
39 print("AP keyboard file is corrupted")
40 localdata = []
41
42 if localdata.size() > 0:
43 letters_saved = localdata[0]
44 if localdata.size() > 1:
45 letters_in_keyholders = localdata[1]
46 if localdata.size() > 2:
47 keyholder_state = localdata[2]
48
49 for k in kALL_LETTERS:
50 var level = 0
51
52 if ap.get_letter_behavior(k, false) == ap.kLETTER_BEHAVIOR_UNLOCKED:
53 level += 1
54 if ap.get_letter_behavior(k, true) == ap.kLETTER_BEHAVIOR_UNLOCKED:
55 level += 1
56
57 letters_dynamic[k] = level
58
59 update_unlocks()
60
61
62func save():
63 var dir = DirAccess.open("user://")
64 var folder = "archipelago_keys"
65 if not dir.dir_exists(folder):
66 dir.make_dir(folder)
67
68 var file = FileAccess.open(filename, FileAccess.WRITE)
69
70 var data = [
71 letters_saved,
72 letters_in_keyholders,
73 keyholder_state,
74 ]
75 file.store_var(data, true)
76 file.close()
77
78
79func update_unlocks():
80 unlocks.resetKeys()
81
82 for k in kALL_LETTERS:
83 var level = 0
84
85 if not letters_in_keyholders.has(k):
86 level = letters_saved.get(k, 0) + letters_dynamic.get(k, 0)
87
88 if level > 2:
89 level = 2
90
91 unlocks.unlockKey(k, level)
92
93
94func collect_local_letter(key, level):
95 if level < 0 or level > 2 or level < letters_saved.get(key, 0):
96 return
97
98 letters_saved[key] = level
99
100 update_unlocks()
101 save()
102
103
104func collect_remote_letter(key, level):
105 if level < 0 or level > 2 or level < letters_dynamic.get(key, 0):
106 return
107
108 letters_dynamic[key] = level
109
110 update_unlocks()
111 save()
112
113
114func put_in_keyholder(key, map, kh_path):
115 if not keyholder_state.has(map):
116 keyholder_state[map] = {}
117
118 keyholder_state[map][kh_path] = key
119 letters_in_keyholders.append(key)
120
121 get_tree().get_root().get_node("scene").get_node(kh_path).setFromAp(
122 key, min(letters_saved.get(key, 0) + letters_dynamic.get(key, 0), 2)
123 )
124
125 update_unlocks()
126 save()
127
128
129func remove_from_keyholder(key, map, kh_path):
130 if not keyholder_state.has(map):
131 # This... shouldn't happen.
132 keyholder_state[map] = {}
133
134 keyholder_state[map].erase(kh_path)
135 letters_in_keyholders.erase(key)
136
137 get_tree().get_root().get_node("scene").get_node(kh_path).setFromAp(key, 0)
138
139 update_unlocks()
140 save()
141
142
143func load_keyholders(map):
144 if keyholder_state.has(map):
145 var khs = keyholder_state[map]
146
147 for path in khs.keys():
148 var key = khs[path]
149 get_tree().get_root().get_node("scene").get_node(path).setFromAp(
150 key, min(letters_saved.get(key, 0) + letters_dynamic.get(key, 0), 2)
151 )
152
153
154func reset_keyholders():
155 if letters_in_keyholders.is_empty():
156 return false
157
158 if keyholder_state.has(global.map):
159 for path in keyholder_state[global.map]:
160 get_tree().get_root().get_node("scene").get_node(path).setFromAp(
161 keyholder_state[global.map][path], 0
162 )
163
164 keyholder_state.clear()
165 letters_in_keyholders.clear()
166
167 update_unlocks()
168 save()
169
170 return true