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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
|
extends Node
const my_version = "0.1.0"
var SCRIPT_client
var SCRIPT_locationListener
var SCRIPT_uuid
var ap_server = ""
var ap_user = ""
var ap_pass = ""
var connection_history = []
var client
var _localdata_file = ""
var _received_indexes = []
var _last_new_item = -1
var _batch_locations = false
var _held_locations = []
signal could_not_connect
signal connect_status
signal ap_connected
func _init():
# Read AP settings from file, if there are any
if FileAccess.file_exists("user://ap_settings"):
var file = FileAccess.open("user://ap_settings", FileAccess.READ)
var data = file.get_var(true)
file.close()
if typeof(data) != TYPE_ARRAY:
global._print("AP settings file is corrupted")
data = []
if data.size() > 0:
ap_server = data[0]
if data.size() > 1:
ap_user = data[1]
if data.size() > 2:
ap_pass = data[2]
if data.size() > 3:
connection_history = data[3]
func _ready():
client = SCRIPT_client.new()
client.SCRIPT_uuid = SCRIPT_uuid
client.connect("item_received", _process_item)
client.connect("message_received", _process_message)
client.connect("could_not_connect", _client_could_not_connect)
client.connect("connect_status", _client_connect_status)
client.connect("client_connected", _client_connected)
add_child(client)
func saveSettings():
# Save the AP settings to disk.
var path = "user://ap_settings"
var file = FileAccess.open(path, FileAccess.WRITE)
var data = [
ap_server,
ap_user,
ap_pass,
connection_history,
]
file.store_var(data, true)
file.close()
func saveLocaldata():
# Save the MW/slot specific settings to disk.
var dir = DirAccess.open("user://")
var folder = "archipelago_data"
if not dir.dir_exists(folder):
dir.make_dir(folder)
var file = FileAccess.open(_localdata_file, FileAccess.WRITE)
var data = [
_last_new_item,
]
file.store_var(data, true)
file.close()
func connectToServer():
_received_indexes = []
_last_new_item = -1
client.connectToServer(ap_server, ap_user, ap_pass)
func getSaveFileName():
return "zzAP_%s_%d" % [client._seed, client._slot]
func disconnect_from_ap():
client.disconnect_from_ap()
func get_item_id_for_door(door_id):
var gamedata = global.get_node("Gamedata")
var door = gamedata.objects.get_doors()[door_id]
if (
door.get_type() == gamedata.SCRIPT_proto.DoorType.EVENT
or door.get_type() == gamedata.SCRIPT_proto.DoorType.LOCATION_ONLY
or door.get_type() == gamedata.SCRIPT_proto.DoorType.CONTROL_CENTER_COLOR
):
return null
return gamedata.get_door_ap_id(door_id)
func has_item(item_id):
return client.hasItem(item_id)
func _process_item(item, index, from, flags):
if index != null:
if _received_indexes.has(index):
# Do not re-process items.
return
_received_indexes.append(index)
var item_name = "Unknown"
if client._item_id_to_name["Lingo 2"].has(item):
item_name = client._item_id_to_name["Lingo 2"][item]
var gamedata = global.get_node("Gamedata")
var door_id = gamedata.door_id_by_ap_id.get(item, null)
if door_id != null and gamedata.get_door_map_name(door_id) == global.map:
var receivers = gamedata.get_door_receivers(door_id)
var scene = get_tree().get_root().get_node_or_null("scene")
if scene != null:
for receiver in receivers:
var rnode = scene.get_node_or_null(receiver)
if rnode != null:
rnode.handleTriggered()
#for painting_id in gamedata.objects.get_doors()[door_id].get_move_paintings():
# var painting = gamedata.objects.get_paintings()[painting_id]
# var pnode = scene.get_node_or_null(painting.get_path() + "/teleportListener")
# if pnode != null:
# pnode.handleTriggered()
# Show a message about the item if it's new.
if index != null and index > _last_new_item:
_last_new_item = index
saveLocaldata()
var player_name = "Unknown"
if client._player_name_by_slot.has(from):
player_name = client._player_name_by_slot[from]
var item_color = colorForItemType(flags)
var message
if from == client._slot:
message = "Found [color=%s]%s[/color]" % [item_color, item_name]
else:
message = "Received [color=%s]%s[/color] from %s" % [item_color, item_name, player_name]
global._print(message)
global.get_node("Messages").showMessage(message)
func _process_message(message):
parse_printjson_for_textclient(message)
if (
!message.has("receiving")
or !message.has("item")
or message["item"]["player"] != client._slot
):
return
var item_name = "Unknown"
var item_player_game = client._game_by_player[message["receiving"]]
if client._item_id_to_name[item_player_game].has(message["item"]["item"]):
item_name = client._item_id_to_name[item_player_game][message["item"]["item"]]
var location_name = "Unknown"
var location_player_game = client._game_by_player[message["item"]["player"]]
if client._location_id_to_name[location_player_game].has(message["item"]["location"]):
location_name = (
client._location_id_to_name[location_player_game][message["item"]["location"]]
)
var player_name = "Unknown"
if client._player_name_by_slot.has(message["receiving"]):
player_name = client._player_name_by_slot[message["receiving"]]
var item_color = colorForItemType(message["item"]["flags"])
if message["type"] == "Hint":
var is_for = ""
if message["receiving"] != client._slot:
is_for = " for %s" % player_name
if !message.has("found") || !message["found"]:
global.get_node("Messages").showMessage(
(
"Hint: [color=%s]%s[/color]%s is on %s"
% [item_color, item_name, is_for, location_name]
)
)
else:
if message["receiving"] != client._slot:
var sentMsg = "Sent [color=%s]%s[/color] to %s" % [item_color, item_name, player_name]
#if _hinted_locations.has(message["item"]["location"]):
# sentMsg += " ([color=#fafad2]Hinted![/color])"
global.get_node("Messages").showMessage(sentMsg)
func parse_printjson_for_textclient(message):
var parts = []
for message_part in message["data"]:
if !message_part.has("type") and message_part.has("text"):
parts.append(message_part["text"])
elif message_part["type"] == "player_id":
if int(message_part["text"]) == client._slot:
parts.append(
"[color=#ee00ee]%s[/color]" % client._player_name_by_slot[client._slot]
)
else:
var from = float(message_part["text"])
parts.append("[color=#fafad2]%s[/color]" % client._player_name_by_slot[from])
elif message_part["type"] == "item_id":
var item_name = "Unknown"
var item_player_game = client._game_by_player[message_part["player"]]
if client._item_id_to_name[item_player_game].has(int(message_part["text"])):
item_name = client._item_id_to_name[item_player_game][int(message_part["text"])]
parts.append(
"[color=%s]%s[/color]" % [colorForItemType(message_part["flags"]), item_name]
)
elif message_part["type"] == "location_id":
var location_name = "Unknown"
var location_player_game = client._game_by_player[message_part["player"]]
if client._location_id_to_name[location_player_game].has(int(message_part["text"])):
location_name = client._location_id_to_name[location_player_game][int(
message_part["text"]
)]
parts.append("[color=#00ff7f]%s[/color]" % location_name)
elif message_part.has("text"):
parts.append(message_part["text"])
var textclient_node = global.get_node("Textclient")
if textclient_node != null:
textclient_node.parse_printjson("".join(parts))
func _client_could_not_connect():
emit_signal("could_not_connect")
func _client_connect_status(message):
emit_signal("connect_status", message)
func _client_connected():
_localdata_file = "user://archipelago_data/%s_%d" % [client._seed, client._slot]
_last_new_item = -1
if FileAccess.file_exists(_localdata_file):
var ap_file = FileAccess.open(_localdata_file, FileAccess.READ)
var localdata = []
if ap_file != null:
localdata = ap_file.get_var(true)
ap_file.close()
if typeof(localdata) != TYPE_ARRAY:
print("AP localdata file is corrupted")
localdata = []
if localdata.size() > 0:
_last_new_item = localdata[0]
emit_signal("ap_connected")
func start_batching_locations():
_batch_locations = true
func send_location(loc_id):
if _batch_locations:
_held_locations.append(loc_id)
else:
client.sendLocation(loc_id)
func stop_batching_locations():
_batch_locations = false
client.sendLocations(_held_locations)
_held_locations.clear()
func colorForItemType(flags):
var int_flags = int(flags)
if int_flags & 1: # progression
if int_flags & 2: # proguseful
return "#f0d200"
else:
return "#bc51e0"
elif int_flags & 2: # useful
return "#2b67ff"
elif int_flags & 4: # trap
return "#d63a22"
else: # filler
return "#14de9e"
|