2025-09-30 01:10:58 +00:00
|
|
|
extends Node2D
|
|
|
|
|
|
2025-10-28 01:02:15 +00:00
|
|
|
var coins_collected : int = 0
|
|
|
|
|
var total_coins : int = 0
|
2025-11-06 02:10:37 +00:00
|
|
|
var levels = ["res://scenes/level_1.tscn", "res://scenes/level_2.tscn", "res://scenes/level_3.tscn"]
|
2025-11-04 01:56:43 +00:00
|
|
|
var timers = [10, 15, 20]
|
|
|
|
|
var time_available : int = 0
|
|
|
|
|
var current_level = 0
|
|
|
|
|
var timer = Timer.new()
|
|
|
|
|
|
|
|
|
|
## Signals
|
|
|
|
|
signal level_changed(level)
|
|
|
|
|
signal destroyed(body)
|
|
|
|
|
signal player_damaged(health, max_health)
|
|
|
|
|
signal player_death
|
2025-11-11 02:17:55 +00:00
|
|
|
signal game_loaded(stashed_data)
|
|
|
|
|
signal game_saved(level, time_remaining, player_health, enemies_dictionary)
|
|
|
|
|
signal timer_updated(time_remaining)
|
|
|
|
|
signal coin_collected(coins_remaining)
|
2025-11-04 01:56:43 +00:00
|
|
|
|
|
|
|
|
var enemy_stats : CharacterStats
|
|
|
|
|
var player_stats : CharacterStats
|
|
|
|
|
var enemies_dict : Dictionary = {}
|
|
|
|
|
var player_current_health : int = 0
|
2025-11-11 02:17:55 +00:00
|
|
|
var stash_data : Dictionary = {}
|
2025-11-04 01:56:43 +00:00
|
|
|
|
|
|
|
|
func _ready() -> void:
|
|
|
|
|
# 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()
|
|
|
|
|
|
2025-11-11 02:17:55 +00:00
|
|
|
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
|
|
|
|
|
|
2025-11-04 01:56:43 +00:00
|
|
|
func second_counter() -> void:
|
|
|
|
|
time_available -= 1
|
2025-11-11 02:17:55 +00:00
|
|
|
timer_updated.emit(time_available)
|
2025-11-04 01:56:43 +00:00
|
|
|
if time_available <= 0:
|
|
|
|
|
print_debug("You ran out of time! Emitting level_changed signal")
|
|
|
|
|
#get_tree().call_deferred("change_scene_to_file", levels[current_level])
|
|
|
|
|
#await get_tree().create_timer(1.0).timeout
|
|
|
|
|
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]
|
|
|
|
|
print_debug("You have %s seconds to find all the coins" % str(time_available))
|
2025-09-30 01:10:58 +00:00
|
|
|
|
|
|
|
|
func _on_trigger_fired(intent: Variant, body: PhysicsBody2D) -> void:
|
|
|
|
|
print("Game controller knows %s trigger fired " % intent)
|
|
|
|
|
match intent:
|
|
|
|
|
"destroy":
|
|
|
|
|
print("Destroy this thing!")
|
|
|
|
|
if body is RigidBody2D:
|
2025-11-04 01:56:43 +00:00
|
|
|
destroyed.emit(body)
|
2025-09-30 01:10:58 +00:00
|
|
|
"powerup":
|
|
|
|
|
print("Power this thing up!")
|
2025-10-28 01:02:15 +00:00
|
|
|
|
|
|
|
|
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))
|
2025-11-04 01:56:43 +00:00
|
|
|
destroyed.emit(coin)
|
2025-10-28 01:02:15 +00:00
|
|
|
|
|
|
|
|
func set_total_coins(value) -> void:
|
2025-11-11 02:17:55 +00:00
|
|
|
coin_collected.emit(value)
|
2025-11-04 01:56:43 +00:00
|
|
|
print_debug("Setting coin total to %s" % str(value))
|
|
|
|
|
if value == 0:
|
|
|
|
|
# You won!
|
|
|
|
|
current_level += 1
|
|
|
|
|
if current_level >= levels.size():
|
|
|
|
|
current_level = 0
|
|
|
|
|
#await get_tree().create_timer(1.0).timeout
|
|
|
|
|
level_changed.emit(levels[current_level])
|
|
|
|
|
#total_coins = value
|
|
|
|
|
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))
|
|
|
|
|
|
2025-11-11 02:17:55 +00:00
|
|
|
func handle_player_death() -> void:
|
|
|
|
|
level_changed.emit(levels[current_level])
|
|
|
|
|
|
|
|
|
|
func add_enemy_to_level(enemy, _stat = null) -> void:
|
2025-11-04 01:56:43 +00:00
|
|
|
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
|
|
|
|
|
}
|
2025-11-11 02:17:55 +00:00
|
|
|
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])
|
2025-11-04 01:56:43 +00:00
|
|
|
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)
|
2025-11-11 02:17:55 +00:00
|
|
|
|
|
|
|
|
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
|