about summary refs log tree commit diff stats
path: root/apworld/locations.py
blob: 108decb845a6dfd04f05648a96ee670cf56ddd0a (plain) (blame)
1
2
3
4
5
from BaseClasses import Location


class Lingo2Location(Location):
    game: str = "Lingo 2"
87 188 189 190 191 192 193 194 195 196 197 198 199
extends Node

const kALL_LETTERS = "abcdefghjiklmnopqrstuvwxyz"

var letters_saved = {}
var letters_in_keyholders = []
var letters_blocked = []
var letters_dynamic = {}
var keyholder_state = {}

var filename = ""


func _init():
	reset()


func reset():
	letters_saved.clear()
	letters_in_keyholders.clear()
	letters_blocked.clear()
	letters_dynamic.clear()
	keyholder_state.clear()


func load_seed():
	var ap = global.get_node("Archipelago")

	reset()

	filename = "user://archipelago_keys/%s_%d" % [ap.client._seed, ap.client._slot]

	if FileAccess.file_exists(filename):
		var ap_file = FileAccess.open(filename, FileAccess.READ)
		var localdata = []
		if ap_file != null:
			localdata = ap_file.get_var(true)
			ap_file.close()

		if typeof(localdata) != TYPE_ARRAY:
			print("AP keyboard file is corrupted")
			localdata = []

		if localdata.size() > 0:
			letters_saved = localdata[0]
		if localdata.size() > 1:
			letters_in_keyholders = localdata[1]
		if localdata.size() > 2:
			keyholder_state = localdata[2]

	for k in kALL_LETTERS:
		var level = 0

		if ap.get_letter_behavior(k, false) == ap.kLETTER_BEHAVIOR_UNLOCKED:
			level += 1
		if ap.get_letter_behavior(k, true) == ap.kLETTER_BEHAVIOR_UNLOCKED:
			level += 1

		letters_dynamic[k] = level

	update_unlocks()


func save():
	var dir = DirAccess.open("user://")
	var folder = "archipelago_keys"
	if not dir.dir_exists(folder):
		dir.make_dir(folder)

	var file = FileAccess.open(filename, FileAccess.WRITE)

	var data = [
		letters_saved,
		letters_in_keyholders,
		keyholder_state,
	]
	file.store_var(data, true)
	file.close()


func update_unlocks():
	unlocks.resetKeys()

	var has_doubles = false

	for k in kALL_LETTERS:
		var level = 0

		if not letters_in_keyholders.has(k):
			level = letters_saved.get(k, 0) + letters_dynamic.get(k, 0)

		if level >= 2:
			level = 2
			has_doubles = true

		if letters_blocked.has(k):
			level = 0

		unlocks.unlockKey(k, level)

	if has_doubles and unlocks.data["double_letters"] != "unlocked":
		var ap = global.get_node("Archipelago")
		if ap.cyan_door_behavior == ap.kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER:
			unlocks.setData("double_letters", "unlocked")


func collect_local_letter(key, level):
	if level < 0 or level > 2 or level < letters_saved.get(key, 0):
		return

	letters_saved[key] = level

	if letters_blocked.has(key):
		letters_blocked.erase(key)

	update_unlocks()
	save()


func collect_remote_letter(key, level):
	if level < 0 or level > 2 or level < letters_dynamic.get(key, 0):
		return

	letters_dynamic[key] = level

	if letters_blocked.has(key):
		letters_blocked.erase(key)

	update_unlocks()
	save()


func put_in_keyholder(key, map, kh_path):
	if not keyholder_state.has(map):
		keyholder_state[map] = {}

	keyholder_state[map][kh_path] = key
	letters_in_keyholders.append(key)

	get_tree().get_root().get_node("scene").get_node(kh_path).setFromAp(
		key, min(letters_saved.get(key, 0) + letters_dynamic.get(key, 0), 2)
	)

	update_unlocks()
	save()


func remove_from_keyholder(key, map, kh_path):
	if not keyholder_state.has(map):
		# This... shouldn't happen.
		keyholder_state[map] = {}

	keyholder_state[map].erase(kh_path)
	letters_in_keyholders.erase(key)

	get_tree().get_root().get_node("scene").get_node(kh_path).setFromAp(key, 0)

	update_unlocks()
	save()


func block_letter(key):
	if not letters_blocked.has(key):
		letters_blocked.append(key)

	update_unlocks()


func load_keyholders(map):
	if keyholder_state.has(map):
		var khs = keyholder_state[map]

		for path in khs.keys():
			var key = khs[path]
			get_tree().get_root().get_node("scene").get_node(path).setFromAp(
				key, min(letters_saved.get(key, 0) + letters_dynamic.get(key, 0), 2)
			)


func reset_keyholders():
	if letters_in_keyholders.is_empty() and letters_blocked.is_empty():
		return false

	var cleared_anything = not letters_in_keyholders.is_empty() or not letters_blocked.is_empty()

	if keyholder_state.has(global.map):
		for path in keyholder_state[global.map]:
			get_tree().get_root().get_node("scene").get_node(path).setFromAp(
				keyholder_state[global.map][path], 0
			)

	keyholder_state.clear()
	letters_in_keyholders.clear()
	letters_blocked.clear()

	update_unlocks()
	save()

	return cleared_anything