La-Torreta-del-Drac/scenes/main.gd

225 lines
6.6 KiB
GDScript

extends Node
class_name GameManager
@export var dragon_template: PackedScene
@export var dragon_ingame: PackedScene
@export var name_setter: PackedScene
@export var dragon_spots: Array[Node2D]
@export var dragon_start_spots: Dictionary[Node2D, Node2D]
var _filled_spots: Dictionary[Node2D, int]
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
@onready var dragon_sharing: DragonSharing = $HTTPRequest
func _ready():
_library = DragonLibrary.new()
_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()
if _save_load.get_tower_name() == "":
_show_name_setter_screen()
_queue_dragon_instantiation()
func _show_name_setter_screen():
var setter: NameSetter = name_setter.instantiate()
setter.set_save_load(_save_load)
add_child(setter)
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 new_position: Vector2i = work_area_position + Vector2i(work_area_size.x / 2.0 - setter.size.x / 2.0, work_area_size.y / 2.0 - setter.size.y / 2.0)
setter.position = new_position
func _queue_dragon_instantiation():
await get_tree().create_timer(rng.randf_range(min_dragon_instantiation_time, max_dragon_instantiation_time)).timeout
if _save_load.get_tower_name() != "":
_instantiate_random_dragon()
_queue_dragon_instantiation()
func _instantiate_random_dragon():
var spot: Node2D = _get_free_spot()
if spot == null:
return
var r = rng.randi_range(0, 99)
if r >= 30:
_instantiate_dragon_from_internet(spot)
else:
_instantiate_dragon_from_library(spot)
func _instantiate_dragon_from_library(spot: Node2D) -> void:
var dragons_available: Array[DragonProperties] = []
for dragon in _library.dragons:
if not _is_dragon_instantiated(dragon):
dragons_available.push_back(dragon)
if dragons_available.size() == 0:
_instantiate_dragon_from_internet(spot)
return
var r = rng.randi_range(0, dragons_available.size() - 1)
var dragon_entity: DragonEntity = _generate_entity(spot, dragons_available[r])
_filled_spots[spot] = dragon_entity.properties.id
func _is_dragon_instantiated(dragon: DragonProperties) -> bool:
for entity: Dragon in _dragon_entities.values():
if _are_properties_equal(entity.properties, dragon):
return true
for entity: DragonEntity in _instantiated_dragons.values():
if _are_properties_equal(entity.properties, dragon):
return true
return false
func _are_properties_equal(p1: DragonProperties, p2: DragonProperties) -> bool:
if p1.name != p2.name:
return false
if p1.origin != p2.origin:
return false
if p1.color != p2.color:
return false
if p1.hat != p2.hat:
return false
if p1.shirt != p2.shirt:
return false
if p1.decor != p2.decor:
return false
return true
func _instantiate_dragon_from_internet(spot: Node2D) -> void:
for i in range(5):
dragon_sharing.receive(_save_load.get_tower_name())
var dragon: DragonProperties = await dragon_sharing.on_dragon_received
if dragon == null:
return
if _is_dragon_instantiated(dragon):
continue
var dragon_entity: DragonEntity = _generate_entity(spot, dragon)
_filled_spots[spot] = dragon_entity.properties.id
return
func _get_free_spot() -> Node2D:
for spot in dragon_spots:
if not _filled_spots.has(spot):
return spot
return null
func _generate_entity(spot: Node2D, properties: DragonProperties) -> DragonEntity:
properties.id = rng.randi()
return _instantiate_dragon_ingame(spot, properties)
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 = DisplayServer.window_get_size()
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(properties: DragonProperties):
var id: int = _library.add_dragon(properties)
dragon_sharing.send(properties)
for spot in dragon_spots:
if not _filled_spots.has(spot):
_instantiate_dragon_ingame(spot, properties)
_filled_spots[spot] = id
break
func _load_game():
_save_load.load()
var dragons: Array[DragonProperties] = _save_load.get_dragons()
_library.add_dragons(dragons)
for d: DragonProperties in dragons:
if d.position != Vector2i(0, 0):
_pick_dragon(d, false)
print(_save_load.contents_to_save)
func _instantiate_dragon_ingame(spot: Node2D, properties: DragonProperties) -> DragonEntity:
var dragon: DragonEntity = dragon_ingame.instantiate()
spot.add_child(dragon)
dragon.dress(properties)
dragon.properties = properties
dragon.on_pick.connect(_pick_dragon)
dragon.on_quit.connect(_quit_dragon)
_instantiated_dragons[properties.id] = dragon
dragon.play_initial_animation(dragon_start_spots[spot])
return dragon
func _pick_dragon(properties: DragonProperties, drag: bool = true):
var dragon: Dragon = _instantiator.instantiate(properties, drag)
_dragon_entities[properties.id] = dragon
dragon.place_back.connect(_dragon_place_back)
add_child(dragon)
_instantiated_dragons.erase(properties.id)
if not _library.has(properties):
_library.add_dragon(properties)
for spot in _filled_spots:
if _filled_spots[spot] == properties.id:
_filled_spots.erase(spot)
func _quit_dragon(id: int):
_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.properties.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)
else:
d.position = Vector2i(0, 0)
_save_load.add_dragon(d)
_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()