diff --git a/PCs/FSM/building_state.gd b/PCs/FSM/building_state.gd index 8a30120..e2b1a4b 100644 --- a/PCs/FSM/building_state.gd +++ b/PCs/FSM/building_state.gd @@ -43,7 +43,7 @@ func process_state(_delta: float) -> void: hero.edit_tool.interact_key_held = false if Input.is_action_just_pressed("Swap Weapons"): state_changed.emit(swap_state) - if Input.is_action_pressed("Ready"): + if Input.is_action_just_pressed("Ready"): if hero.ready_state: hero.unready_self() else: diff --git a/PCs/FSM/carding_state.gd b/PCs/FSM/carding_state.gd index 1b59d29..4fa09b9 100644 --- a/PCs/FSM/carding_state.gd +++ b/PCs/FSM/carding_state.gd @@ -69,7 +69,7 @@ func process_state(_delta: float) -> void: swap_to_slot(10) if Input.is_action_just_pressed("Swap Weapons"): state_changed.emit(swap_state) - if Input.is_action_pressed("Ready"): + if Input.is_action_just_pressed("Ready"): if hero.ready_state: hero.unready_self() else: diff --git a/PCs/hero.gd b/PCs/hero.gd index bda6673..6649f14 100644 --- a/PCs/hero.gd +++ b/PCs/hero.gd @@ -158,12 +158,12 @@ func exit_fighting_state() -> void: func _physics_process(_delta: float) -> void: - if !is_multiplayer_authority() or paused: + if paused or !is_multiplayer_authority(): return func _process(delta: float) -> void: - if !is_multiplayer_authority() or paused: + if paused or !is_multiplayer_authority(): return if !movement.sprinting: movement.zoom_factor += sprint_zoom_speed * 2.0 * delta diff --git a/PCs/hero.tscn b/PCs/hero.tscn index 496830c..7a9fbca 100644 --- a/PCs/hero.tscn +++ b/PCs/hero.tscn @@ -451,12 +451,12 @@ bones/15/rotation = Quaternion(-0.2017903, 0.015379741, -0.03813146, 0.97856534) bones/16/rotation = Quaternion(-0.0048455074, 0.003865697, 0.59440565, 0.8041415) bones/18/rotation = Quaternion(-0.2272016, 0.019839177, 0.4623247, 0.856879) bones/23/rotation = Quaternion(-0.045133274, -0.11772486, 0.9614004, -0.24456768) -bones/24/rotation = Quaternion(-0.31305715, 0.075180076, -0.21363969, 0.92233473) -bones/25/rotation = Quaternion(0.5710469, -0.039941728, 0.017517319, 0.819758) -bones/26/rotation = Quaternion(-0.69202226, 0.0027399438, -0.003180337, 0.721864) -bones/28/rotation = Quaternion(0.056880478, 0.03165418, 0.2195195, 0.97343403) -bones/29/rotation = Quaternion(0.038734946, -0.00095578696, -0.019037286, 0.9990678) -bones/30/rotation = Quaternion(-0.67850786, -0.0014370738, 0.0042436896, 0.73457956) +bones/24/rotation = Quaternion(-0.03303061, -0.005903939, -0.221179, 0.9746559) +bones/25/rotation = Quaternion(0.049654786, 0.0001291396, 0.019066628, 0.9985845) +bones/26/rotation = Quaternion(-0.68533796, 0.002092736, -0.0037087626, 0.7282128) +bones/28/rotation = Quaternion(-0.20499752, -0.0437259, 0.21891265, 0.9529646) +bones/29/rotation = Quaternion(0.586818, 0.04117671, -0.017359266, 0.8084849) +bones/30/rotation = Quaternion(-0.41481006, 0.02057148, 0.021915937, 0.9094114) [node name="AnimationPlayer" parent="Model/doe_girl" parent_id_path=PackedInt32Array(1269374108, 1532649165) index="1" unique_id=126187206] autoplay = &"HoldGun" diff --git a/Scenes/CardPrinter/card_printer.gd b/Scenes/CardPrinter/card_printer.gd index fd147c5..4301f33 100644 --- a/Scenes/CardPrinter/card_printer.gd +++ b/Scenes/CardPrinter/card_printer.gd @@ -4,8 +4,6 @@ class_name CardPrinter extends StaticBody3D @export var button_collider: CollisionShape3D @export var card_selection_menu: PackedScene -#TODO: use faction enum -var base_faction: int = 1 var cards_generated: int = 0 var reply_player: Hero var spawned_cards: Array[CardItem] = [] @@ -41,9 +39,9 @@ func generate_rarity() -> int: func randomize_cards(faction: Card.Faction) -> void: - #TODO: no magic numbers, asshole! 3 = cards to spawn + var cards_to_spawn: int = 3 var pos_x: float = 0.0 - for x: int in 3: + for x: int in cards_to_spawn: var decided_rarity: int = generate_rarity() var card_choices: Array[Card] = get_faction_cards(faction) var card_array: Array = [] diff --git a/Scenes/ShopStand/shop_stand.gd b/Scenes/ShopStand/shop_stand.gd index 62955e7..12725a2 100644 --- a/Scenes/ShopStand/shop_stand.gd +++ b/Scenes/ShopStand/shop_stand.gd @@ -21,6 +21,7 @@ var blanks_available: int = 5 var blank_cost: int = 20 var buy_blank_prompt: String = "PROMPT_BUY_BLANK" var buy_card_prompt: String = "PROMPT_BUY_CARD" +var shops_generated: int = 0 func close() -> void: @@ -34,9 +35,14 @@ func close() -> void: func randomize_cards() -> void: - #TODO: use seeded randomness blanks_available = 5 - var random_faction: int = randi_range(1, Card.Faction.values().size() - 1) + var unlocked_classes: Array[HeroClass] = Data.save_data.get_unlocked_classes() + var faction_choices: Array[Card.Faction] + for hero: HeroClass in unlocked_classes: + if !faction_choices.has(hero.faction): + faction_choices.append(hero.faction) + var random_faction: int = NoiseRandom.randi_in_range(shops_generated, 0, faction_choices.size() - 1) + shops_generated += 1 var cheap_cards: Array[Card] = [] var medium_cards: Array[Card] = [] var pricey_cards: Array[Card] = [] diff --git a/Scripts/EnemyAI/enemy_movement.gd b/Scripts/EnemyAI/enemy_movement.gd index a366c70..eca87e2 100644 --- a/Scripts/EnemyAI/enemy_movement.gd +++ b/Scripts/EnemyAI/enemy_movement.gd @@ -8,7 +8,6 @@ var speed: float = 0.0 func _ready() -> void: - #TODO: make deterministic random - var variance: float = randf_range(-1.0, 1.0) + var variance: float = NoiseRandom.randf_in_range(character.name.to_int(), -1.0, 1.0) var variance_max: float = 0.03 # Enemy speed can vary by 3% from their base speed speed = character.stats.movement_speed + (variance * variance_max) diff --git a/Scripts/EnemyAI/pathing_controller.gd b/Scripts/EnemyAI/pathing_controller.gd index 501c254..794552b 100644 --- a/Scripts/EnemyAI/pathing_controller.gd +++ b/Scripts/EnemyAI/pathing_controller.gd @@ -1,8 +1,7 @@ class_name PathingController extends EnemyMovement -#var path: Curve3D -#var path_progress: float = 0.0 +var random_points_generated: int var flow_field: FlowField var next_node: FlowNodeData : get(): @@ -13,9 +12,12 @@ var next_node: FlowNodeData : return var found_point: bool = false while !found_point: - #TODO: make deterministic random - var x: float = randf_range(-1, 1) - var y: float = randf_range(-1, 1) + random_points_generated += 1 + var sample: int = random_points_generated + character.name.to_int() + var r: float = 1.0 * sqrt(NoiseRandom.randf_in_range(sample, 0.0, 1.0)) + var theta: float = NoiseRandom.randf_in_range(sample * 4, 0.0, 1.0) * 2.0 * PI + var x: float = r * cos(theta) + var y: float = r * sin(theta) if Vector3(next_node.position.x + x, next_node.position.y, next_node.position.z + y).distance_to(next_node.position) <= 1.0: found_point = true next_pos = Vector3(next_node.position.x + x, next_node.position.y, next_node.position.z + y) diff --git a/Scripts/Resources/card.gd b/Scripts/Resources/card.gd index cc44a03..d466942 100644 --- a/Scripts/Resources/card.gd +++ b/Scripts/Resources/card.gd @@ -5,7 +5,7 @@ enum Faction { GENERIC = 0, ENGINEER = 1, MAGE = 2, - } +} @export var cost: int @export var rarity: Data.Rarity diff --git a/Scripts/Resources/save_data.gd b/Scripts/Resources/save_data.gd index 2283a12..cc1b0e7 100644 --- a/Scripts/Resources/save_data.gd +++ b/Scripts/Resources/save_data.gd @@ -27,6 +27,17 @@ var mage_cards_bought: int = 0 var mage_unlocked: bool = 0 +func get_unlocked_classes() -> Array[HeroClass]: + var arr: Array[HeroClass] = [] + for character: HeroClass in Data.characters: + if character.faction == Card.Faction.ENGINEER: + arr.append(Data.characters) + #TODO: When mage cards are good to show up in the shop, replace false with mage_unlocked + if false and character.faction == Card.Faction.MAGE: + arr.append(Data.characters) + return arr + + func check_high_score(level_title: String, wave_reached: int, endless: bool) -> void: if !endless_high_scores.has(level_title): endless_high_scores[level_title] = 0 diff --git a/Scripts/game.gd b/Scripts/game.gd index db3e5d6..3228220 100644 --- a/Scripts/game.gd +++ b/Scripts/game.gd @@ -206,19 +206,14 @@ func set_wave_to_spawners(wave_thing: WaveConfig, wave_number: int) -> void: func set_upcoming_wave() -> void: - if is_multiplayer_authority(): - #print(wave) - #print(level_config.waves.size()) - if wave > level_config.waves.size(): - #print("added new wave on top") - var spawn_power: int = WaveManager.calculate_spawn_power(wave, connected_players_nodes.size()) - var new_wave: WaveConfig = WaveManager.generate_wave(spawn_power, level.enemy_pool, level.enemy_spawns.size()) - level_config.waves.append(new_wave) + if wave > level_config.waves.size(): + var spawn_power: int = WaveManager.calculate_spawn_power(wave, connected_players_nodes.size()) + var new_wave: WaveConfig = WaveManager.generate_wave(spawn_power, level.enemy_pool, level.enemy_spawns.size()) + level_config.waves.append(new_wave) - var new_wave: WaveConfig = get_upcoming_waves(1)[0] - #print(new_wave) - set_wave_to_spawners(new_wave, wave) - temp_set_upcoming_wave(new_wave, WaveManager.calculate_pot(wave, connected_players_nodes.size())) + var new_wave: WaveConfig = get_upcoming_waves(1)[0] + set_wave_to_spawners(new_wave, wave) + temp_set_upcoming_wave(new_wave, WaveManager.calculate_pot(wave, connected_players_nodes.size())) func temp_set_upcoming_wave(new_wave: WaveConfig, coins: int) -> void: @@ -407,15 +402,14 @@ func continue_with_game() -> void: gamemode.endless = true Input.mouse_mode = Input.MOUSE_MODE_CAPTURED connected_players_nodes[multiplayer.get_unique_id()].unpause() - #TODO: This shouldn't happen. instead, the wave generator should generate level_config waves - #FIXME: this really needs to be changed because otherwise endless mode cant have shit like - #stations and shop respawns. it all needs to be part of the one system u know set_upcoming_wave() func quit_to_desktop() -> void: - multiplayer.multiplayer_peer.close() - multiplayer.multiplayer_peer = null + #for player: Hero in connected_players_nodes.values(): + # player.queue_free() + #multiplayer.multiplayer_peer.close() + #multiplayer.multiplayer_peer = null get_tree().quit() @@ -424,8 +418,10 @@ func scene_switch_main_menu() -> void: node.queue_free() level = null connected_players_nodes.clear() - multiplayer.multiplayer_peer.close() - multiplayer.multiplayer_peer = null + if multiplayer.multiplayer_peer: + multiplayer.multiplayer_peer.close() + multiplayer.multiplayer_peer = null + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE switch_to_main_menu.emit() diff --git a/Scripts/multiplayer_lobby.gd b/Scripts/multiplayer_lobby.gd index 630cd44..93ff5d1 100644 --- a/Scripts/multiplayer_lobby.gd +++ b/Scripts/multiplayer_lobby.gd @@ -87,6 +87,7 @@ func networked_ready_player(peer_id: int) -> void: start_game = false if start_game: setup_game() + visible = false func ready_player(peer_id: int = multiplayer.get_unique_id()) -> void: @@ -99,11 +100,14 @@ func ready_player(peer_id: int = multiplayer.get_unique_id()) -> void: start_game = false if start_game: setup_game() + visible = false @rpc("any_peer", "reliable") func networked_select_class(peer_id: int) -> void: player_character_selected_states[connected_players_profiles[peer_id]] = true + if chatbox: + chatbox.append_message("SERVER", Color.TOMATO, connected_players_profiles[peer_id].display_name + " has chosen a class!") var start_game: bool = true for state: bool in player_character_selected_states.values(): if !state: @@ -125,7 +129,6 @@ func select_class(peer_id: int = multiplayer.get_unique_id()) -> void: func start_game() -> void: enet_peer.refuse_new_connections = true - visible = false super.start_game() diff --git a/UI/Menus/CharacterSelect/character_select.gd b/UI/Menus/CharacterSelect/character_select.gd index dd7b3be..dc30815 100644 --- a/UI/Menus/CharacterSelect/character_select.gd +++ b/UI/Menus/CharacterSelect/character_select.gd @@ -76,4 +76,5 @@ func advance_selector() -> void: func _on_confirm_button_pressed() -> void: + $Controls.visible = false hero_confirmed.emit() diff --git a/main.gd b/main.gd index 78e8e4b..82082e6 100644 --- a/main.gd +++ b/main.gd @@ -69,6 +69,7 @@ func load_multiplayer() -> void: multi_player_lobby.game_manager = game_manager multi_player_lobby.setup_the_ui() multi_player_lobby.player_disconnected.connect(game_manager.remove_player) + multi_player_lobby.disconnected_from_server.connect(game_manager.scene_switch_main_menu) func load_scene(scene_path: String) -> void: diff --git a/network_puppeteer.gd b/network_puppeteer.gd index f8934ee..38ccc53 100644 --- a/network_puppeteer.gd +++ b/network_puppeteer.gd @@ -1,11 +1,16 @@ class_name NetworkPuppeteer extends Node -@export var player: CharacterBody3D +@export var player: Hero @export var player_movement: PlayerMovement @export var skeleton: Skeleton3D @export var animation_tree: AnimationTree +func _ready() -> void: + if is_multiplayer_authority(): + player.ready_state_changed.connect(func x(state: bool) -> void: set_ready_state.rpc(state)) + + func _process(delta: float) -> void: if is_multiplayer_authority(): set_position.rpc(player.global_position) @@ -28,3 +33,11 @@ func set_rotation(x: float, y: float) -> void: var bone: int = skeleton.find_bone("Head") var pos: Quaternion = skeleton.get_bone_pose_rotation(bone) skeleton.set_bone_pose_rotation(bone, Quaternion.from_euler(Vector3(x, 0, 0))) + + +@rpc("reliable", "call_remote") +func set_ready_state(state: bool) -> void: + if state: + player.ready_self() + else: + player.unready_self()