full multiplayer plus new models
This commit is contained in:
@ -26,7 +26,7 @@ func point_is_build_location(point_id):
|
||||
return !non_build_locations.has(point_id)
|
||||
|
||||
|
||||
func test_path_if_point_toggled(point_id):
|
||||
func test_path_if_point_toggled(point_id) -> bool:
|
||||
if astar.is_point_disabled(point_id):
|
||||
astar.set_point_disabled(point_id, false)
|
||||
else:
|
||||
@ -60,6 +60,29 @@ func networked_spawn_wall(pos : Vector3, name_id : int):
|
||||
tower_path.add_child(base)
|
||||
|
||||
|
||||
func build_random_maze(block_limit):
|
||||
var untested_point_ids = []
|
||||
for index in (grid_size.x * grid_size.y):
|
||||
untested_point_ids.append(index)
|
||||
if block_limit <= 0 or block_limit > untested_point_ids.size():
|
||||
block_limit = untested_point_ids.size()
|
||||
for index in block_limit:
|
||||
var random_point = untested_point_ids.pick_random()
|
||||
untested_point_ids.erase(random_point)
|
||||
if test_path_if_point_toggled(random_point):
|
||||
networked_toggle_point.rpc(random_point)
|
||||
|
||||
|
||||
func place_random_towers(tower_limit):
|
||||
var untowered_bases = tower_bases.duplicate()
|
||||
if tower_limit <= 0 or tower_limit > untowered_bases.size():
|
||||
tower_limit = untowered_bases.size()
|
||||
for index in tower_limit:
|
||||
var random_base = untowered_bases.pick_random() as TowerBase
|
||||
untowered_bases.erase(random_base)
|
||||
random_base.add_card(Data.cards.pick_random())
|
||||
|
||||
|
||||
func find_path() -> bool:
|
||||
var path = astar.get_point_path(astar.get_point_count() - 2, astar.get_point_count() - 1)
|
||||
if !path.is_empty():
|
||||
|
26
Scripts/CinemaCam.gd
Normal file
26
Scripts/CinemaCam.gd
Normal file
@ -0,0 +1,26 @@
|
||||
extends Node3D
|
||||
class_name CinematicCamManager
|
||||
|
||||
@export var path_follows : Array[PathFollow3D]
|
||||
@export var cameras : Array[Camera3D]
|
||||
@export var pan_speed := 1.0
|
||||
var current_cam := 0
|
||||
var does_its_thing := true
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
for path_follow in path_follows:
|
||||
path_follow.progress_ratio = 0.0
|
||||
if does_its_thing:
|
||||
cameras[0].make_current()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if does_its_thing:
|
||||
path_follows[current_cam].progress_ratio += pan_speed * delta
|
||||
if path_follows[current_cam].progress_ratio >= 1.0:
|
||||
current_cam += 1
|
||||
if current_cam >= cameras.size():
|
||||
current_cam = 0
|
||||
path_follows[current_cam].progress_ratio = 0.0
|
||||
cameras[current_cam].make_current()
|
@ -3,7 +3,7 @@ class_name ProjectileTower
|
||||
|
||||
@export var projectile_scene : PackedScene
|
||||
|
||||
var force := 20.0
|
||||
var force := 150.0
|
||||
var projectile_id := 0
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ func networked_shoot():
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_projectile(peer_id):
|
||||
var projectile = projectile_scene.instantiate() as Projectile
|
||||
projectile.position = global_position + Vector3.UP
|
||||
projectile.position = yaw_model.global_position
|
||||
projectile.damage = damage
|
||||
projectile.direction = -yaw_model.global_transform.basis.z
|
||||
projectile.force = force
|
||||
|
@ -17,6 +17,10 @@ func _physics_process(_delta: float) -> void:
|
||||
fire(enemy)
|
||||
|
||||
|
||||
func aim():
|
||||
pass
|
||||
|
||||
|
||||
func fire(target):
|
||||
if is_instance_valid(target) and target.alive:
|
||||
target.damage(damage)
|
||||
|
@ -5,7 +5,7 @@ signal completed
|
||||
|
||||
func set_popup(prompt_text, dismiss_text):
|
||||
$VBoxContainer/Label.text = prompt_text
|
||||
$VBoxContainer/Button.text = dismiss_text
|
||||
$VBoxContainer/MarginContainerButton.text = dismiss_text
|
||||
|
||||
|
||||
func _on_button_pressed() -> void:
|
||||
|
@ -49,8 +49,8 @@ func retrieve_card(i):
|
||||
var card = cards[i].stats
|
||||
var item = item_card_scene.instantiate() as ItemCard
|
||||
item.card = card
|
||||
item.position = Vector3(1.683, 0, 0)
|
||||
add_child(item)
|
||||
item.position += -transform.basis.z * 2
|
||||
button_collider.disabled = false
|
||||
button_box.position = Vector3(0,0,0)
|
||||
|
||||
|
@ -5,8 +5,8 @@ signal completed(outcome)
|
||||
|
||||
func set_popup(prompt_text, confirm_text, cancel_text):
|
||||
$VBoxContainer/Label.text = prompt_text
|
||||
$VBoxContainer/HBoxContainer/Confirm.text = confirm_text
|
||||
$VBoxContainer/HBoxContainer/Cancel.text = cancel_text
|
||||
$VBoxContainer/HBoxContainer/MarginContainer/Confirm.text = confirm_text
|
||||
$VBoxContainer/HBoxContainer/MarginContainer2/Cancel.text = cancel_text
|
||||
|
||||
|
||||
func _on_confirm_pressed() -> void:
|
||||
|
@ -9,8 +9,8 @@ var preferences : PlayerPreferences
|
||||
var player_profile : PlayerProfile
|
||||
var player_keymap : PlayerKeymap
|
||||
|
||||
var wall_cost := 4
|
||||
var printer_cost := 10
|
||||
var wall_cost := 1
|
||||
var printer_cost := 20
|
||||
enum TargetType {UNDEFINED = 0, LAND = 1, AIR = 2, BOTH = 3}
|
||||
enum EnemyType {UNDEFINED = 0, LAND = 1, AIR = 2}
|
||||
enum Rarity {COMMON = 0, UNCOMMON = 1, RARE = 2, EPIC = 3, LEGENDARY = 4}
|
||||
|
@ -22,10 +22,13 @@ var level : Level
|
||||
var enemies := 0
|
||||
var objective_health := 120
|
||||
var wave := 0
|
||||
var endless_mode := false
|
||||
var upcoming_wave
|
||||
var pot : float
|
||||
var UILayer : CanvasLayer
|
||||
var chatbox : Chatbox
|
||||
var wave_limit := 20
|
||||
var starting_cash := 16
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -44,6 +47,20 @@ func parse_command(text : String, peer_id : int):
|
||||
connected_players_nodes[peer_id].inventory.add(gift)
|
||||
if text.substr(1, 2) == "tr":
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "[color=#f7a8b8]t[color=#55cdfc]r[color=#ffffff]a[color=#55cdfc]n[color=#f7a8b8]s [color=#e50000]r[color=#ff8d00]i[color=#ffee00]g[color=#028121]h[color=#004cff]t[color=#760088]s[color=white]!!")
|
||||
if text.substr(1, 11) == "random_maze":
|
||||
level.a_star_graph_3d.build_random_maze(50)
|
||||
if text.substr(1, 13) == "random_towers":
|
||||
level.a_star_graph_3d.place_random_towers(level.a_star_graph_3d.tower_bases.size() / 3.0)
|
||||
if text.substr(1, 11) == "set_endless":
|
||||
if is_multiplayer_authority():
|
||||
networked_set_endless.rpc(true)
|
||||
else:
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "Unable to edit gamemode")
|
||||
if text.substr(1, 12) == "set_standard":
|
||||
if is_multiplayer_authority():
|
||||
networked_set_endless.rpc(false)
|
||||
else:
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "Unable to edit gamemode")
|
||||
# if text.substr(1, 17) == "show tower ranges":
|
||||
# pass
|
||||
# if text.substr(1, 20) = "show gauntlet ranges":
|
||||
@ -82,6 +99,7 @@ func spawn_players(player_array, player_profiles, chatbox_open_signal, chatbox_c
|
||||
enemy_number_changed.connect(player.hud.set_enemy_count)
|
||||
add_child(player)
|
||||
p_i += 1
|
||||
level.cinematic_cam.does_its_thing = false
|
||||
start_game()
|
||||
|
||||
|
||||
@ -116,6 +134,15 @@ func networked_set_upcoming_wave(wave_dict, coins):
|
||||
connected_players_nodes[key].hud.set_upcoming_wave(upcoming_wave)
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_set_endless(value):
|
||||
endless_mode = value
|
||||
if endless_mode:
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "Endless mode enabled!")
|
||||
else:
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "Endless mode disabled!")
|
||||
|
||||
|
||||
func increase_enemy_count():
|
||||
enemies += 1
|
||||
enemy_number_changed.emit(enemies)
|
||||
@ -131,7 +158,7 @@ func enemy_died(enemy):
|
||||
return
|
||||
if enemies == 0:
|
||||
end_wave()
|
||||
if wave >= 20:
|
||||
if !endless_mode and wave >= wave_limit:
|
||||
win_game()
|
||||
|
||||
|
||||
@ -146,7 +173,7 @@ func damage_goal(enemy, penalty):
|
||||
lose_game()
|
||||
elif enemies == 0:
|
||||
end_wave()
|
||||
if wave >= 20:
|
||||
if !endless_mode and wave >= wave_limit:
|
||||
win_game()
|
||||
|
||||
|
||||
@ -174,7 +201,7 @@ func start_game():
|
||||
level.a_star_graph_3d.find_path()
|
||||
set_upcoming_wave()
|
||||
for peer_id in connected_players_nodes:
|
||||
connected_players_nodes[peer_id].currency = 20
|
||||
connected_players_nodes[peer_id].currency = starting_cash / connected_players_nodes.size()
|
||||
game_started.emit()
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
extends VBoxContainer
|
||||
class_name KeybindsOptionsMenu
|
||||
|
||||
var keybind_popup = load("res://Scenes/UI/keybind_popup.tscn")
|
||||
var keybind_boxes = []
|
||||
|
@ -6,3 +6,4 @@ class_name Level
|
||||
@export var enemy_spawns : Array[Node3D] = []
|
||||
@export var enemy_goals : Array[Node3D] = []
|
||||
@export var a_star_graph_3d : AStarGraph3D
|
||||
@export var cinematic_cam : CinematicCamManager
|
||||
|
@ -4,9 +4,28 @@ var confirmation_popup_scene = preload("res://Scenes/Menus/confirmation_popup.ts
|
||||
var text_input_popup_scene = preload("res://Scenes/Menus/text_input_popup.tscn")
|
||||
var multiplayer_lobby_scene_path = "res://Scenes/multiplayer_lobby.tscn"
|
||||
var options_menu_scene = preload("res://Scenes/Menus/options_menu.tscn")
|
||||
@export var bg_level : Level
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$ProfileEditor/VBoxContainer/HBoxContainer/DisplayName.text = Data.player_profile.display_name
|
||||
bg_level.a_star_graph_3d.make_grid()
|
||||
bg_level.a_star_graph_3d.find_path()
|
||||
bg_level.a_star_graph_3d.build_random_maze(50)
|
||||
bg_level.a_star_graph_3d.place_random_towers(20)
|
||||
var new_wave = WaveManager.generate_wave(400, bg_level.enemy_pool)
|
||||
for spawn in bg_level.enemy_spawns:
|
||||
spawn.signal_for_after_enemy_died = enemy_died
|
||||
spawn.signal_for_after_enemy_reached_goal = damage_goal
|
||||
spawn.signal_for_when_enemy_spawns.connect(increase_enemy_count)
|
||||
spawn.spawn_wave(new_wave)
|
||||
|
||||
func enemy_died(some_arg):
|
||||
pass
|
||||
func damage_goal():
|
||||
pass
|
||||
func increase_enemy_count():
|
||||
pass
|
||||
|
||||
|
||||
func _on_display_name_edit_pressed() -> void:
|
||||
|
@ -1,12 +1,18 @@
|
||||
extends Control
|
||||
class_name OptionsMenu
|
||||
|
||||
@export var gameplay : GameplayOptionsMenu
|
||||
@export var graphics : GraphicsOptionsMenu
|
||||
@export var keybinds : KeybindsOptionsMenu
|
||||
|
||||
|
||||
func _on_cancel_pressed() -> void:
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_confirm_pressed() -> void:
|
||||
gameplay.save()
|
||||
graphics.save()
|
||||
Data.graphics.apply_graphical_settings(get_viewport())
|
||||
Data.graphics.save_profile_to_disk()
|
||||
Data.preferences.save_profile_to_disk()
|
||||
|
@ -1,58 +0,0 @@
|
||||
extends Node3D
|
||||
class_name OldTower
|
||||
|
||||
@export var model : Node3D
|
||||
@export var range_sphere : CSGSphere3D
|
||||
@export var minimap_range_sphere : CSGSphere3D
|
||||
|
||||
var targeted_enemy
|
||||
var cooldown := 0.0
|
||||
var other_cooldown := 0.0
|
||||
|
||||
func _ready() -> void:
|
||||
cooldown = 1.0 / stats.fire_rate
|
||||
range_sphere.radius = stats.fire_range
|
||||
minimap_range_sphere.radius = stats.fire_range
|
||||
#minimap_range_sphere.set_visible(true)
|
||||
|
||||
|
||||
func preview_range(value):
|
||||
range_sphere.set_visible(value)
|
||||
minimap_range_sphere.set_visible(value)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
other_cooldown -= delta
|
||||
if !targeted_enemy:
|
||||
acquire_target()
|
||||
else:
|
||||
if model.global_position.distance_to(targeted_enemy.global_position) > stats.fire_range:
|
||||
targeted_enemy = null
|
||||
if targeted_enemy:
|
||||
aim()
|
||||
if other_cooldown <= 0:
|
||||
shoot()
|
||||
other_cooldown = cooldown
|
||||
|
||||
|
||||
func shoot():
|
||||
targeted_enemy.damage(stats.damage)
|
||||
|
||||
|
||||
func aim():
|
||||
model.look_at(targeted_enemy.global_position)
|
||||
|
||||
|
||||
func acquire_target():
|
||||
var most_progressed_enemy = null
|
||||
for enemy in get_tree().get_nodes_in_group("Enemies"):
|
||||
if model.global_position.distance_to(enemy.global_position) > stats.fire_range:
|
||||
continue
|
||||
var em_1 = enemy.movement_controller as EnemyMovement
|
||||
var em_2 : EnemyMovement
|
||||
if most_progressed_enemy != null:
|
||||
em_2 = most_progressed_enemy.movement_controller as EnemyMovement
|
||||
if (most_progressed_enemy == null or em_1.distance_remaining < em_2.distance_remaining) and enemy.stats.target_type & stats.can_target:
|
||||
most_progressed_enemy = enemy
|
||||
if most_progressed_enemy != null:
|
||||
targeted_enemy = most_progressed_enemy
|
Reference in New Issue
Block a user