extends Node2D ## Autoload GameController object for handling game logic ## Signals # Save/load signal game_loaded(stashed_data) signal game_saved(level, time_remaining, player_health, enemies_dictionary) # Player health signal player_damaged(health, max_health) signal player_death # Other signal coin_collected(coins_remaining) signal destroyed(body) signal level_changed(level) signal timer_updated(time_remaining) ## Member variables # Coins var coins_collected : int = 0 var total_coins : int = 0 # Levels var level_names : Array = DirAccess.open("res://scenes/levels").get_files() var levels : Array var current_level = 0 # Save/load var stash_data : Dictionary = {} # Timers var timers = [10, 15, 20] var time_available : int = 0 var timer = Timer.new() # Characters var enemy_stats : CharacterStats var player_stats : CharacterStats var enemies_dict : Dictionary = {} var player_current_health : int = 0 func _ready() -> void: # test file loading from folder print_debug("Raw level names: " + str(level_names)) for level_name in level_names: var level_path = "res://scenes/levels/" + level_name levels.append(level_path) print_debug("Adjusted level names: " + str(levels)) # load in characters enemy_stats = load("res://resources/slime_stats.tres") player_stats = load("res://resources/player_stats.tres") player_current_health = player_stats.starting_health add_child(timer) timer.wait_time = 1.0 timer.one_shot = false timer.connect("timeout", second_counter) timer.start() func _process(_delta: float) -> void: if Input.is_action_just_pressed("save"): save_game() pass if Input.is_action_just_pressed("load"): load_game() pass func second_counter() -> void: time_available -= 1 timer_updated.emit(time_available) if time_available <= 0: print_debug("You ran out of time! Emitting level_changed signal") level_changed.emit(levels[current_level]) func reset() -> void: print_debug("Resetting the level") enemies_dict.clear() player_current_health = player_stats["starting_health"] time_available = timers[current_level] func on_coin_collected(_body, coin) -> void: print_debug("GC knows coin collected") coins_collected += 1 print_debug("Coins collected: %s" % str(coins_collected)) print_debug("There are %s coins remaining" % str(total_coins - coins_collected)) destroyed.emit(coin) func set_total_coins(value) -> void: coin_collected.emit(value) print_debug("Setting coin total to %s" % str(value)) if value == 0: print_debug("You beat Level %s!" % levels[current_level]) current_level += 1 if current_level >= levels.size(): current_level = 0 level_changed.emit(levels[current_level]) print_debug("There are %s coins in the level" % str(value)) func on_player_slimed(_body, slime) -> void: print_debug("GC knows player slimed") print_debug("Damage: " + str(enemies_dict[slime]["damage"])) player_current_health -= enemies_dict[slime]["damage"] if player_current_health <= 0: print_debug("Player dead!") player_death.emit() else: print_debug("Taking damage") player_damaged.emit(player_current_health, player_stats.starting_health) print_debug("Player Health: " + str(player_current_health) + " of " + str(player_stats.starting_health)) func handle_player_death() -> void: level_changed.emit(levels[current_level]) func add_enemy_to_level(enemy, _stat = null) -> void: print_debug("GC adding %s to level" % enemy.name) var rand_damage : int = randi() % 10 var this_enemy_stats : Dictionary = { "health": enemy_stats.health, "damage": enemy_stats.melee_damage + rand_damage } if _stat: this_enemy_stats.health = _stat.health this_enemy_stats.damage = _stat.damage print_debug("This enemy's health is %s and its damage is %s" % [this_enemy_stats.health, this_enemy_stats.damage]) enemies_dict[enemy] = this_enemy_stats func bullet_damage(thing_damaged, _bullet) -> void: print_debug("Bullet has hit %s" % thing_damaged.name) if thing_damaged is Slimer: print_debug("Hitting a slime!") enemies_dict[thing_damaged]["health"] -= player_stats.ranged_damage if enemies_dict[thing_damaged]["health"] <= 0: print("Enemy killed") remove_enemy_from_level(thing_damaged) destroyed.emit(thing_damaged) else: print_debug("Slime health is %s" % enemies_dict[thing_damaged]["health"]) func remove_enemy_from_level(enemy) -> void: enemies_dict.erase(enemy) func save_game() -> void: game_saved.emit(current_level, time_available, player_current_health, enemies_dict) func load_game() -> void: if ResourceLoader.exists("res://resources/level" + str(current_level) + "_game_save_stats.tres"): var saved_game : SaveObject = load("res://resources/level" + str(current_level) + "_game_save_stats.tres") enemies_dict.clear() stash_data = saved_game.game_save game_loaded.emit(stash_data) func stash_game(stash) -> void: print_debug("Stashing game state") stash_data = stash var stash_object = SaveObject.new() stash_object.game_save = stash ResourceSaver.save(stash_object, "res://resources/level" + str(current_level) + "_game_save_stats.tres") func set_player_health(value: int) -> void: print_debug("Setting player health to %s" % str(value)) player_current_health = value #func _on_trigger_fired(intent: Variant, body: PhysicsBody2D) -> void: #print("Game controller knows %s trigger fired "change_scene % intent) #match intent: #"destroy": #print("Destroy this thing!") #if body is RigidBody2D: #destroyed.emit(body) #"powerup": #print("Power this thing up!")