extends Node class_name GameManager @export var dragon_template: PackedScene @export var dragon_ingame: PackedScene @export var dragon_spots: Array[Node2D] var _filled_spots: Dictionary[Node2D, int] @export var hat_outfits: DragonOutfit @export var shirt_outfits: DragonOutfit @export var shoes_outfits: DragonOutfit var _instantiator: DragonInstantiator var _save_load: SaveLoad var _library: DragonLibrary var _dragon_entities: Dictionary[int, Dragon] = {} var _instantiated_dragons: Dictionary[int, DragonEntity] = {} var rng: RandomNumberGenerator = RandomNumberGenerator.new() @export var min_dragon_instantiation_time: float @export var max_dragon_instantiation_time: float func _ready(): _library = DragonLibrary.new(hat_outfits, shirt_outfits, shoes_outfits) _instantiator = DragonInstantiator.new(dragon_template, get_viewport(), get_window()) _save_load = SaveLoad.new() await get_tree().process_frame move_window_to_bottom_right() _load_game() _queue_dragon_instantiation() func _queue_dragon_instantiation(): await get_tree().create_timer(rng.randf_range(min_dragon_instantiation_time, max_dragon_instantiation_time)).timeout _instantiate_random_dragon() func _instantiate_random_dragon(): for spot in dragon_spots: if not _filled_spots.has(spot): var dragon: DragonEntity = _pick_random_dragon(spot.position) if dragon != null: _filled_spots[spot] = dragon.id break _queue_dragon_instantiation() func _pick_random_dragon(pos: Vector2) -> DragonEntity: for dragon in _library.dragons: var id: int = dragon['id'] if _instantiated_dragons.has(id) or _dragon_entities.has(id): continue var dragon_name: String = dragon['name'] var hat: Texture2D = hat_outfits.get_texture(dragon['hat']) var shirt: Texture2D = shirt_outfits.get_texture(dragon['shirt']) var shoes: Texture2D = shoes_outfits.get_texture(dragon['shoes']) return _instantiate_dragon_ingame(pos, hat, shirt, shoes, dragon_name, id) return null func move_window_to_bottom_right(): var display_index: int = DisplayServer.window_get_current_screen() var work_area_position: Vector2i = DisplayServer.screen_get_usable_rect(display_index).position var work_area_size: Vector2i = DisplayServer.screen_get_usable_rect(display_index).size var window_size: Vector2i = Vector2i(work_area_size.y / 4 * 1.77777, work_area_size.y / 4) var new_position: Vector2i = work_area_position + Vector2i(work_area_size.x - window_size.x, work_area_size.y - window_size.y) DisplayServer.window_set_size(window_size) DisplayServer.window_set_position(new_position) func add_dragon(hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String): var id: int = _library.add_dragon(dragon_name, hat, shirt, shoes) for spot in dragon_spots: if not _filled_spots.has(spot): _instantiate_dragon_ingame(spot.position, hat, shirt, shoes, dragon_name, id) _filled_spots[spot] = id break func _load_game(): _save_load.load() var dragons: Array = _save_load.get_dragons() _library.add_dragons(dragons) for d in dragons: if d['pos'] != Vector2i(0, 0): var hat: Texture2D = hat_outfits.get_texture(d['hat']) var shirt: Texture2D = shirt_outfits.get_texture(d['shirt']) var shoes: Texture2D = shoes_outfits.get_texture(d['shoes']) _pick_dragon(d['id'], d['pos'], hat, shirt, shoes, d['name'], false) print(_save_load.contents_to_save) func _instantiate_dragon_ingame(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, id: int) -> DragonEntity: var dragon: DragonEntity = dragon_ingame.instantiate() dragon.dress(hat, shirt, shoes) dragon.set_dragon_name(dragon_name) add_child(dragon) dragon.id = id dragon.position = position dragon.on_pick.connect(_pick_dragon) _instantiated_dragons[id] = dragon return dragon func _pick_dragon(id: int, position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, drag: bool = true): var dragon: Dragon = _instantiator.instantiate(position, hat, shirt, shoes, dragon_name, drag) dragon.id = id _dragon_entities[id] = dragon dragon.place_back.connect(_dragon_place_back) add_child(dragon) _instantiated_dragons.erase(id) for spot in _filled_spots: if _filled_spots[spot] == id: _filled_spots.erase(spot) func _dragon_place_back(dragon: Dragon): _dragon_entities.erase(dragon.id) func _on_close_pressed() -> void: _save_load.clear_dragons() for d in _library.dragons: if _dragon_entities.has(d['id']) and _dragon_entities[d['id']] != null: _save_load.add_dragon(d['id'], d['name'], d['hat'], d['shirt'], d['shoes'], _dragon_entities[d['id']].position) else: _save_load.add_dragon(d['id'], d['name'], d['hat'], d['shirt'], d['shoes'], Vector2i(0, 0)) _save_load.save() await get_tree().process_frame await get_tree().process_frame await get_tree().process_frame await get_tree().process_frame await get_tree().process_frame get_tree().quit()