Files
fps_project_1/scripts/LevelManager.gd
2025-01-17 16:04:03 -06:00

239 lines
7.2 KiB
GDScript

extends Node3D
@export var load_save : = true
@export var player : Node
@export var money = 250
@export var start_health = 3
@export var MAX_PARTICLES = 100
@export var gun_1 : Resource
@export var gun_2 : Resource
@export_group("Drops")
@export var drop_chance_minimum = .1
@export var ammo_drop_enabled = true
@export var expected_ammo = {"light" : 200, "medium" : 50, "heavy" : 25,"shotgun" : 20, "rocket" : 3} #light, medium,heavy,shotgun,rocket
@export var stamina_drop_enabled = true
@export var health_drop_enabled = true
@export var money_drop_enabled = true
@onready var item_pickup = preload("res://assets/item_pickup.tscn")
@onready var crown = preload("res://assets/crown.tscn")
var dead_player = preload("res://assets/dead_cam.tscn")
const CLEARED_ANNOUNCE = preload("res://assets/cleared_announce.tscn")
const DEAD_ANNOUNCE = preload("res://assets/dead_announce.tscn")
var level_name
var paused = false
var health = start_health
var pickups = []
var held_guns = []
var ammo_current = [0]
var ammo_reserve = [0]
var keys = []
var guns_dict = {}
var current_gun_index
var particle_number = 0
var enemy_hiveminds = []
var remaining_enemies
var last_hit : Node
var target_type
var respawn_position
var respawn_cam_rotation
var respawn_rot
var engine_time_scale_cache : float = 1.0
# Called when the node enters the scene tree for the first time.
func _ready():
level_name = self.get_name()
print("LEVEL NAME ",level_name)
#connect to signals
SignalBus.enemy_count_changed.connect(enemy_count)
#LOAD DATA
SaveLoad.load_persistent_data()
if SaveLoad.data_cleared or !load_save:
refresh_scene()
GameGlobals.game_loaded = true
SignalBus.emit_signal("game_loaded")
else:
if SaveLoad.check_save_game_exists(level_name):
SaveLoad.load_save_game_data(level_name)
else:
refresh_scene()
#Spawn Crown
if SaveLoad.last_hit_path:
var crown_spawn = crown.instantiate()
var crown_target = get_node(SaveLoad.last_hit_path)
if crown_target:
crown_target.add_child(crown_spawn)
crown_spawn.position = Vector3(0,2,0)
#global randomize function
randomize()
#clear spawned in objects
for node in get_tree().get_nodes_in_group("spawned"):
node.queue_free()
#find enemy hiveminds
for node in get_tree().get_nodes_in_group("enemy_hivemind"):
enemy_hiveminds.append(node)
#count starting enemies
enemy_count()
func refresh_scene():
health = start_health
respawn_position = player.camera.global_position
respawn_cam_rotation = player.global_transform.basis
if player:
#Set up starting guns and ammo
if gun_1 != null:
held_guns = [gun_1]
var instance_gun = held_guns[0].instantiate()
player.add_ammo(true,instance_gun.gun_name,instance_gun.ammo_type,instance_gun.max_ammo,instance_gun.start_mags)
if gun_2 != null:
held_guns.append(gun_2)
var instance_gun_2 = held_guns[1].instantiate()
player.add_ammo(true,instance_gun_2.gun_name,instance_gun_2.ammo_type,instance_gun_2.max_ammo,instance_gun_2.start_mags)
# Spawn first gun
if gun_1 != null:
current_gun_index = 0
gun_spawn(0)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
pass
func gun_spawn(index):
#loop around if scrolling past available guns
if index > held_guns.size() - 1:
index = 0
elif index < 0:
index = held_guns.size() - 1
current_gun_index = index
if held_guns != []:
var instance_gun = held_guns[index].instantiate()
instance_gun.global_transform.origin = player.weapon_spawner.position
player.gun = instance_gun
player.def_weapon_holder_pos = player.weapon_holder.position
instance_gun.gun_index = index
instance_gun.anim_player.play("swap_in")
player.weapon_holder.add_child(instance_gun)
func enemy_count():
var sum = 0
var enemies = get_tree().get_nodes_in_group("enemy")
for i in enemies:
if i.get_class() == "CharacterBody3D":
sum += 1
print("enemies: " + str(sum))
if sum == 0:
cleared()
func cleared():
var clearedmsg = CLEARED_ANNOUNCE.instantiate()
get_parent().add_child(clearedmsg)
await get_tree().create_timer(1).timeout
clearedmsg.queue_free()
func die():
#record stats
if SaveLoad.player_deaths:
SaveLoad.player_deaths += 1
else:
SaveLoad.player_deaths = 1
SaveLoad.save_persistent_data()
SaveLoad.clear_save_game_data()
var deadmsg = DEAD_ANNOUNCE.instantiate()
get_parent().add_child(deadmsg)
var instance_dead = dead_player.instantiate()
instance_dead.global_position = player.camera.global_position
instance_dead.transform.basis = player.global_transform.basis
if last_hit != null:
instance_dead.target = last_hit
SaveLoad.last_hit_path = str(last_hit.get_path())
instance_dead.target_type = target_type
instance_dead.respawn_position = respawn_position
instance_dead.respawn_rotation = respawn_cam_rotation
instance_dead.respawn_fov = player.camera.fov
get_tree().get_root().add_child(instance_dead)
instance_dead.camera.current = true
player.dead = true
player.toggle_hud(true)
player.gun.visible = false
player.health_indicator.color = Color(0.471, 0, 0, 0)
func pickup_spawn(randomized):
var pickup_type
var ammo_type
var value
if randomized:
#random item
pickup_type = randi_range(0,3)
#if item type is ammo, pick random ammo
if pickup_type == 0:
var player_ammo = player.ammo_reserve.keys()
ammo_type = int(player_ammo.pick_random())
#random value of pickup
value = randi_range(1,50)
else:
var health_weight = (1.0 - (health / start_health)) + drop_chance_minimum
var stamina_weight = (1.0 - (player.remaining_stamina / player.MAX_STAMINA)) + drop_chance_minimum
var money_weight = (1.0 - clamp(float(money) / float(500),0,1)) + drop_chance_minimum #fix this logic later once the economy makes sense
var ammo_weight = drop_chance_minimum
var ammo_type_weight = {}
# weight ammo player owns against expected ammo values
for i in player.ammo_reserve.keys():
var i_weight
match int(i):
0:
i_weight = 1.0 - clamp(float(player.ammo_reserve[str(i)]) / float(expected_ammo["light"]),0,1)
1:
i_weight = 1.0 - clamp(float(player.ammo_reserve[str(i)]) / float(expected_ammo["medium"]),0,1)
2:
i_weight = 1.0 - clamp(float(player.ammo_reserve[str(i)]) / float(expected_ammo["heavy"]),0,1)
3:
i_weight = 1.0 - clamp(float(player.ammo_reserve[str(i)]) / float(expected_ammo["shotgun"]),0,1)
4:
i_weight = 1.0 - clamp(float(player.ammo_reserve[str(i)]) / float(expected_ammo["rocket"]),0,1)
if i_weight > ammo_weight:
ammo_weight = i_weight
ammo_type_weight[i] = i_weight + drop_chance_minimum
pickup_type = HelperFuncs.weighted_random({"0" : ammo_weight, "1" : stamina_weight,"2" : health_weight,"3" : money_weight})
match pickup_type:
"0":
if ammo_type_weight.size() > 0:
ammo_type = int(HelperFuncs.weighted_random(ammo_type_weight))
else:
ammo_type = randi_range(0,4)
value = randi_range(1,20)
"1":
value = randi_range(int(player.MAX_STAMINA * .25),player.MAX_STAMINA)
"2":
value = randi_range(int(start_health * .25),start_health)
"3":
var bill_denoms = [5,10,20,50,100]
value = bill_denoms.pick_random()
return {"pickup_type" : pickup_type,"ammo_type" : ammo_type,"value" : value}
func save_quit():
SaveLoad.save_game_data(level_name)
get_tree().quit()