enabled enforced static typing
This commit is contained in:
@ -1,44 +1,43 @@
|
||||
extends Node3D
|
||||
class_name AStarGraph3D
|
||||
class_name AStarGraph3D extends Node3D
|
||||
|
||||
@export var grid_size := Vector2i(15, 7)
|
||||
@export var point_gap := 2.0
|
||||
var non_build_locations = []
|
||||
var astar := AStar3D.new()
|
||||
@export var grid_size: Vector2i = Vector2i(15, 7)
|
||||
@export var point_gap: float = 2.0
|
||||
var non_build_locations: Array = []
|
||||
var astar: AStar3D = AStar3D.new()
|
||||
|
||||
#TODO generalize this better
|
||||
@export var start : Node3D
|
||||
@export var end : Node3D
|
||||
@export var spawner : EnemySpawner
|
||||
@export var visualized_path : VisualizedPath
|
||||
@export var tower_path : Node
|
||||
var tower_base_scene = load("res://Scenes/tower_base.tscn")
|
||||
var tower_frame_scene = load("res://Scenes/tower_frame.tscn")
|
||||
var tower_bases = []
|
||||
var tower_base_ids = {}
|
||||
var tower_frames = []
|
||||
var wall_id = 0
|
||||
@export var start: Node3D
|
||||
@export var end: Node3D
|
||||
@export var spawner: EnemySpawner
|
||||
@export var visualized_path: VisualizedPath
|
||||
@export var tower_path: Node
|
||||
var tower_base_scene: PackedScene = load("res://Scenes/tower_base.tscn")
|
||||
var tower_frame_scene: PackedScene = load("res://Scenes/tower_frame.tscn")
|
||||
var tower_bases: Array = []
|
||||
var tower_base_ids: Dictionary = {}
|
||||
var tower_frames: Array = []
|
||||
var wall_id: int = 0
|
||||
|
||||
|
||||
func toggle_point(point_id, caller_id):
|
||||
func toggle_point(point_id: int, caller_id: int) -> void:
|
||||
networked_toggle_point.rpc(point_id, caller_id)
|
||||
|
||||
|
||||
func remove_wall(wall : TowerBase):
|
||||
func remove_wall(wall: TowerBase) -> void:
|
||||
networked_remove_wall.rpc(wall.point_id)
|
||||
toggle_point(wall.point_id, multiplayer.get_unique_id())
|
||||
|
||||
|
||||
func point_is_build_location(point_id):
|
||||
func point_is_build_location(point_id: int) -> bool:
|
||||
return !non_build_locations.has(point_id)
|
||||
|
||||
|
||||
func test_path_if_point_toggled(point_id) -> bool:
|
||||
func test_path_if_point_toggled(point_id: int) -> bool:
|
||||
if astar.is_point_disabled(point_id):
|
||||
astar.set_point_disabled(point_id, false)
|
||||
else:
|
||||
astar.set_point_disabled(point_id, true)
|
||||
var result = find_path()
|
||||
var result: bool = find_path()
|
||||
if astar.is_point_disabled(point_id):
|
||||
astar.set_point_disabled(point_id, false)
|
||||
else:
|
||||
@ -47,7 +46,7 @@ func test_path_if_point_toggled(point_id) -> bool:
|
||||
|
||||
|
||||
@rpc("reliable", "any_peer", "call_local")
|
||||
func networked_toggle_point(point_id, caller_id):
|
||||
func networked_toggle_point(point_id: int, caller_id: int) -> void:
|
||||
if astar.is_point_disabled(point_id):
|
||||
astar.set_point_disabled(point_id, false)
|
||||
else:
|
||||
@ -59,46 +58,46 @@ func networked_toggle_point(point_id, caller_id):
|
||||
wall_id += 1
|
||||
|
||||
|
||||
func get_north_point(point_id) -> int:
|
||||
var x = point_id / grid_size.y
|
||||
var y = point_id % grid_size.y
|
||||
func get_north_point(point_id: int) -> int:
|
||||
var x: int = floori(float(point_id) / float(grid_size.y))
|
||||
var y: int = point_id % grid_size.y
|
||||
if x - 1 >= 0: #if the north point id could possibly exist as a neighbor
|
||||
return (x - 1) * grid_size.y + y
|
||||
return -1
|
||||
|
||||
|
||||
func get_south_point(point_id) -> int:
|
||||
var x = point_id / grid_size.y
|
||||
var y = point_id % grid_size.y
|
||||
func get_south_point(point_id: int) -> int:
|
||||
var x: int = floori(float(point_id) / float(grid_size.y))
|
||||
var y: int = point_id % grid_size.y
|
||||
if x + 1 <= grid_size.x - 1: #if the south point id could possibly exist as a neighbor
|
||||
return (x + 1) * grid_size.y + y
|
||||
return -1
|
||||
|
||||
|
||||
func get_west_point(point_id) -> int:
|
||||
var x = point_id / grid_size.y
|
||||
var y = point_id % grid_size.y
|
||||
func get_west_point(point_id: int) -> int:
|
||||
var x: int = floori(float(point_id) / float(grid_size.y))
|
||||
var y: int = point_id % grid_size.y
|
||||
if y + 1 <= grid_size.y - 1: #if the east point id could possibly exist as a neighbor
|
||||
return x * grid_size.y + y + 1
|
||||
return -1
|
||||
|
||||
|
||||
func get_east_point(point_id) -> int:
|
||||
var x = point_id / grid_size.y
|
||||
var y = point_id % grid_size.y
|
||||
func get_east_point(point_id: int) -> int:
|
||||
var x: int = floori(float(point_id) / float(grid_size.y))
|
||||
var y: int = point_id % grid_size.y
|
||||
if y - 1 >= 0: #if the west point id could possibly exist as a neighbor
|
||||
return x * grid_size.y + y - 1
|
||||
return -1
|
||||
|
||||
|
||||
func count_valid_neighbours(point_id) -> int:
|
||||
func count_valid_neighbours(point_id: int) -> int:
|
||||
if !point_id:
|
||||
return 0
|
||||
var valid_neighbours = 0
|
||||
var north_point = get_north_point(point_id)
|
||||
var south_point = get_south_point(point_id)
|
||||
var east_point = get_east_point(point_id)
|
||||
var west_point = get_west_point(point_id)
|
||||
var valid_neighbours: int = 0
|
||||
var north_point: int = get_north_point(point_id)
|
||||
var south_point: int = get_south_point(point_id)
|
||||
var east_point: int = get_east_point(point_id)
|
||||
var west_point: int = get_west_point(point_id)
|
||||
|
||||
if north_point and !astar.is_point_disabled(north_point):
|
||||
valid_neighbours += 1
|
||||
@ -118,102 +117,102 @@ func count_valid_neighbours(point_id) -> int:
|
||||
return valid_neighbours
|
||||
|
||||
|
||||
func disable_all_tower_frames():
|
||||
for frame in tower_frames:
|
||||
func disable_all_tower_frames() -> void:
|
||||
for frame: Node3D in tower_frames:
|
||||
frame.set_visible(false)
|
||||
|
||||
|
||||
func enable_non_path_tower_frames():
|
||||
for frame in tower_frames:
|
||||
func enable_non_path_tower_frames() -> void:
|
||||
for frame: Node3D in tower_frames:
|
||||
if !astar.is_point_disabled(tower_frames.find(frame)):
|
||||
frame.set_visible(true)
|
||||
disable_path_tower_frames()
|
||||
|
||||
|
||||
func disable_path_tower_frames():
|
||||
for id in astar.get_id_path(astar.get_point_count() - 2, astar.get_point_count() - 1):
|
||||
func disable_path_tower_frames() -> void:
|
||||
for id: int in astar.get_id_path(astar.get_point_count() - 2, astar.get_point_count() - 1):
|
||||
if id < (grid_size.x * grid_size.y) and !test_path_if_point_toggled(id):
|
||||
tower_frames[id].set_visible(false)
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_wall(pos : Vector3, name_id : int, caller_id : int):
|
||||
var base = tower_base_scene.instantiate() as TowerBase
|
||||
func networked_spawn_wall(pos: Vector3, name_id: int, caller_id: int) -> void:
|
||||
var base: TowerBase = tower_base_scene.instantiate() as TowerBase
|
||||
base.position = pos
|
||||
base.name = "Wall" + str(name_id)
|
||||
base.owner_id = caller_id
|
||||
var point_id = astar.get_closest_point(pos, true)
|
||||
var point_id: int = astar.get_closest_point(pos, true)
|
||||
base.point_id = point_id
|
||||
tower_base_ids[point_id] = base
|
||||
tower_bases.append(base)
|
||||
tower_path.add_child(base)
|
||||
var north_point = get_north_point(point_id)
|
||||
var south_point = get_south_point(point_id)
|
||||
var east_point = get_east_point(point_id)
|
||||
var west_point = get_west_point(point_id)
|
||||
if north_point >= 0 and astar.is_point_disabled(north_point):
|
||||
var north_point: int = get_north_point(point_id)
|
||||
var south_point: int = get_south_point(point_id)
|
||||
var east_point: int = get_east_point(point_id)
|
||||
var west_point: int = get_west_point(point_id)
|
||||
if north_point >= 0 and tower_base_ids.has(north_point) and astar.is_point_disabled(north_point):
|
||||
base.set_north_wall(true)
|
||||
tower_base_ids[north_point].set_south_wall(true)
|
||||
if south_point >= 0 and astar.is_point_disabled(south_point):
|
||||
if south_point >= 0 and tower_base_ids.has(south_point) and astar.is_point_disabled(south_point):
|
||||
base.set_south_wall(true)
|
||||
tower_base_ids[south_point].set_north_wall(true)
|
||||
if east_point >= 0 and astar.is_point_disabled(east_point):
|
||||
if east_point >= 0 and tower_base_ids.has(east_point) and astar.is_point_disabled(east_point):
|
||||
base.set_east_wall(true)
|
||||
tower_base_ids[east_point].set_west_wall(true)
|
||||
if west_point >= 0 and astar.is_point_disabled(west_point):
|
||||
if west_point >= 0 and tower_base_ids.has(west_point) and astar.is_point_disabled(west_point):
|
||||
base.set_west_wall(true)
|
||||
tower_base_ids[west_point].set_east_wall(true)
|
||||
|
||||
|
||||
@rpc("reliable", "call_local", "any_peer")
|
||||
func networked_remove_wall(new_wall_id: int):
|
||||
var wall = tower_base_ids[new_wall_id]
|
||||
func networked_remove_wall(new_wall_id: int) -> void:
|
||||
var wall: TowerBase = tower_base_ids[new_wall_id]
|
||||
Game.connected_players_nodes[wall.owner_id].currency += Data.wall_cost
|
||||
tower_bases.erase(wall)
|
||||
tower_base_ids.erase(new_wall_id)
|
||||
wall.queue_free()
|
||||
var north_point = get_north_point(new_wall_id)
|
||||
var south_point = get_south_point(new_wall_id)
|
||||
var east_point = get_east_point(new_wall_id)
|
||||
var west_point = get_west_point(new_wall_id)
|
||||
if north_point >= 0 and astar.is_point_disabled(north_point):
|
||||
var north_point: int = get_north_point(new_wall_id)
|
||||
var south_point: int = get_south_point(new_wall_id)
|
||||
var east_point: int = get_east_point(new_wall_id)
|
||||
var west_point: int = get_west_point(new_wall_id)
|
||||
if north_point >= 0 and tower_base_ids.has(north_point) and astar.is_point_disabled(north_point):
|
||||
tower_base_ids[north_point].set_south_wall(false)
|
||||
if south_point >= 0 and astar.is_point_disabled(south_point):
|
||||
if south_point >= 0 and tower_base_ids.has(south_point) and astar.is_point_disabled(south_point):
|
||||
tower_base_ids[south_point].set_north_wall(false)
|
||||
if east_point >= 0 and astar.is_point_disabled(east_point):
|
||||
if east_point >= 0 and tower_base_ids.has(east_point) and astar.is_point_disabled(east_point):
|
||||
tower_base_ids[east_point].set_west_wall(false)
|
||||
if west_point >= 0 and astar.is_point_disabled(west_point):
|
||||
if west_point >= 0 and tower_base_ids.has(west_point) and astar.is_point_disabled(west_point):
|
||||
tower_base_ids[west_point].set_east_wall(false)
|
||||
|
||||
|
||||
func build_random_maze(block_limit):
|
||||
var untested_point_ids = []
|
||||
for index in (grid_size.x * grid_size.y):
|
||||
func build_random_maze(block_limit: int) -> void:
|
||||
var untested_point_ids: Array = []
|
||||
for index: int 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()
|
||||
for index: int in block_limit:
|
||||
var random_point: int = 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, multiplayer.get_unique_id())
|
||||
|
||||
|
||||
func place_random_towers(tower_limit):
|
||||
var untowered_bases = tower_bases.duplicate()
|
||||
func place_random_towers(tower_limit: int) -> void:
|
||||
var untowered_bases: Array = 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
|
||||
for index: int in tower_limit:
|
||||
var random_base: TowerBase = untowered_bases.pick_random() as TowerBase
|
||||
untowered_bases.erase(random_base)
|
||||
random_base.add_card(Data.cards.pick_random(), multiplayer.get_unique_id())
|
||||
|
||||
|
||||
func find_path() -> bool:
|
||||
var path = astar.get_point_path(astar.get_point_count() - 2, astar.get_point_count() - 1)
|
||||
var path: PackedVector3Array = astar.get_point_path(astar.get_point_count() - 2, astar.get_point_count() - 1)
|
||||
if !path.is_empty():
|
||||
var curve = Curve3D.new()
|
||||
for point in path:
|
||||
var curve: Curve3D = Curve3D.new()
|
||||
for point: Vector3 in path:
|
||||
curve.add_point(point)
|
||||
spawner.path.curve = curve
|
||||
spawner.path.spawn_visualizer_points()
|
||||
@ -221,37 +220,37 @@ func find_path() -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func make_grid():
|
||||
for x in grid_size.x:
|
||||
for y in grid_size.y:
|
||||
var point_position = Vector3((x - floori(grid_size.x / 2)) * point_gap, 0.5, (y - floori(grid_size.y / 2)) * point_gap)
|
||||
func make_grid() -> void:
|
||||
for x: int in grid_size.x:
|
||||
for y: int in grid_size.y:
|
||||
var point_position: Vector3 = Vector3((x - floori(grid_size.x / 2.0)) * point_gap, 0.5, (y - floori(grid_size.y / 2.0)) * point_gap)
|
||||
astar.add_point(int(x * grid_size.y + y), point_position)
|
||||
var frame = tower_frame_scene.instantiate()
|
||||
var frame: Node3D = tower_frame_scene.instantiate()
|
||||
frame.position = point_position
|
||||
tower_frames.append(frame)
|
||||
add_child(frame)
|
||||
|
||||
for x in grid_size.x:
|
||||
for y in grid_size.y:
|
||||
var point_id = grid_size.y * x + y
|
||||
for x: int in grid_size.x:
|
||||
for y: int in grid_size.y:
|
||||
var point_id: int = grid_size.y * x + y
|
||||
if x > 0:
|
||||
var north_point_id = grid_size.y * (x - 1) + y
|
||||
var north_point_id: int = grid_size.y * (x - 1) + y
|
||||
astar.connect_points(point_id, north_point_id, false)
|
||||
if x < grid_size.x - 1:
|
||||
var south_point_id = grid_size.y * (x + 1) + y
|
||||
var south_point_id: int = grid_size.y * (x + 1) + y
|
||||
astar.connect_points(point_id, south_point_id, false)
|
||||
if y > 0:
|
||||
var east_point_id = grid_size.y * x + (y - 1)
|
||||
var east_point_id: int = grid_size.y * x + (y - 1)
|
||||
astar.connect_points(point_id, east_point_id, false)
|
||||
if y < grid_size.y - 1:
|
||||
var west_point_id = grid_size.y * x + (y + 1)
|
||||
var west_point_id: int = grid_size.y * x + (y + 1)
|
||||
astar.connect_points(point_id, west_point_id, false)
|
||||
|
||||
non_build_locations.append(astar.get_point_count())
|
||||
astar.add_point(astar.get_point_count(), start.global_position)
|
||||
for x in grid_size.y:
|
||||
for x: int in grid_size.y:
|
||||
astar.connect_points(int(astar.get_point_count() - 1), x)
|
||||
non_build_locations.append(astar.get_point_count())
|
||||
astar.add_point(astar.get_point_count(), end.global_position)
|
||||
for x in grid_size.y:
|
||||
for x: int in grid_size.y:
|
||||
astar.connect_points(astar.get_point_count() - 1, int(grid_size.y * (grid_size.x - 1) + x))
|
||||
|
@ -1,15 +1,14 @@
|
||||
extends Node3D
|
||||
class_name CinematicCamManager
|
||||
class_name CinematicCamManager extends Node3D
|
||||
|
||||
@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
|
||||
@export var path_follows: Array[PathFollow3D]
|
||||
@export var cameras: Array[Camera3D]
|
||||
@export var pan_speed: float = 1.0
|
||||
var current_cam: int = 0
|
||||
var does_its_thing: bool = true
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
for path_follow in path_follows:
|
||||
for path_follow: PathFollow3D in path_follows:
|
||||
path_follow.progress_ratio = 0.0
|
||||
if does_its_thing:
|
||||
cameras[0].make_current()
|
||||
|
@ -1,10 +1,9 @@
|
||||
@tool
|
||||
extends MeshInstance3D
|
||||
class_name DebugMesh
|
||||
class_name DebugMesh extends MeshInstance3D
|
||||
|
||||
|
||||
func _ready():
|
||||
var mat = StandardMaterial3D.new()
|
||||
func _ready() -> void:
|
||||
var mat: StandardMaterial3D = StandardMaterial3D.new()
|
||||
mesh = ImmediateMesh.new()
|
||||
mat.no_depth_test = true
|
||||
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
@ -13,7 +12,7 @@ func _ready():
|
||||
set_material_override(mat)
|
||||
|
||||
|
||||
func clear():
|
||||
func clear() -> void:
|
||||
mesh.clear_surfaces()
|
||||
|
||||
|
||||
@ -28,15 +27,15 @@ func draw_line(begin_pos: Vector3, end_pos: Vector3, color: Color = Color.RED) -
|
||||
func draw_sphere(center: Vector3, radius: float = 1.0, color: Color = Color.RED) -> void:
|
||||
var step: int = 30
|
||||
var sppi: float = 2 * PI / step
|
||||
var axes = [
|
||||
var axes: Array = [
|
||||
[Vector3.UP, Vector3.RIGHT],
|
||||
[Vector3.RIGHT, Vector3.FORWARD],
|
||||
[Vector3.FORWARD, Vector3.UP]
|
||||
]
|
||||
for axis in axes:
|
||||
for axis: Array in axes:
|
||||
mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP)
|
||||
mesh.surface_set_color(color)
|
||||
for i in range(step + 1):
|
||||
for i: int in range(step + 1):
|
||||
mesh.surface_add_vertex(center + (axis[0] * radius)
|
||||
.rotated(axis[1], sppi * (i % step)))
|
||||
mesh.surface_end()
|
||||
|
@ -1,8 +1,7 @@
|
||||
extends EnemyMovement
|
||||
class_name BeeliningController
|
||||
class_name BeeliningController extends EnemyMovement
|
||||
|
||||
var goal : Node3D
|
||||
var direction : Vector3
|
||||
var goal: Node3D
|
||||
var direction: Vector3
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -11,6 +10,6 @@ func _ready() -> void:
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var distance_travelled = (character.stats.movement_speed * clampf(character.movement_speed_penalty, 0.0, 1.0)) * delta
|
||||
var distance_travelled: float = (character.stats.movement_speed * clampf(character.movement_speed_penalty, 0.0, 1.0)) * delta
|
||||
distance_remaining -= distance_travelled
|
||||
character.global_position = character.global_position + (direction * distance_travelled)
|
||||
|
@ -1,6 +1,5 @@
|
||||
extends Node
|
||||
class_name EnemyMovement
|
||||
class_name EnemyMovement extends Node
|
||||
|
||||
@export var character : CharacterBody3D
|
||||
@export var character: CharacterBody3D
|
||||
|
||||
var distance_remaining := 0.0
|
||||
var distance_remaining: float = 0.0
|
||||
|
@ -1,8 +1,7 @@
|
||||
extends EnemyMovement
|
||||
class_name PathingController
|
||||
class_name PathingController extends EnemyMovement
|
||||
|
||||
var path : Curve3D
|
||||
var path_progress = 0.0
|
||||
var path: Curve3D
|
||||
var path_progress: float = 0.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -13,9 +12,9 @@ func _ready() -> void:
|
||||
func _physics_process(delta: float) -> void:
|
||||
if !path:
|
||||
return
|
||||
var distance_travelled = (character.stats.movement_speed * clampf(character.movement_speed_penalty, 0.0, 1.0)) * delta
|
||||
var distance_travelled: float = (character.stats.movement_speed * clampf(character.movement_speed_penalty, 0.0, 1.0)) * delta
|
||||
distance_remaining -= distance_travelled
|
||||
path_progress += distance_travelled
|
||||
var sample = path.sample_baked_with_rotation(path_progress, true)
|
||||
var sample: Transform3D = path.sample_baked_with_rotation(path_progress, true)
|
||||
character.global_position = sample.origin
|
||||
character.look_at(character.global_position + -sample.basis.z)
|
||||
|
@ -1,50 +1,49 @@
|
||||
extends CanvasLayer
|
||||
class_name HUD
|
||||
class_name HUD extends CanvasLayer
|
||||
|
||||
var last_lives_count = 120
|
||||
@export var wave_count : Label
|
||||
@export var lives_count : Label
|
||||
@export var currency_count : Label
|
||||
@export var minimap_outline : TextureRect
|
||||
@export var crosshair : Control
|
||||
@export var minimap : TextureRect
|
||||
@export var minimap_cam : MinimapCamera3D
|
||||
@export var minimap_viewport : SubViewport
|
||||
@export var fps_label : Label
|
||||
@export var hover_text : Label
|
||||
var minimap_anchor : Node3D
|
||||
var enemy_names = []
|
||||
@export var enemy_sprites : Array[TextureRect]
|
||||
@export var enemy_counts : Array[Label]
|
||||
@export var weapon_energy_bar : TextureProgressBar
|
||||
@export var offhand_energy_bar : TextureProgressBar
|
||||
@export var pickup_notif_scene : PackedScene
|
||||
@export var wave_start_label : Label
|
||||
var last_lives_count: int = 120
|
||||
@export var wave_count: Label
|
||||
@export var lives_count: Label
|
||||
@export var currency_count: Label
|
||||
@export var minimap_outline: TextureRect
|
||||
@export var crosshair: Control
|
||||
@export var minimap: TextureRect
|
||||
@export var minimap_cam: MinimapCamera3D
|
||||
@export var minimap_viewport: SubViewport
|
||||
@export var fps_label: Label
|
||||
@export var hover_text: Label
|
||||
var minimap_anchor: Node3D
|
||||
var enemy_names: Array[String]
|
||||
@export var enemy_sprites: Array[TextureRect]
|
||||
@export var enemy_counts: Array[Label]
|
||||
@export var weapon_energy_bar: TextureProgressBar
|
||||
@export var offhand_energy_bar: TextureProgressBar
|
||||
@export var pickup_notif_scene: PackedScene
|
||||
@export var wave_start_label: Label
|
||||
|
||||
|
||||
func set_energy_visible(value):
|
||||
func set_energy_visible(value: bool) -> void:
|
||||
weapon_energy_bar.set_visible(value)
|
||||
|
||||
|
||||
func set_offhand_energy_visible(value):
|
||||
func set_offhand_energy_visible(value: bool) -> void:
|
||||
offhand_energy_bar.set_visible(value)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
func _process(_delta: float) -> void:
|
||||
fps_label.text = "FPS: " + str(Engine.get_frames_per_second())
|
||||
wave_start_label.text = "Press [" + Data.player_keymap.ready.as_text_key_label() + "] to start wave"
|
||||
|
||||
|
||||
func grow_wave_start_label():
|
||||
func grow_wave_start_label() -> void:
|
||||
tween_label(300.0)
|
||||
|
||||
|
||||
func shrink_wave_start_label():
|
||||
func shrink_wave_start_label() -> void:
|
||||
tween_label(0.0)
|
||||
|
||||
|
||||
func tween_label(x: float) -> void:
|
||||
var tween = create_tween()
|
||||
var tween: Tween = create_tween()
|
||||
tween.set_ease(Tween.EASE_IN_OUT)
|
||||
tween.set_trans(Tween.TRANS_QUAD)
|
||||
if x > 0.0:
|
||||
@ -55,45 +54,45 @@ func tween_label(x: float) -> void:
|
||||
tween.tween_callback(wave_start_label.set_visible.bind(false))
|
||||
|
||||
|
||||
func set_hover_text(text):
|
||||
func set_hover_text(text: String) -> void:
|
||||
hover_text.text = text
|
||||
hover_text.set_visible(true)
|
||||
|
||||
|
||||
func unset_hover_text():
|
||||
func unset_hover_text() -> void:
|
||||
hover_text.set_visible(false)
|
||||
|
||||
|
||||
func set_wave_count(value):
|
||||
func set_wave_count(value: int) -> void:
|
||||
wave_count.text = str(value)
|
||||
|
||||
|
||||
func set_lives_count(value):
|
||||
func set_lives_count(value: int) -> void:
|
||||
lives_count.text = str(value)
|
||||
for x in last_lives_count - value:
|
||||
for x: int in last_lives_count - value:
|
||||
$LivesBar.take_life()
|
||||
last_lives_count = value
|
||||
|
||||
|
||||
func enemy_count_down(enemy):
|
||||
var index = enemy_names.find(enemy.title)
|
||||
var num = enemy_counts[index].text.to_int() - 1
|
||||
func enemy_count_down(enemy: Enemy) -> void:
|
||||
var index: int = enemy_names.find(enemy.title)
|
||||
var num: int = enemy_counts[index].text.to_int() - 1
|
||||
enemy_counts[index].text = str(num)
|
||||
if num == 0:
|
||||
enemy_counts[index].set_visible(false)
|
||||
enemy_sprites[index].set_visible(false)
|
||||
|
||||
|
||||
func set_upcoming_wave(value):
|
||||
var frame_count = 0
|
||||
func set_upcoming_wave(value: Dictionary) -> void:
|
||||
var frame_count: int = 0
|
||||
enemy_names = []
|
||||
var wave = {}
|
||||
for index in value:
|
||||
var wave: Dictionary = {}
|
||||
for index: int in value:
|
||||
wave[Data.enemies[index]] = value[index]
|
||||
for x in enemy_sprites.size():
|
||||
for x: int in enemy_sprites.size():
|
||||
enemy_sprites[x].set_visible(false)
|
||||
enemy_counts[x].set_visible(false)
|
||||
for enemy in wave:
|
||||
for enemy: Enemy in wave:
|
||||
enemy_names.append(enemy.title)
|
||||
enemy_sprites[frame_count].texture = enemy.icon
|
||||
enemy_counts[frame_count].text = str(wave[enemy])
|
||||
@ -102,23 +101,23 @@ func set_upcoming_wave(value):
|
||||
frame_count += 1
|
||||
|
||||
|
||||
func set_currency_count(value):
|
||||
func set_currency_count(value: int) -> void:
|
||||
currency_count.text = str(value)
|
||||
|
||||
|
||||
func set_crosshair_visible(value : bool):
|
||||
func set_crosshair_visible(value: bool) -> void:
|
||||
crosshair.set_visible(value)
|
||||
|
||||
|
||||
func set_weapon_energy(value):
|
||||
func set_weapon_energy(value: int) -> void:
|
||||
weapon_energy_bar.value = value
|
||||
|
||||
|
||||
func set_offhand_energy(value):
|
||||
func set_offhand_energy(value: int) -> void:
|
||||
offhand_energy_bar.value = value
|
||||
|
||||
|
||||
func maximise_minimap(anchor):
|
||||
func maximise_minimap(anchor: Node3D) -> void:
|
||||
minimap_cam.anchor = anchor
|
||||
minimap.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
minimap.offset_bottom = -40
|
||||
@ -131,7 +130,7 @@ func maximise_minimap(anchor):
|
||||
currency_count.set_visible(false)
|
||||
|
||||
|
||||
func minimize_minimap(anchor):
|
||||
func minimize_minimap(anchor: Node3D) -> void:
|
||||
minimap_cam.anchor = anchor
|
||||
minimap.set_anchors_and_offsets_preset(Control.PRESET_TOP_RIGHT)
|
||||
minimap.offset_right = -40
|
||||
@ -145,6 +144,6 @@ func minimize_minimap(anchor):
|
||||
|
||||
|
||||
func pickup(card: Card) -> void:
|
||||
var notif = pickup_notif_scene.instantiate()
|
||||
var notif: PickupNotification = pickup_notif_scene.instantiate()
|
||||
notif.set_card(card)
|
||||
$VBoxContainer.add_child(notif)
|
||||
|
@ -1,11 +1,10 @@
|
||||
extends Projectile
|
||||
class_name ExplosiveProjectile
|
||||
class_name ExplosiveProjectile extends Projectile
|
||||
|
||||
@export var explosion_range := 3.0
|
||||
@export var explosion_range: float = 3.0
|
||||
|
||||
var exploded := false
|
||||
var sound_done := false
|
||||
var particles_done := false
|
||||
var exploded: bool = false
|
||||
var sound_done: bool = false
|
||||
var particles_done: bool = false
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
@ -18,12 +17,12 @@ func _on_body_entered(_body: Node) -> void:
|
||||
explode()
|
||||
|
||||
|
||||
func explode():
|
||||
func explode() -> void:
|
||||
if is_multiplayer_authority() and !exploded:
|
||||
freeze = true
|
||||
exploded = true
|
||||
$CollisionShape3D.call_deferred("set_disabled", true)
|
||||
for enemy in get_tree().get_nodes_in_group("Enemies"):
|
||||
for enemy: EnemyController in get_tree().get_nodes_in_group("Enemies"):
|
||||
if global_position.distance_to(enemy.global_position) <= explosion_range:
|
||||
hit(enemy)
|
||||
networked_hit.rpc(get_tree().root.get_path_to(enemy))
|
||||
@ -33,7 +32,7 @@ func explode():
|
||||
$AudioStreamPlayer.play()
|
||||
|
||||
|
||||
func hit(target):
|
||||
func hit(target: CharacterBody3D) -> void:
|
||||
target.damage(damage)
|
||||
if owner_id == 0:
|
||||
if Data.preferences.display_tower_damage_indicators:
|
||||
@ -47,13 +46,13 @@ func hit(target):
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_hit(target_node_path):
|
||||
var target = get_tree().root.get_node(target_node_path)
|
||||
func networked_hit(target_node_path: String) -> void:
|
||||
var target: CharacterBody3D = get_tree().root.get_node(target_node_path)
|
||||
hit(target)
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_kill():
|
||||
func networked_kill() -> void:
|
||||
$Sprite3D.set_visible(false)
|
||||
$GPUParticles3D.emitting = true
|
||||
$AudioStreamPlayer.play()
|
||||
|
@ -1,9 +1,8 @@
|
||||
extends ExplosiveProjectile
|
||||
class_name HomingProjectile
|
||||
class_name HomingProjectile extends ExplosiveProjectile
|
||||
|
||||
var target : Node3D
|
||||
var acceleration := 50.0
|
||||
var max_speed := 13.0
|
||||
var target: Node3D
|
||||
var acceleration: float = 50.0
|
||||
var max_speed: float = 13.0
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
|
@ -1,15 +1,14 @@
|
||||
extends RigidBody3D
|
||||
class_name Projectile
|
||||
class_name Projectile extends RigidBody3D
|
||||
|
||||
@export var collision_shape : CollisionShape3D
|
||||
@export var collision_shape: CollisionShape3D
|
||||
|
||||
var damage_particle_scene = preload("res://Scenes/damage_particle.tscn")
|
||||
var owner_id = 0 #should be left unchanged by towers, 1 for host, peer_id on peers
|
||||
var direction := Vector3.FORWARD
|
||||
var force := 2.0
|
||||
var damage := 0.0
|
||||
var lifetime := 10.0
|
||||
var time_alive := 0.0
|
||||
var damage_particle_scene: PackedScene = preload("res://Scenes/damage_particle.tscn")
|
||||
var owner_id: int = 0 #should be left unchanged by towers, 1 for host, peer_id on peers
|
||||
var direction: Vector3= Vector3.FORWARD
|
||||
var force: float = 2.0
|
||||
var damage: float = 0.0
|
||||
var lifetime: float = 10.0
|
||||
var time_alive: float = 0.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -20,9 +19,9 @@ func _process(delta: float) -> void:
|
||||
time_alive += delta
|
||||
|
||||
|
||||
func spawn_damage_indicator(pos):
|
||||
func spawn_damage_indicator(pos: Vector3) -> void:
|
||||
if damage > 0:
|
||||
var marker = damage_particle_scene.instantiate()
|
||||
var marker: Node3D = damage_particle_scene.instantiate()
|
||||
get_tree().root.add_child(marker)
|
||||
marker.set_number(damage)
|
||||
marker.position = pos
|
||||
@ -33,5 +32,5 @@ func _on_body_entered(_body: Node) -> void:
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_kill():
|
||||
func networked_kill() -> void:
|
||||
queue_free()
|
||||
|
@ -1,15 +1,14 @@
|
||||
extends ExplosiveProjectile
|
||||
class_name StatusApplyingProjectile
|
||||
class_name StatusApplyingProjectile extends ExplosiveProjectile
|
||||
|
||||
@export var status_stats : StatusStats
|
||||
@export var status_stats: StatusStats
|
||||
|
||||
|
||||
func hit(target):
|
||||
func hit(target: CharacterBody3D) -> void:
|
||||
super.hit(target)
|
||||
target.status_manager.add_effect(build_status_object())
|
||||
|
||||
|
||||
func build_status_object() -> StatusEffect:
|
||||
var status = StatusEffect.new()
|
||||
var status: StatusEffect = StatusEffect.new()
|
||||
status.stats = status_stats
|
||||
return status
|
||||
|
@ -1,11 +1,10 @@
|
||||
extends Item
|
||||
class_name Card
|
||||
class_name Card extends Item
|
||||
|
||||
enum Faction {GENERIC = 0}
|
||||
|
||||
@export var rarity : Data.Rarity
|
||||
@export var faction : Faction
|
||||
@export var turret_scene : PackedScene
|
||||
@export var weapon_scene : PackedScene
|
||||
@export var weapon_stats : CardText
|
||||
@export var tower_stats : CardText
|
||||
@export var rarity: Data.Rarity
|
||||
@export var faction: Faction
|
||||
@export var turret_scene: PackedScene
|
||||
@export var weapon_scene: PackedScene
|
||||
@export var weapon_stats: CardText
|
||||
@export var tower_stats: CardText
|
||||
|
@ -1,13 +1,12 @@
|
||||
extends Resource
|
||||
class_name CardText
|
||||
class_name CardText extends Resource
|
||||
|
||||
@export var target_type : Data.TargetType
|
||||
@export var attributes : Array[StatAttribute]
|
||||
@export_multiline var text : String
|
||||
@export var target_type: Data.TargetType
|
||||
@export var attributes: Array[StatAttribute]
|
||||
@export_multiline var text: String
|
||||
|
||||
|
||||
func get_attribute(attribute : String) -> float:
|
||||
for stat in attributes:
|
||||
func get_attribute(attribute: String) -> float:
|
||||
for stat: StatAttribute in attributes:
|
||||
if stat.key == attribute:
|
||||
return stat.value
|
||||
return 0.0
|
||||
|
@ -1,13 +1,12 @@
|
||||
extends Resource
|
||||
class_name Enemy
|
||||
class_name Enemy extends Resource
|
||||
|
||||
@export var title := "dog"
|
||||
@export var title: String = "dog"
|
||||
@export var target_type: Data.EnemyType
|
||||
@export var icon: Texture
|
||||
@export var death_sprite: Texture
|
||||
@export var sprite: AtlasTexture
|
||||
@export var spawn_power:= 10
|
||||
@export var health := 100
|
||||
@export var penalty := 10
|
||||
@export var movement_speed := 0.5
|
||||
@export var spawn_cooldown := 1.0
|
||||
@export var spawn_power: int = 10
|
||||
@export var health: int = 100
|
||||
@export var penalty: int = 10
|
||||
@export var movement_speed: float = 0.5
|
||||
@export var spawn_cooldown: float = 1.0
|
||||
|
@ -1,7 +1,6 @@
|
||||
extends Resource
|
||||
class_name HeroClass
|
||||
class_name HeroClass extends Resource
|
||||
|
||||
@export var hero_name : String = "Default"
|
||||
@export var texture : Texture
|
||||
@export var hand_texture : Texture
|
||||
@export var deck : Array[Card]
|
||||
@export var hero_name: String = "Default"
|
||||
@export var texture: Texture
|
||||
@export var hand_texture: Texture
|
||||
@export var deck: Array[Card]
|
||||
|
@ -1,5 +1,4 @@
|
||||
extends Resource
|
||||
class_name Item
|
||||
class_name Item extends Resource
|
||||
|
||||
@export var display_name : String
|
||||
@export var icon : Texture
|
||||
@export var display_name: String
|
||||
@export var icon: Texture
|
||||
|
@ -1,20 +1,19 @@
|
||||
extends Resource
|
||||
class_name PlayerAudioSettings
|
||||
class_name PlayerAudioSettings extends Resource
|
||||
|
||||
const SAVE_PATH := "user://audio_settings.tres"
|
||||
const SAVE_PATH: String = "user://audio_settings.tres"
|
||||
|
||||
@export var master := 100.0
|
||||
@export var music := 100.0
|
||||
@export var sfx := 100.0
|
||||
@export var master: float = 100.0
|
||||
@export var music: float = 100.0
|
||||
@export var sfx: float = 100.0
|
||||
|
||||
|
||||
func apply_audio_settings():
|
||||
func apply_audio_settings() -> void:
|
||||
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear_to_db(master / 100.0))
|
||||
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), linear_to_db(music / 100.0))
|
||||
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("SFX"), linear_to_db(sfx / 100.0))
|
||||
|
||||
|
||||
func save_profile_to_disk():
|
||||
func save_profile_to_disk() -> void:
|
||||
ResourceSaver.save(self, SAVE_PATH)
|
||||
static func load_profile_from_disk() -> PlayerAudioSettings:
|
||||
if ResourceLoader.exists(SAVE_PATH):
|
||||
|
@ -1,15 +1,14 @@
|
||||
extends Resource
|
||||
class_name PlayerGraphicsSettings
|
||||
class_name PlayerGraphicsSettings extends Resource
|
||||
|
||||
const SAVE_PATH := "user://graphics_settings.tres"
|
||||
const SAVE_PATH: String = "user://graphics_settings.tres"
|
||||
|
||||
@export var hfov := 100.0
|
||||
@export var vsync_mode := 1
|
||||
@export var aa_mode := 0
|
||||
@export var windowed_mode := 0
|
||||
@export var hfov: float = 100.0
|
||||
@export var vsync_mode: int = 1
|
||||
@export var aa_mode: int = 0
|
||||
@export var windowed_mode: int = 0
|
||||
|
||||
|
||||
func apply_graphical_settings(viewport):
|
||||
func apply_graphical_settings(viewport: Viewport) -> void:
|
||||
DisplayServer.window_set_vsync_mode(vsync_mode)
|
||||
match aa_mode:
|
||||
0:
|
||||
@ -30,7 +29,7 @@ func apply_graphical_settings(viewport):
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN)
|
||||
|
||||
|
||||
func save_profile_to_disk():
|
||||
func save_profile_to_disk() -> void:
|
||||
ResourceSaver.save(self, SAVE_PATH)
|
||||
static func load_profile_from_disk() -> PlayerGraphicsSettings:
|
||||
if ResourceLoader.exists(SAVE_PATH):
|
||||
|
@ -1,60 +1,173 @@
|
||||
extends Resource
|
||||
class_name PlayerKeymap
|
||||
class_name PlayerKeymap extends Resource
|
||||
|
||||
const SAVE_PATH := "user://keymap.tres"
|
||||
const SAVE_PATH: String = "user://keymap.tres"
|
||||
|
||||
@export var title : String
|
||||
@export var title: String
|
||||
|
||||
@export var move_forward : InputEventKey
|
||||
@export var move_backward : InputEventKey
|
||||
@export var move_left : InputEventKey
|
||||
@export var move_right : InputEventKey
|
||||
@export var jump : InputEventKey
|
||||
@export var sprint : InputEventKey
|
||||
@export var interact : InputEventKey
|
||||
@export var open_text_chat : InputEventKey
|
||||
@export var ready : InputEventKey
|
||||
@export var pause : InputEventKey
|
||||
@export var equip_card_in_gauntlet : InputEventKey
|
||||
@export var view_map : InputEventKey
|
||||
@export_category("Primary Bindings")
|
||||
@export var move_forward: InputEvent
|
||||
@export var move_backward: InputEvent
|
||||
@export var move_left: InputEvent
|
||||
@export var move_right: InputEvent
|
||||
@export var jump: InputEvent
|
||||
@export var sprint: InputEvent
|
||||
@export var interact: InputEvent
|
||||
@export var open_text_chat: InputEvent
|
||||
@export var ready: InputEvent
|
||||
@export var pause: InputEvent
|
||||
@export var equip_card_in_gauntlet: InputEvent
|
||||
@export var view_map: InputEvent
|
||||
@export var fire1: InputEvent
|
||||
@export var fire2: InputEvent
|
||||
@export var select_next_card: InputEvent
|
||||
@export var select_prev_card: InputEvent
|
||||
|
||||
@export_category("Secondary Bindings")
|
||||
@export var secondary_move_forward: InputEvent
|
||||
@export var secondary_move_backward: InputEvent
|
||||
@export var secondary_move_left: InputEvent
|
||||
@export var secondary_move_right: InputEvent
|
||||
@export var secondary_jump: InputEvent
|
||||
@export var secondary_sprint: InputEvent
|
||||
@export var secondary_interact: InputEvent
|
||||
@export var secondary_open_text_chat: InputEvent
|
||||
@export var secondary_ready: InputEvent
|
||||
@export var secondary_pause: InputEvent
|
||||
@export var secondary_equip_card_in_gauntlet: InputEvent
|
||||
@export var secondary_view_map: InputEvent
|
||||
@export var secondary_fire1: InputEvent
|
||||
@export var secondary_fire2: InputEvent
|
||||
@export var secondary_select_next_card: InputEvent
|
||||
@export var secondary_select_prev_card: InputEvent
|
||||
|
||||
|
||||
func apply():
|
||||
replace_action_event("Move Forward", move_forward)
|
||||
replace_action_event("Move Backward", move_backward)
|
||||
replace_action_event("Move Left", move_left)
|
||||
replace_action_event("Move Right", move_right)
|
||||
replace_action_event("Jump", jump)
|
||||
replace_action_event("Sprint", sprint)
|
||||
replace_action_event("Interact", interact)
|
||||
replace_action_event("Open Text Chat", open_text_chat)
|
||||
replace_action_event("Ready", ready)
|
||||
replace_action_event("Pause", pause)
|
||||
replace_action_event("Equip In Gauntlet", equip_card_in_gauntlet)
|
||||
replace_action_event("View Map", view_map)
|
||||
func apply() -> void:
|
||||
replace_action_event("Move Forward", move_forward, secondary_move_forward)
|
||||
replace_action_event("Move Backward", move_backward, secondary_move_backward)
|
||||
replace_action_event("Move Left", move_left, secondary_move_left)
|
||||
replace_action_event("Move Right", move_right, secondary_move_right)
|
||||
replace_action_event("Jump", jump, secondary_jump)
|
||||
replace_action_event("Sprint", sprint, secondary_sprint)
|
||||
replace_action_event("Interact", interact, secondary_interact)
|
||||
replace_action_event("Open Text Chat", open_text_chat, secondary_open_text_chat)
|
||||
replace_action_event("Ready", ready, secondary_ready)
|
||||
replace_action_event("Pause", pause, secondary_pause)
|
||||
replace_action_event("Equip In Gauntlet", equip_card_in_gauntlet, secondary_equip_card_in_gauntlet)
|
||||
replace_action_event("View Map", view_map, secondary_view_map)
|
||||
replace_action_event("Primary Fire", fire1, secondary_fire1)
|
||||
replace_action_event("Secondary Fire", fire2, secondary_fire2)
|
||||
replace_action_event("Select Next Card", select_next_card, secondary_select_next_card)
|
||||
replace_action_event("Select Previous Card", select_prev_card, secondary_select_prev_card)
|
||||
|
||||
|
||||
func replace_action_event(action_string, event):
|
||||
func replace_action_event(action_string: String, event: InputEvent, secondary_event: InputEvent) -> void:
|
||||
InputMap.action_erase_events(action_string)
|
||||
InputMap.action_add_event(action_string, event)
|
||||
if event:
|
||||
InputMap.action_add_event(action_string, event)
|
||||
if secondary_event:
|
||||
InputMap.action_add_event(action_string, secondary_event)
|
||||
|
||||
|
||||
func get_current_input_map():
|
||||
func set_primary_action_event(action_string: String, event: InputEvent) -> void:
|
||||
var secondary_event: InputEvent
|
||||
if InputMap.action_get_events(action_string).size() > 1:
|
||||
secondary_event = InputMap.action_get_events(action_string)[1]
|
||||
replace_action_event(action_string, event, secondary_event)
|
||||
|
||||
|
||||
func set_secondary_action_event(action_string: String, event: InputEvent) -> void:
|
||||
var primary_event: InputEvent
|
||||
if InputMap.action_get_events(action_string).size() > 0:
|
||||
primary_event = InputMap.action_get_events(action_string)[0]
|
||||
replace_action_event(action_string, primary_event, event)
|
||||
|
||||
|
||||
func append_input_map() -> void:
|
||||
InputMap.action_add_event("Move Forward", move_forward)
|
||||
InputMap.action_add_event("Move Backward", move_backward)
|
||||
InputMap.action_add_event("Move Left", move_left)
|
||||
InputMap.action_add_event("Move Right", move_right)
|
||||
InputMap.action_add_event("Jump", jump)
|
||||
InputMap.action_add_event("Sprint", sprint)
|
||||
InputMap.action_add_event("Interact", interact)
|
||||
InputMap.action_add_event("Open Text Chat", open_text_chat)
|
||||
InputMap.action_add_event("Ready", ready)
|
||||
InputMap.action_add_event("Pause", pause)
|
||||
InputMap.action_add_event("Equip In Gauntlet", equip_card_in_gauntlet)
|
||||
InputMap.action_add_event("View Map", view_map)
|
||||
InputMap.action_add_event("Primary Fire", fire1)
|
||||
InputMap.action_add_event("Secondary Fire", fire2)
|
||||
InputMap.action_add_event("Select Next Card", select_next_card)
|
||||
InputMap.action_add_event("Select Previous Card", select_prev_card)
|
||||
|
||||
|
||||
func get_current_input_map() -> void:
|
||||
move_forward = InputMap.action_get_events("Move Forward")[0]
|
||||
if InputMap.action_get_events("Move Forward").size() > 1:
|
||||
secondary_move_forward = InputMap.action_get_events("Move Forward")[1]
|
||||
|
||||
move_backward = InputMap.action_get_events("Move Backward")[0]
|
||||
if InputMap.action_get_events("Move Backward").size() > 1:
|
||||
secondary_move_backward = InputMap.action_get_events("Move Backward")[1]
|
||||
|
||||
move_left = InputMap.action_get_events("Move Left")[0]
|
||||
if InputMap.action_get_events("Move Left").size() > 1:
|
||||
secondary_move_left = InputMap.action_get_events("Move Left")[1]
|
||||
|
||||
move_right = InputMap.action_get_events("Move Right")[0]
|
||||
if InputMap.action_get_events("Move Right").size() > 1:
|
||||
secondary_move_right = InputMap.action_get_events("Move Right")[1]
|
||||
|
||||
jump = InputMap.action_get_events("Jump")[0]
|
||||
if InputMap.action_get_events("Jump").size() > 1:
|
||||
secondary_jump = InputMap.action_get_events("Jump")[1]
|
||||
|
||||
sprint = InputMap.action_get_events("Sprint")[0]
|
||||
if InputMap.action_get_events("Sprint").size() > 1:
|
||||
secondary_sprint = InputMap.action_get_events("Sprint")[1]
|
||||
|
||||
interact = InputMap.action_get_events("Interact")[0]
|
||||
if InputMap.action_get_events("Interact").size() > 1:
|
||||
secondary_interact = InputMap.action_get_events("Interact")[1]
|
||||
|
||||
open_text_chat = InputMap.action_get_events("Open Text Chat")[0]
|
||||
if InputMap.action_get_events("Open Text Chat").size() > 1:
|
||||
secondary_open_text_chat = InputMap.action_get_events("Open Text Chat")[1]
|
||||
|
||||
ready = InputMap.action_get_events("Ready")[0]
|
||||
if InputMap.action_get_events("Ready").size() > 1:
|
||||
secondary_ready = InputMap.action_get_events("Ready")[1]
|
||||
|
||||
pause = InputMap.action_get_events("Pause")[0]
|
||||
if InputMap.action_get_events("Pause").size() > 1:
|
||||
secondary_pause = InputMap.action_get_events("Pause")[1]
|
||||
|
||||
equip_card_in_gauntlet = InputMap.action_get_events("Equip In Gauntlet")[0]
|
||||
if InputMap.action_get_events("Equip In Gauntlet").size() > 1:
|
||||
secondary_equip_card_in_gauntlet = InputMap.action_get_events("Equip In Gauntlet")[1]
|
||||
|
||||
view_map = InputMap.action_get_events("View Map")[0]
|
||||
if InputMap.action_get_events("View Map").size() > 1:
|
||||
secondary_view_map = InputMap.action_get_events("View Map")[1]
|
||||
|
||||
fire1 = InputMap.action_get_events("Primary Fire")[0]
|
||||
if InputMap.action_get_events("Primary Fire").size() > 1:
|
||||
secondary_fire1 = InputMap.action_get_events("Primary Fire")[1]
|
||||
|
||||
fire2 = InputMap.action_get_events("Secondary Fire")[0]
|
||||
if InputMap.action_get_events("Secondary Fire").size() > 1:
|
||||
secondary_fire2 = InputMap.action_get_events("Secondary Fire")[1]
|
||||
|
||||
select_next_card = InputMap.action_get_events("Select Next Card")[0]
|
||||
if InputMap.action_get_events("Select Next Card").size() > 1:
|
||||
secondary_select_next_card = InputMap.action_get_events("Select Next Card")[1]
|
||||
|
||||
select_prev_card = InputMap.action_get_events("Select Previous Card")[0]
|
||||
if InputMap.action_get_events("Select Previous Card").size() > 1:
|
||||
secondary_select_prev_card = InputMap.action_get_events("Select Previous Card")[1]
|
||||
|
||||
|
||||
func save_profile_to_disk():
|
||||
func save_profile_to_disk() -> void:
|
||||
get_current_input_map()
|
||||
ResourceSaver.save(self, SAVE_PATH)
|
||||
static func load_profile_from_disk() -> PlayerKeymap:
|
||||
|
@ -1,20 +1,19 @@
|
||||
extends Resource
|
||||
class_name PlayerPreferences
|
||||
class_name PlayerPreferences extends Resource
|
||||
|
||||
const SAVE_PATH := "user://preferences.tres"
|
||||
const SAVE_PATH: String = "user://preferences.tres"
|
||||
|
||||
@export var mouse_sens := 28.0
|
||||
@export var invert_lookY := false
|
||||
@export var invert_lookX := false
|
||||
@export var toggle_sprint := false
|
||||
@export var fixed_minimap := false
|
||||
@export var display_tower_damage_indicators := true
|
||||
@export var display_self_damage_indicators := true
|
||||
@export var display_party_damage_indicators := true
|
||||
@export var display_status_effect_damage_indicators := true
|
||||
@export var mouse_sens: float = 28.0
|
||||
@export var invert_lookY: bool = false
|
||||
@export var invert_lookX: bool = false
|
||||
@export var toggle_sprint: bool = false
|
||||
@export var fixed_minimap: bool = false
|
||||
@export var display_tower_damage_indicators: bool = true
|
||||
@export var display_self_damage_indicators: bool = true
|
||||
@export var display_party_damage_indicators: bool = true
|
||||
@export var display_status_effect_damage_indicators: bool = true
|
||||
|
||||
|
||||
func save_profile_to_disk():
|
||||
func save_profile_to_disk() -> void:
|
||||
ResourceSaver.save(self, SAVE_PATH)
|
||||
static func load_profile_from_disk() -> PlayerPreferences:
|
||||
if ResourceLoader.exists(SAVE_PATH):
|
||||
|
@ -1,45 +1,44 @@
|
||||
extends Resource
|
||||
class_name PlayerProfile
|
||||
class_name PlayerProfile extends Resource
|
||||
|
||||
signal display_name_changed(old_name, new_name)
|
||||
signal preferred_class_changed(old_class, new_class)
|
||||
signal display_name_changed(old_name: String, new_name: String)
|
||||
signal preferred_class_changed(old_class: int, new_class: int)
|
||||
|
||||
const SAVE_PATH := "user://profile.tres"
|
||||
const SAVE_PATH: String = "user://profile.tres"
|
||||
|
||||
@export var display_name := "Charlie"
|
||||
@export var preferred_class := 0
|
||||
@export var display_name: String = "Charlie"
|
||||
@export var preferred_class: int = 0
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
var dict = {}
|
||||
var dict: Dictionary = {}
|
||||
dict["display_name"] = display_name
|
||||
dict["preferred_class"] = preferred_class
|
||||
return dict
|
||||
static func from_dict(dict) -> PlayerProfile:
|
||||
var output = PlayerProfile.new()
|
||||
static func from_dict(dict: Dictionary) -> PlayerProfile:
|
||||
var output: PlayerProfile = PlayerProfile.new()
|
||||
output.display_name = dict["display_name"]
|
||||
output.preferred_class = dict["preferred_class"]
|
||||
return output
|
||||
|
||||
func set_display_name(new_display_name):
|
||||
func set_display_name(new_display_name: String) -> void:
|
||||
if new_display_name == display_name:
|
||||
return
|
||||
var old_name = display_name
|
||||
var old_name: String = display_name
|
||||
display_name = new_display_name
|
||||
save_profile_to_disk()
|
||||
display_name_changed.emit(old_name, display_name)
|
||||
func get_display_name() -> String:
|
||||
return display_name
|
||||
|
||||
func set_preferred_class(new_preferred_class):
|
||||
func set_preferred_class(new_preferred_class: int) -> void:
|
||||
if new_preferred_class == preferred_class:
|
||||
return
|
||||
var old_class = preferred_class
|
||||
var old_class: int = preferred_class
|
||||
preferred_class = new_preferred_class
|
||||
preferred_class_changed.emit(old_class, preferred_class)
|
||||
func get_preferred_class() -> int:
|
||||
return preferred_class
|
||||
|
||||
func save_profile_to_disk():
|
||||
func save_profile_to_disk() -> void:
|
||||
ResourceSaver.save(self, SAVE_PATH)
|
||||
static func load_profile_from_disk() -> PlayerProfile:
|
||||
if ResourceLoader.exists(SAVE_PATH):
|
||||
|
@ -1,7 +1,6 @@
|
||||
extends Resource
|
||||
class_name SaveStats
|
||||
class_name SaveStats extends Resource
|
||||
|
||||
const SAVE_PATH := "user://save_stats.tres"
|
||||
const SAVE_PATH: String = "user://save_stats.tres"
|
||||
|
||||
@export var wins: int
|
||||
@export var losses: int
|
||||
@ -18,7 +17,7 @@ func add_game_outcome(outcome: bool) -> void:
|
||||
twenty_game_history.pop_front()
|
||||
|
||||
|
||||
func save_profile_to_disk():
|
||||
func save_profile_to_disk() -> void:
|
||||
ResourceSaver.save(self, SAVE_PATH)
|
||||
static func load_profile_from_disk() -> SaveStats:
|
||||
if ResourceLoader.exists(SAVE_PATH):
|
||||
|
@ -1,5 +1,4 @@
|
||||
extends Resource
|
||||
class_name StatAttribute
|
||||
class_name StatAttribute extends Resource
|
||||
|
||||
@export var key : String
|
||||
@export var value : float
|
||||
@export var key: String
|
||||
@export var value: float
|
||||
|
@ -1,9 +1,8 @@
|
||||
extends Resource
|
||||
class_name StatusStats
|
||||
class_name StatusStats extends Resource
|
||||
|
||||
@export var name : String
|
||||
@export var max_stacks := 0
|
||||
@export var proc_cd := 0.0
|
||||
@export var duration := 1.0
|
||||
@export var potency := 1.0
|
||||
@export var icon : Texture
|
||||
@export var name: String
|
||||
@export var max_stacks: int = 0
|
||||
@export var proc_cd: float = 0.0
|
||||
@export var duration: float = 1.0
|
||||
@export var potency: float = 1.0
|
||||
@export var icon: Texture
|
||||
|
@ -1,17 +1,16 @@
|
||||
extends Node3D
|
||||
class_name StatusEffector
|
||||
class_name StatusEffector extends Node3D
|
||||
|
||||
@export var hbox : HBoxContainer
|
||||
@export var enemy : EnemyController
|
||||
@export var hbox: HBoxContainer
|
||||
@export var enemy: EnemyController
|
||||
|
||||
var icon_scene = preload("res://Scenes/status_icon.tscn")
|
||||
var immune : Array[StatusEffect] = []
|
||||
var effects = {}
|
||||
var icons = {}
|
||||
var icon_scene: PackedScene = preload("res://Scenes/status_icon.tscn")
|
||||
var immune: Array[StatusEffect] = []
|
||||
var effects: Dictionary = {}
|
||||
var icons: Dictionary = {}
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
for effect in effects:
|
||||
for effect: StatusEffect in effects:
|
||||
if effects[effect] == 0:
|
||||
continue
|
||||
effect.time_since_proc += delta
|
||||
@ -27,25 +26,25 @@ func _process(delta: float) -> void:
|
||||
effect.time_since_proc -= effect.stats.proc_cd
|
||||
|
||||
|
||||
func force_proc(effect_to_proc : StatusEffect):
|
||||
for effect in effects:
|
||||
func force_proc(effect_to_proc: StatusEffect) -> void:
|
||||
for effect: StatusEffect in effects:
|
||||
if effect.stats == effect_to_proc.stats:
|
||||
effect.proc(enemy, effects[effect], effects)
|
||||
|
||||
|
||||
func add_effect(new_effect : StatusEffect):
|
||||
for effect in immune:
|
||||
func add_effect(new_effect: StatusEffect) -> void:
|
||||
for effect: StatusEffect in immune:
|
||||
if effect.stats == new_effect.stats:
|
||||
return
|
||||
|
||||
var existing_effect
|
||||
for effect in effects:
|
||||
var existing_effect: StatusEffect
|
||||
for effect: StatusEffect in effects:
|
||||
if effect.stats == new_effect.stats:
|
||||
existing_effect = effect
|
||||
if !existing_effect:
|
||||
existing_effect = new_effect
|
||||
effects[new_effect] = 0
|
||||
var icon = icon_scene.instantiate()
|
||||
var icon: TextureRect = icon_scene.instantiate()
|
||||
icon.texture = new_effect.stats.icon
|
||||
icon.set_visible(false)
|
||||
icons[new_effect] = icon
|
||||
|
@ -1,6 +1,5 @@
|
||||
extends StatusEffect
|
||||
class_name StatusDoT
|
||||
class_name StatusDoT extends StatusEffect
|
||||
|
||||
|
||||
func proc(affected, stacks, _existing_effects):
|
||||
func proc(affected: EnemyController, stacks: int, _existing_effects: Dictionary) -> void:
|
||||
affected.damage(stats.potency * stacks)
|
||||
|
@ -1,19 +1,18 @@
|
||||
extends RefCounted
|
||||
class_name StatusEffect
|
||||
class_name StatusEffect extends RefCounted
|
||||
|
||||
var stats : StatusStats
|
||||
var stats: StatusStats
|
||||
|
||||
var time_since_proc := 0.0
|
||||
var time_existed := 0.0
|
||||
var time_since_proc: float = 0.0
|
||||
var time_existed: float = 0.0
|
||||
|
||||
|
||||
func on_attached(_affected, _existing_effects):
|
||||
func on_attached(_affected: EnemyController, _existing_effects: Dictionary) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func on_removed(_affected, _existing_effects):
|
||||
func on_removed(_affected: EnemyController, _existing_effects: Dictionary) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func proc(_affected, _stacks, _existing_effects):
|
||||
func proc(_affected: EnemyController, _stacks: int, _existing_effects: Dictionary) -> void:
|
||||
pass
|
||||
|
@ -1,10 +1,9 @@
|
||||
extends StatusEffect
|
||||
class_name StatusSlow
|
||||
class_name StatusSlow extends StatusEffect
|
||||
|
||||
|
||||
func on_attached(affected, _existing_effects):
|
||||
func on_attached(affected: EnemyController, _existing_effects: Dictionary) -> void:
|
||||
affected.movement_speed_penalty -= stats.potency
|
||||
|
||||
|
||||
func on_removed(affected, _existing_effects):
|
||||
func on_removed(affected: EnemyController, _existing_effects: Dictionary) -> void:
|
||||
affected.movement_speed_penalty += stats.potency
|
||||
|
@ -1,8 +1,7 @@
|
||||
extends Tower
|
||||
class_name HitscanTower
|
||||
class_name HitscanTower extends Tower
|
||||
|
||||
|
||||
func shoot():
|
||||
func shoot() -> void:
|
||||
super.shoot()
|
||||
if targeted_enemy and is_instance_valid(targeted_enemy) and targeted_enemy.alive:
|
||||
targeted_enemy.damage(damage)
|
||||
@ -11,5 +10,5 @@ func shoot():
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_shoot():
|
||||
func networked_shoot() -> void:
|
||||
super.networked_shoot()
|
||||
|
@ -1,26 +1,25 @@
|
||||
extends Tower
|
||||
class_name ProjectileTower
|
||||
class_name ProjectileTower extends Tower
|
||||
|
||||
@export var projectile_scene : PackedScene
|
||||
@export var projectile_scene: PackedScene
|
||||
|
||||
var force := 150.0
|
||||
var projectile_id := 0
|
||||
var force: float = 150.0
|
||||
var projectile_id: int = 0
|
||||
|
||||
|
||||
func shoot():
|
||||
func shoot() -> void:
|
||||
if is_multiplayer_authority():
|
||||
networked_spawn_projectile.rpc(multiplayer.get_unique_id())
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_shoot():
|
||||
func networked_shoot() -> void:
|
||||
super.networked_shoot()
|
||||
shoot()
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_projectile(peer_id):
|
||||
var projectile = projectile_scene.instantiate() as Projectile
|
||||
func networked_spawn_projectile(peer_id: int) -> Projectile:
|
||||
var projectile: Projectile = projectile_scene.instantiate() as Projectile
|
||||
projectile.position = yaw_model.global_position
|
||||
projectile.damage = damage
|
||||
projectile.direction = -yaw_model.global_transform.basis.z
|
||||
|
@ -1,27 +1,26 @@
|
||||
extends StatusApplyingTower
|
||||
class_name RangeAffectingTower
|
||||
class_name RangeAffectingTower extends StatusApplyingTower
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
if !is_multiplayer_authority():
|
||||
return
|
||||
var enemies_in_range = []
|
||||
for enemy in get_tree().get_nodes_in_group("Enemies"):
|
||||
var enemies_in_range: Array = []
|
||||
for enemy: EnemyController in get_tree().get_nodes_in_group("Enemies"):
|
||||
if !is_instance_valid(enemy) or !enemy.alive or global_position.distance_to(enemy.global_position) > target_range:
|
||||
continue
|
||||
if enemy.stats.target_type & stats.target_type:
|
||||
enemies_in_range.append(enemy)
|
||||
if time_since_firing >= time_between_shots:
|
||||
time_since_firing -= time_between_shots
|
||||
for enemy in enemies_in_range:
|
||||
for enemy: EnemyController in enemies_in_range:
|
||||
fire(enemy)
|
||||
|
||||
|
||||
func aim():
|
||||
func aim() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func fire(target):
|
||||
func fire(target: EnemyController) -> void:
|
||||
if is_instance_valid(target) and target.alive:
|
||||
target.damage(damage)
|
||||
target.status_manager.add_effect(build_status_object())
|
||||
@ -32,6 +31,6 @@ func fire(target):
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_fire(target_node_path):
|
||||
var target = get_tree().root.get_node(target_node_path)
|
||||
func networked_fire(target_node_path: String) -> void:
|
||||
var target: EnemyController = get_tree().root.get_node(target_node_path)
|
||||
fire(target)
|
||||
|
@ -1,9 +1,8 @@
|
||||
extends Tower
|
||||
class_name ShapecastTower
|
||||
class_name ShapecastTower extends Tower
|
||||
|
||||
@export var shapecast : ShapeCast3D
|
||||
@export var particlesystem : GPUParticles3D
|
||||
@export var status_stats : StatusStats
|
||||
@export var shapecast: ShapeCast3D
|
||||
@export var particlesystem: GPUParticles3D
|
||||
@export var status_stats: StatusStats
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
@ -14,19 +13,19 @@ func _process(delta: float) -> void:
|
||||
particlesystem.emitting = false
|
||||
|
||||
|
||||
func shoot():
|
||||
for index in shapecast.get_collision_count():
|
||||
var target = shapecast.get_collider(index) as CharacterBody3D
|
||||
func shoot() -> void:
|
||||
for index: int in shapecast.get_collision_count():
|
||||
var target: CharacterBody3D = shapecast.get_collider(index) as CharacterBody3D
|
||||
hit(target)
|
||||
|
||||
|
||||
func aim():
|
||||
func aim() -> void:
|
||||
yaw_model.look_at(targeted_enemy.global_position)
|
||||
pitch_model.look_at(targeted_enemy.global_position)
|
||||
pitch_model.rotation.x = 0.0
|
||||
|
||||
|
||||
func hit(target):
|
||||
func hit(target: CharacterBody3D) -> void:
|
||||
if is_instance_valid(target) and target.alive:
|
||||
target.damage(damage)
|
||||
if Data.preferences.display_tower_damage_indicators:
|
||||
@ -37,12 +36,12 @@ func hit(target):
|
||||
|
||||
|
||||
func build_status_object() -> StatusEffect:
|
||||
var status = StatusEffect.new()
|
||||
var status: StatusEffect = StatusEffect.new()
|
||||
status.stats = status_stats
|
||||
return status
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_hit(target_node_path):
|
||||
var target = get_tree().root.get_node(target_node_path)
|
||||
func networked_hit(target_node_path: String) -> void:
|
||||
var target: CharacterBody3D = get_tree().root.get_node(target_node_path) as CharacterBody3D
|
||||
hit(target)
|
||||
|
@ -1,10 +1,9 @@
|
||||
extends HitscanTower
|
||||
class_name StatusApplyingTower
|
||||
class_name StatusApplyingTower extends HitscanTower
|
||||
|
||||
@export var status_stats : StatusStats
|
||||
@export var status_stats: StatusStats
|
||||
|
||||
|
||||
func shoot():
|
||||
func shoot() -> void:
|
||||
super.shoot()
|
||||
if targeted_enemy and is_instance_valid(targeted_enemy) and targeted_enemy.alive:
|
||||
targeted_enemy.damage(damage)
|
||||
@ -12,11 +11,11 @@ func shoot():
|
||||
|
||||
|
||||
func build_status_object() -> StatusEffect:
|
||||
var status = StatusEffect.new()
|
||||
var status: StatusEffect = StatusEffect.new()
|
||||
status.stats = status_stats
|
||||
return status
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_shoot():
|
||||
func networked_shoot() -> void:
|
||||
super.networked_shoot()
|
||||
|
@ -1,21 +1,20 @@
|
||||
extends Node3D
|
||||
class_name Tower
|
||||
class_name Tower extends Node3D
|
||||
|
||||
@export var stats : CardText
|
||||
@export var animator : AnimationPlayer
|
||||
@export var pitch_model : MeshInstance3D
|
||||
@export var yaw_model : MeshInstance3D
|
||||
@export var range_indicator : CSGSphere3D
|
||||
@export var audio_player : AudioStreamPlayer3D
|
||||
@export var stats: CardText
|
||||
@export var animator: AnimationPlayer
|
||||
@export var pitch_model: MeshInstance3D
|
||||
@export var yaw_model: MeshInstance3D
|
||||
@export var range_indicator: CSGSphere3D
|
||||
@export var audio_player: AudioStreamPlayer3D
|
||||
|
||||
var owner_id : int
|
||||
var damage_particle_scene = preload("res://Scenes/damage_particle.tscn")
|
||||
var base_name
|
||||
var targeted_enemy
|
||||
var time_since_firing := 0.0
|
||||
var time_between_shots := 0.0
|
||||
var damage := 0.0
|
||||
var target_range := 0.0
|
||||
var owner_id: int
|
||||
var damage_particle_scene: PackedScene = preload("res://Scenes/damage_particle.tscn")
|
||||
var base_name: String
|
||||
var targeted_enemy: EnemyController
|
||||
var time_since_firing: float = 0.0
|
||||
var time_between_shots: float = 0.0
|
||||
var damage: float = 0.0
|
||||
var target_range: float = 0.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -25,7 +24,7 @@ func _ready() -> void:
|
||||
range_indicator.radius = target_range
|
||||
|
||||
|
||||
func preview_range(value):
|
||||
func preview_range(value: bool) -> void:
|
||||
range_indicator.set_visible(value)
|
||||
|
||||
|
||||
@ -57,19 +56,19 @@ func _physics_process(_delta: float) -> void:
|
||||
shoot()
|
||||
|
||||
|
||||
func aim():
|
||||
func aim() -> void:
|
||||
yaw_model.look_at(targeted_enemy.global_position)
|
||||
pitch_model.look_at(targeted_enemy.global_position)
|
||||
pitch_model.rotation.x = 0.0
|
||||
|
||||
|
||||
func acquire_target():
|
||||
var most_progressed_enemy = null
|
||||
for enemy in get_tree().get_nodes_in_group("Enemies"):
|
||||
func acquire_target() -> void:
|
||||
var most_progressed_enemy: EnemyController = null
|
||||
for enemy: EnemyController in get_tree().get_nodes_in_group("Enemies"):
|
||||
if global_position.distance_to(enemy.global_position) > target_range:
|
||||
continue
|
||||
var em_1 = enemy.movement_controller as EnemyMovement
|
||||
var em_2 : EnemyMovement
|
||||
var em_1: EnemyMovement = 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.target_type:
|
||||
@ -79,26 +78,26 @@ func acquire_target():
|
||||
networked_acquire_target.rpc(get_tree().root.get_path_to(most_progressed_enemy))
|
||||
|
||||
|
||||
func shoot():
|
||||
func shoot() -> void:
|
||||
animator.play("shoot")
|
||||
audio_player.play()
|
||||
if is_multiplayer_authority():
|
||||
networked_shoot.rpc()
|
||||
|
||||
|
||||
func spawn_damage_indicator(pos):
|
||||
func spawn_damage_indicator(pos: Vector3) -> void:
|
||||
if damage > 0:
|
||||
var marker = damage_particle_scene.instantiate()
|
||||
var marker: Sprite3D = damage_particle_scene.instantiate()
|
||||
get_tree().root.add_child(marker)
|
||||
marker.set_number(damage)
|
||||
marker.position = pos
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_shoot():
|
||||
func networked_shoot() -> void:
|
||||
shoot()
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_acquire_target(target_node_path):
|
||||
func networked_acquire_target(target_node_path: String) -> void:
|
||||
targeted_enemy = get_tree().root.get_node(target_node_path)
|
||||
|
@ -1,10 +1,9 @@
|
||||
extends Weapon
|
||||
class_name HitscanWeapon
|
||||
class_name HitscanWeapon extends Weapon
|
||||
|
||||
@export var raycast : RayCast3D
|
||||
@export var range_debug_indicator : CSGSphere3D
|
||||
@export var raycast: RayCast3D
|
||||
@export var range_debug_indicator: CSGSphere3D
|
||||
|
||||
var attack_range := 0.0
|
||||
var attack_range: float = 0.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -15,12 +14,12 @@ func _ready() -> void:
|
||||
raycast.global_position = hero.camera.global_position
|
||||
|
||||
|
||||
func shoot():
|
||||
func shoot() -> void:
|
||||
super.shoot()
|
||||
if raycast.is_colliding():
|
||||
var target = raycast.get_collider()
|
||||
var target: CharacterBody3D = raycast.get_collider()
|
||||
if target != null:
|
||||
var target_hitbox = target.shape_owner_get_owner(raycast.get_collider_shape())
|
||||
var target_hitbox: Hitbox = target.shape_owner_get_owner(raycast.get_collider_shape())
|
||||
if target_hitbox is Hitbox:
|
||||
hit(target, target_hitbox)
|
||||
if Data.preferences.display_self_damage_indicators:
|
||||
@ -28,14 +27,14 @@ func shoot():
|
||||
networked_hit.rpc(get_tree().root.get_path_to(target), get_tree().root.get_path_to(target_hitbox))
|
||||
|
||||
|
||||
func hit(_target, target_hitbox : Hitbox):
|
||||
func hit(_target: CharacterBody3D, target_hitbox: Hitbox) -> void:
|
||||
target_hitbox.damage(damage)
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_hit(target_path : String, target_hitbox_path : String):
|
||||
var target = get_tree().root.get_node(target_path)
|
||||
var target_hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
|
||||
func networked_hit(target_path: String, target_hitbox_path: String) -> void:
|
||||
var target: CharacterBody3D = get_tree().root.get_node(target_path)
|
||||
var target_hitbox: Hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
|
||||
hit(target, target_hitbox)
|
||||
if Data.preferences.display_party_damage_indicators:
|
||||
spawn_damage_indicator(target.sprite.global_position)
|
||||
|
@ -1,25 +1,24 @@
|
||||
extends Weapon
|
||||
class_name ProjectileWeapon
|
||||
class_name ProjectileWeapon extends Weapon
|
||||
|
||||
@export var projectile_scene : PackedScene
|
||||
@export var projectile_scene: PackedScene
|
||||
|
||||
var force := 20.0
|
||||
var projectile_id := 0
|
||||
var force: float = 20.0
|
||||
var projectile_id: int = 0
|
||||
|
||||
|
||||
func shoot():
|
||||
func shoot() -> void:
|
||||
super.shoot()
|
||||
networked_spawn_projectile.rpc(multiplayer.get_unique_id(), -global_transform.basis.z)
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_shoot():
|
||||
func networked_shoot() -> void:
|
||||
super.networked_shoot()
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_projectile(peer_id, direction):
|
||||
var projectile = projectile_scene.instantiate() as Projectile
|
||||
func networked_spawn_projectile(peer_id: int, direction: Vector3) -> void:
|
||||
var projectile: Projectile = projectile_scene.instantiate() as Projectile
|
||||
projectile.position = global_position
|
||||
projectile.damage = damage
|
||||
projectile.direction = direction
|
||||
|
@ -1,12 +1,11 @@
|
||||
extends Weapon
|
||||
class_name ShapecastWeapon
|
||||
class_name ShapecastWeapon extends Weapon
|
||||
|
||||
@export var shapecast : ShapeCast3D
|
||||
@export var range_debug_indicator : CSGSphere3D
|
||||
@export var status_stats : StatusStats
|
||||
@export var particles : GPUParticles3D
|
||||
@export var shapecast: ShapeCast3D
|
||||
@export var range_debug_indicator: CSGSphere3D
|
||||
@export var status_stats: StatusStats
|
||||
@export var particles: GPUParticles3D
|
||||
|
||||
var attack_range := 0.0
|
||||
var attack_range: float = 0.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -22,12 +21,12 @@ func _process(delta: float) -> void:
|
||||
particles.emitting = trigger_held
|
||||
|
||||
|
||||
func shoot():
|
||||
func shoot() -> void:
|
||||
super.shoot()
|
||||
for index in shapecast.get_collision_count():
|
||||
var target = shapecast.get_collider(index)
|
||||
for index: int in shapecast.get_collision_count():
|
||||
var target: CharacterBody3D = shapecast.get_collider(index)
|
||||
if target:
|
||||
var target_hitbox = target.shape_owner_get_owner(shapecast.get_collider_shape(index))
|
||||
var target_hitbox: Hitbox = target.shape_owner_get_owner(shapecast.get_collider_shape(index))
|
||||
if target_hitbox is Hitbox:
|
||||
hit(target, target_hitbox)
|
||||
if Data.preferences.display_self_damage_indicators:
|
||||
@ -36,20 +35,20 @@ func shoot():
|
||||
|
||||
|
||||
func build_status_object() -> StatusEffect:
|
||||
var status = StatusEffect.new()
|
||||
var status: StatusEffect = StatusEffect.new()
|
||||
status.stats = status_stats
|
||||
return status
|
||||
|
||||
|
||||
func hit(target, target_hitbox : Hitbox):
|
||||
func hit(target: CharacterBody3D, target_hitbox: Hitbox) -> void:
|
||||
target_hitbox.damage(damage)
|
||||
target.status_manager.add_effect(build_status_object())
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_hit(target_path : String, target_hitbox_path : String):
|
||||
var target = get_tree().root.get_node(target_path)
|
||||
var target_hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
|
||||
func networked_hit(target_path: String, target_hitbox_path: String) -> void:
|
||||
var target: CharacterBody3D = get_tree().root.get_node(target_path) as CharacterBody3D
|
||||
var target_hitbox: Hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
|
||||
hit(target, target_hitbox)
|
||||
if Data.preferences.display_party_damage_indicators:
|
||||
spawn_damage_indicator(target.sprite.global_position)
|
||||
|
@ -1,15 +1,14 @@
|
||||
extends HitscanWeapon
|
||||
class_name StatusApplyingWeapon
|
||||
class_name StatusApplyingWeapon extends HitscanWeapon
|
||||
|
||||
@export var status_stats : StatusStats
|
||||
@export var status_stats: StatusStats
|
||||
|
||||
|
||||
func hit(target, target_hitbox : Hitbox):
|
||||
func hit(target: CharacterBody3D, target_hitbox: Hitbox) -> void:
|
||||
super.hit(target, target_hitbox)
|
||||
target.status_manager.add_effect(build_status_object())
|
||||
|
||||
|
||||
func build_status_object() -> StatusEffect:
|
||||
var status = StatusEffect.new()
|
||||
var status: StatusEffect = StatusEffect.new()
|
||||
status.stats = status_stats
|
||||
return status
|
||||
|
@ -1,27 +1,26 @@
|
||||
extends Node3D
|
||||
class_name Weapon
|
||||
class_name Weapon extends Node3D
|
||||
|
||||
signal energy_changed(energy)
|
||||
signal energy_changed(energy: int)
|
||||
|
||||
@export var stats : CardText
|
||||
@export var animator : AnimationPlayer
|
||||
@export var audio_player : AudioStreamPlayer3D
|
||||
@export var recharge_timer : Timer
|
||||
@export var stats: CardText
|
||||
@export var animator: AnimationPlayer
|
||||
@export var audio_player: AudioStreamPlayer3D
|
||||
@export var recharge_timer: Timer
|
||||
|
||||
var damage_particle_scene = preload("res://Scenes/damage_particle.tscn")
|
||||
var hero : Hero
|
||||
var trigger_held := false
|
||||
var second_trigger_held := false
|
||||
var time_since_firing := 0.0
|
||||
var time_between_shots := 0.0
|
||||
var damage := 0.0
|
||||
var max_energy := 100.0
|
||||
var current_energy := 100.0
|
||||
var energy_cost := 1.0
|
||||
var recharging := false
|
||||
var recharge_speed := 0.0
|
||||
var recharge_acceleration = 2.0
|
||||
var recharge_max_speed = 25.0
|
||||
var damage_particle_scene: PackedScene = preload("res://Scenes/damage_particle.tscn")
|
||||
var hero: Hero
|
||||
var trigger_held: bool = false
|
||||
var second_trigger_held: bool = false
|
||||
var time_since_firing: float = 0.0
|
||||
var time_between_shots: float = 0.0
|
||||
var damage: float = 0.0
|
||||
var max_energy: float = 100.0
|
||||
var current_energy: float = 100.0
|
||||
var energy_cost: float = 1.0
|
||||
var recharging: bool = false
|
||||
var recharge_speed: float = 0.0
|
||||
var recharge_acceleration: float = 2.0
|
||||
var recharge_max_speed: float = 25.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -30,7 +29,7 @@ func _ready() -> void:
|
||||
energy_cost = stats.get_attribute("Energy")
|
||||
|
||||
|
||||
func set_hero(value):
|
||||
func set_hero(value: Hero) -> void:
|
||||
hero = value
|
||||
|
||||
|
||||
@ -56,33 +55,33 @@ func _physics_process(_delta: float) -> void:
|
||||
networked_shoot.rpc()
|
||||
|
||||
|
||||
func hold_trigger():
|
||||
func hold_trigger() -> void:
|
||||
trigger_held = true
|
||||
|
||||
|
||||
func release_trigger():
|
||||
func release_trigger() -> void:
|
||||
if trigger_held:
|
||||
recharge_timer.start()
|
||||
trigger_held = false
|
||||
|
||||
|
||||
func hold_second_trigger():
|
||||
func hold_second_trigger() -> void:
|
||||
second_trigger_held = true
|
||||
|
||||
|
||||
func release_second_trigger():
|
||||
func release_second_trigger() -> void:
|
||||
second_trigger_held = false
|
||||
|
||||
|
||||
func spawn_damage_indicator(pos):
|
||||
func spawn_damage_indicator(pos: Vector3) -> void:
|
||||
if damage > 0:
|
||||
var marker = damage_particle_scene.instantiate()
|
||||
var marker: Node3D = damage_particle_scene.instantiate()
|
||||
get_tree().root.add_child(marker)
|
||||
marker.set_number(damage)
|
||||
marker.position = pos
|
||||
|
||||
|
||||
func shoot():
|
||||
func shoot() -> void:
|
||||
animator.play("shoot")
|
||||
audio_player.play()
|
||||
recharging = false
|
||||
@ -91,7 +90,7 @@ func shoot():
|
||||
|
||||
|
||||
@rpc
|
||||
func networked_shoot():
|
||||
func networked_shoot() -> void:
|
||||
animator.play("shoot")
|
||||
audio_player.play()
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
extends PanelContainer
|
||||
class_name AlertPopup
|
||||
class_name AlertPopup extends PanelContainer
|
||||
|
||||
signal completed
|
||||
signal completed()
|
||||
|
||||
func set_popup(prompt_text, dismiss_text):
|
||||
func set_popup(prompt_text: String, dismiss_text: String) -> void:
|
||||
$VBoxContainer/Label.text = prompt_text
|
||||
$VBoxContainer/MarginContainerButton.text = dismiss_text
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
extends VBoxContainer
|
||||
class_name AudioOptions extends VBoxContainer
|
||||
|
||||
@export var master_input: SpinBox
|
||||
@export var master_slider: HSlider
|
||||
|
@ -1,34 +1,33 @@
|
||||
extends Node2D
|
||||
class_name CardInHand
|
||||
class_name CardInHand extends Node2D
|
||||
|
||||
var stats : Card
|
||||
@export var rarity_sprite : Sprite2D
|
||||
@export var title_text : Label
|
||||
@export var description : RichTextLabel
|
||||
@export var target_label : Label
|
||||
var stats: Card
|
||||
@export var rarity_sprite: Sprite2D
|
||||
@export var title_text: Label
|
||||
@export var description: RichTextLabel
|
||||
@export var target_label: Label
|
||||
|
||||
|
||||
func set_card(value):
|
||||
func set_card(value: Card) -> void:
|
||||
stats = value
|
||||
title_text.text = stats.display_name
|
||||
target_label.text = str(Data.TargetType.keys()[stats.tower_stats.target_type])
|
||||
rarity_sprite.region_rect = Rect2(64 * stats.rarity, 0, 64, 64)
|
||||
|
||||
|
||||
func process_card_text(card_text : CardText) -> String:
|
||||
var processed_string = card_text.text
|
||||
for stat in card_text.attributes:
|
||||
func process_card_text(card_text: CardText) -> String:
|
||||
var processed_string: String = card_text.text
|
||||
for stat: StatAttribute in card_text.attributes:
|
||||
processed_string = processed_string.replace(stat.key, str(stat.value))
|
||||
processed_string = processed_string.replace("/", "[color=red]")
|
||||
processed_string = processed_string.replace("\\", "[color=black]")
|
||||
return processed_string
|
||||
|
||||
|
||||
func view_weapon():
|
||||
func view_weapon() -> void:
|
||||
description.text = process_card_text(stats.weapon_stats)
|
||||
target_label.text = "Both"
|
||||
|
||||
|
||||
func view_tower():
|
||||
func view_tower() -> void:
|
||||
description.text = process_card_text(stats.tower_stats)
|
||||
target_label.text = str(Data.TargetType.keys()[stats.tower_stats.target_type])
|
||||
|
@ -1,34 +1,34 @@
|
||||
extends StaticBody3D
|
||||
class_name CardPrinter
|
||||
class_name CardPrinter extends StaticBody3D
|
||||
|
||||
@export var cards : Array[CardInHand]
|
||||
@export var item_card_scene : PackedScene
|
||||
var card_available = false
|
||||
@export var button_collider : CollisionShape3D
|
||||
@export var button_box : Node3D
|
||||
@export var choice_colliders : Array[CollisionShape3D]
|
||||
@export var cards: Array[CardInHand]
|
||||
@export var item_card_scene: PackedScene
|
||||
@export var button_collider: CollisionShape3D
|
||||
@export var button_box: Node3D
|
||||
@export var choice_colliders: Array[CollisionShape3D]
|
||||
|
||||
var card_available: bool = false
|
||||
|
||||
|
||||
func randomize_cards():
|
||||
var weight_total = 0
|
||||
for rarity in Data.Rarity:
|
||||
func randomize_cards() -> void:
|
||||
var weight_total: int = 0
|
||||
for rarity: String in Data.Rarity:
|
||||
weight_total += Data.rarity_weights[rarity]
|
||||
|
||||
var generated_rarity = randi_range(0, weight_total)
|
||||
var decided_rarity := 0
|
||||
var generated_rarity: int = randi_range(0, weight_total)
|
||||
var decided_rarity: int = 0
|
||||
|
||||
for rarity in Data.Rarity:
|
||||
for rarity: String in Data.Rarity:
|
||||
weight_total -= Data.rarity_weights[rarity]
|
||||
if generated_rarity >= weight_total:
|
||||
decided_rarity = Data.Rarity[rarity]
|
||||
break
|
||||
|
||||
var card_array = []
|
||||
for x in Data.cards:
|
||||
var card_array: Array = []
|
||||
for x: Card in Data.cards:
|
||||
if x.rarity == decided_rarity:
|
||||
card_array.append(x)
|
||||
var card
|
||||
for x in cards:
|
||||
var card: Card
|
||||
for x: CardInHand in cards:
|
||||
if card_array.size() > 0:
|
||||
card = card_array.pick_random()
|
||||
card_array.erase(card)
|
||||
@ -36,18 +36,18 @@ func randomize_cards():
|
||||
#TODO: in reality this should just show the icon and then hovering over it lets you see either side at the players own discretion
|
||||
x.view_tower()
|
||||
$Node3D.set_visible(true)
|
||||
for x in choice_colliders:
|
||||
for x: CollisionShape3D in choice_colliders:
|
||||
x.disabled = false
|
||||
card_available = true
|
||||
|
||||
|
||||
func retrieve_card(i):
|
||||
func retrieve_card(i: int) -> void:
|
||||
$Node3D.set_visible(false)
|
||||
for x in choice_colliders:
|
||||
for x: CollisionShape3D in choice_colliders:
|
||||
x.disabled = true
|
||||
if card_available:
|
||||
var card = cards[i].stats
|
||||
var item = item_card_scene.instantiate() as ItemCard
|
||||
var card: Card = cards[i].stats
|
||||
var item: ItemCard = item_card_scene.instantiate() as ItemCard
|
||||
item.card = card
|
||||
item.position = Vector3(1.683, 0, 0)
|
||||
add_child(item)
|
||||
@ -56,7 +56,7 @@ func retrieve_card(i):
|
||||
$AudioStreamPlayer3D.play()
|
||||
|
||||
|
||||
func _on_static_body_3d_button_interacted(_value) -> void:
|
||||
func _on_static_body_3d_button_interacted(_value: int) -> void:
|
||||
button_collider.disabled = true
|
||||
button_box.position = Vector3(0,0,-0.2)
|
||||
$AudioStreamPlayer3D.play()
|
||||
|
@ -1,20 +1,19 @@
|
||||
extends Control
|
||||
class_name Chatbox
|
||||
class_name Chatbox extends Control
|
||||
|
||||
signal opened
|
||||
signal closed
|
||||
|
||||
@export var input_line : LineEdit
|
||||
@export var textbox : RichTextLabel
|
||||
@export var text_panel : PanelContainer
|
||||
@export var fade_timer : Timer
|
||||
@export var input_line: LineEdit
|
||||
@export var textbox: RichTextLabel
|
||||
@export var text_panel: PanelContainer
|
||||
@export var fade_timer: Timer
|
||||
|
||||
var text_selected := false
|
||||
var username := "default"
|
||||
var color = Color.TOMATO
|
||||
var fading = true
|
||||
var time_to_fade = 2.0
|
||||
var time_since_started_fading = 2.0
|
||||
var text_selected: bool = false
|
||||
var username: String = "default"
|
||||
var color: Color = Color.TOMATO
|
||||
var fading: bool = true
|
||||
var time_to_fade: float = 2.0
|
||||
var time_since_started_fading:float = 2.0
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
@ -58,12 +57,12 @@ func _input(event: InputEvent) -> void:
|
||||
fade_timer.start()
|
||||
|
||||
|
||||
func change_username(old_name, new_name):
|
||||
func change_username(old_name: String, new_name: String) -> void:
|
||||
append_message("SERVER", Color.TOMATO, old_name + " has changed their display name to " + new_name)
|
||||
|
||||
|
||||
@rpc("reliable","call_local","any_peer")
|
||||
func append_message(user, user_color, content):
|
||||
func append_message(user: String, user_color: Color, content: String) -> void:
|
||||
textbox.append_text("[[color=" + user_color.to_html() + "]" + user + "[color=white]] " + content + "\n")
|
||||
fading = false
|
||||
fade_timer.start()
|
||||
|
@ -1,9 +1,8 @@
|
||||
extends PanelContainer
|
||||
class_name ConfirmationPopup
|
||||
class_name ConfirmationPopup extends PanelContainer
|
||||
|
||||
signal completed(outcome)
|
||||
signal completed(outcome: bool)
|
||||
|
||||
func set_popup(prompt_text, confirm_text, cancel_text):
|
||||
func set_popup(prompt_text: String, confirm_text: String, cancel_text: String) -> void:
|
||||
$VBoxContainer/Label.text = prompt_text
|
||||
$VBoxContainer/HBoxContainer/Confirm.text = confirm_text
|
||||
$VBoxContainer/HBoxContainer/Cancel.text = cancel_text
|
||||
|
@ -1,18 +1,18 @@
|
||||
extends Sprite3D
|
||||
class_name DamageParticle extends Sprite3D
|
||||
|
||||
@onready var label: Label = $SubViewport/Label
|
||||
var time_alive := 0.0
|
||||
var movement_speed := 1.0
|
||||
var movement_vector : Vector3
|
||||
var time_alive: float = 0.0
|
||||
var movement_speed: float = 1.0
|
||||
var movement_vector: Vector3
|
||||
|
||||
func _ready():
|
||||
var theta = deg_to_rad(40)
|
||||
var z = randf_range(cos(theta), 1)
|
||||
var phi = randf_range(0, 2 * PI)
|
||||
var vector = Vector3(sqrt(1 - pow(z, 2)) * cos(phi), z, sqrt(1 - pow(z, 2)) * sin(phi))
|
||||
func _ready() -> void:
|
||||
var theta: float = deg_to_rad(40)
|
||||
var z: float = randf_range(cos(theta), 1)
|
||||
var phi: float = randf_range(0, 2 * PI)
|
||||
var vector: Vector3 = Vector3(sqrt(1 - pow(z, 2)) * cos(phi), z, sqrt(1 - pow(z, 2)) * sin(phi))
|
||||
movement_vector = vector.normalized()
|
||||
|
||||
func set_number(num):
|
||||
func set_number(num: int) -> void:
|
||||
label.text = str(num)
|
||||
|
||||
|
||||
|
@ -9,14 +9,15 @@ var audio: PlayerAudioSettings
|
||||
var preferences: PlayerPreferences
|
||||
var player_profile: PlayerProfile
|
||||
var player_keymap: PlayerKeymap
|
||||
var player_controller_keymap: PlayerKeymap = preload("res://Resources/Keymaps/controller.tres")
|
||||
var save_stats: SaveStats
|
||||
|
||||
var wall_cost := 1
|
||||
var printer_cost := 15
|
||||
var wall_cost: int = 1
|
||||
var printer_cost: int = 15
|
||||
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}
|
||||
var rarity_weights = {
|
||||
var rarity_weights: Dictionary = {
|
||||
"COMMON" = 50,
|
||||
"UNCOMMON" = 30,
|
||||
"RARE" = 10,
|
||||
@ -33,32 +34,33 @@ func _ready() -> void:
|
||||
preferences = PlayerPreferences.load_profile_from_disk()
|
||||
player_keymap = PlayerKeymap.load_profile_from_disk()
|
||||
player_keymap.apply()
|
||||
player_controller_keymap.append_input_map()
|
||||
save_stats = SaveStats.load_profile_from_disk()
|
||||
|
||||
characters.append(preload("res://PCs/Red/red.tres"))
|
||||
characters.append(preload("res://PCs/Mechanic/red.tres"))
|
||||
#characters.append(preload("res://PCs/Green/green.tres"))
|
||||
characters.append(preload("res://PCs/Blue/blue.tres"))
|
||||
characters.append(preload("res://PCs/Mage/blue.tres"))
|
||||
|
||||
#Common
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Assault/card_assault.tres"))
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/BombLauncher/card_bomb_launcher.tres"))
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Gatling/card_gatling.tres"))
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/RocketLauncher/card_rocket_launcher.tres"))
|
||||
cards.append(preload("res://PCs/Mechanic/ClassCards/Assault/card_assault.tres"))
|
||||
cards.append(preload("res://PCs/Mechanic/ClassCards/BombLauncher/card_bomb_launcher.tres"))
|
||||
cards.append(preload("res://PCs/Mechanic/ClassCards/Gatling/card_gatling.tres"))
|
||||
cards.append(preload("res://PCs/Mechanic/ClassCards/RocketLauncher/card_rocket_launcher.tres"))
|
||||
#Uncommon
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Sniper/card_sniper.tres"))
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Blowdart/card_blowdart.tres"))
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Refrigerator/card_refrigerator.tres"))
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/GlueLauncher/card_glue_launcher.tres"))
|
||||
cards.append(preload("res://PCs/Mechanic/ClassCards/Sniper/card_sniper.tres"))
|
||||
cards.append(preload("res://PCs/Entomologist/ClassCards/Blowdart/card_blowdart.tres"))
|
||||
cards.append(preload("res://PCs/Mage/ClassCards/Refrigerator/card_refrigerator.tres"))
|
||||
cards.append(preload("res://PCs/Mechanic/ClassCards/GlueLauncher/card_glue_launcher.tres"))
|
||||
#Rare
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Flamethrower/card_flamethrower.tres"))
|
||||
cards.append(preload("res://PCs/Mechanic/ClassCards/Flamethrower/card_flamethrower.tres"))
|
||||
#cards.append(preload("res://PCs/Universal/ClassCards/DamageEnhancer/card_damage_enhancer.tres"))
|
||||
#cards.append(preload("res://PCs/Universal/ClassCards/SpeedEnhancer/card_speed_enhancer.tres"))
|
||||
#Epic
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Icicle/card_icicle.tres"))
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Fireball/card_fireball.tres"))
|
||||
cards.append(preload("res://PCs/Mage/ClassCards/Icicle/card_icicle.tres"))
|
||||
cards.append(preload("res://PCs/Mage/ClassCards/Fireball/card_fireball.tres"))
|
||||
#cards.append(preload("res://PCs/Universal/ClassCards/GammaLaser/card_gamma_laser.tres"))
|
||||
#Legendary
|
||||
cards.append(preload("res://PCs/Universal/ClassCards/Reactor/card_reactor.tres"))
|
||||
cards.append(preload("res://PCs/Mechanic/ClassCards/Reactor/card_reactor.tres"))
|
||||
#cards.append(preload("res://PCs/Universal/ClassCards/Lightning/card_lightning.tres"))
|
||||
|
||||
enemies.append(preload("res://Worlds/GreenPlanet/Enemies/dog.tres"))
|
||||
|
@ -1,32 +1,31 @@
|
||||
extends Node3D
|
||||
class_name EditTool
|
||||
class_name EditTool extends Node3D
|
||||
|
||||
@export var hero : Hero
|
||||
@export var inventory : Inventory
|
||||
@export var ray : RayCast3D
|
||||
@export var wall_preview : TowerBase
|
||||
@export var progress_bar : TextureProgressBar
|
||||
@export var hero: Hero
|
||||
@export var inventory: Inventory
|
||||
@export var ray: RayCast3D
|
||||
@export var wall_preview: TowerBase
|
||||
@export var progress_bar: TextureProgressBar
|
||||
|
||||
var enabled := true
|
||||
var point_id := -1
|
||||
var obstacle_last_point := -1
|
||||
var valid_point := false
|
||||
var is_looking_at_tower_base := false
|
||||
var tower_preview
|
||||
var last_tower_base
|
||||
var last_collider
|
||||
var last_card
|
||||
var ray_collider
|
||||
var ray_point
|
||||
var enabled: bool = true
|
||||
var point_id: int = -1
|
||||
var obstacle_last_point: int = -1
|
||||
var valid_point: bool = false
|
||||
var is_looking_at_tower_base: bool = false
|
||||
var tower_preview: Tower
|
||||
var last_tower_base: TowerBase
|
||||
var last_collider: Object
|
||||
var last_card: Card
|
||||
var ray_collider: Object
|
||||
var ray_point: Vector3
|
||||
|
||||
var interact_key_held := false
|
||||
var interacted_once := false
|
||||
var interact_held_time := 0.0
|
||||
var interact_hold_time := 0.4
|
||||
var interact_key_held: bool = false
|
||||
var interacted_once: bool = false
|
||||
var interact_held_time: float = 0.0
|
||||
var interact_hold_time: float = 0.4
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var c = Color.GREEN
|
||||
var c: Color = Color.GREEN
|
||||
c.a = 0.8
|
||||
wall_preview.set_color(c)
|
||||
wall_preview.set_float(0.0)
|
||||
@ -36,7 +35,6 @@ func _ready() -> void:
|
||||
func _process(delta: float) -> void:
|
||||
if !enabled:
|
||||
ray_collider = null
|
||||
ray_point = null
|
||||
wall_preview.set_visible(false)
|
||||
if is_instance_valid(last_collider):
|
||||
Game.level.a_star_graph_3d.tower_base_ids[last_collider.point_id].set_float(1.0)
|
||||
@ -99,13 +97,13 @@ func _process(delta: float) -> void:
|
||||
if !Game.level.a_star_graph_3d.point_is_build_location(point_id) or hero.currency < Data.wall_cost:
|
||||
wall_preview.set_visible(false)
|
||||
else:
|
||||
var point_position = Game.level.a_star_graph_3d.astar.get_point_position(point_id)
|
||||
var point_position: Vector3 = Game.level.a_star_graph_3d.astar.get_point_position(point_id)
|
||||
wall_preview.global_position = point_position
|
||||
wall_preview.global_rotation = Vector3.ZERO
|
||||
if obstacle_last_point != point_id:
|
||||
obstacle_last_point = point_id
|
||||
if Game.level.a_star_graph_3d.test_path_if_point_toggled(point_id):
|
||||
var c = Color.GREEN
|
||||
var c: Color = Color.GREEN
|
||||
c.a = 0.8
|
||||
wall_preview.set_color(c)
|
||||
wall_preview.set_float(0.0)
|
||||
@ -116,7 +114,6 @@ func _process(delta: float) -> void:
|
||||
valid_point = false
|
||||
else:
|
||||
ray_collider = null
|
||||
ray_point = null
|
||||
is_looking_at_tower_base = false
|
||||
delete_tower_preview()
|
||||
wall_preview.set_visible(false)
|
||||
@ -124,10 +121,10 @@ func _process(delta: float) -> void:
|
||||
wall_preview.set_visible(false)
|
||||
|
||||
|
||||
func spawn_tower_preview():
|
||||
func spawn_tower_preview() -> void:
|
||||
delete_tower_preview()
|
||||
last_tower_base = ray_collider
|
||||
var card = inventory.contents.keys()[hero.inventory_selected_index]
|
||||
var card: Card = inventory.contents.keys()[hero.inventory_selected_index]
|
||||
last_card = card
|
||||
tower_preview = card.turret_scene.instantiate() as Tower
|
||||
tower_preview.stats = card.tower_stats
|
||||
@ -136,7 +133,7 @@ func spawn_tower_preview():
|
||||
ray_collider.add_child(tower_preview)
|
||||
|
||||
|
||||
func delete_tower_preview():
|
||||
func delete_tower_preview() -> void:
|
||||
last_tower_base = null
|
||||
last_card = null
|
||||
if is_instance_valid(tower_preview):
|
||||
@ -144,35 +141,35 @@ func delete_tower_preview():
|
||||
tower_preview = null
|
||||
|
||||
|
||||
func interact():
|
||||
func interact() -> void:
|
||||
if ray_collider is TowerBase:
|
||||
var tower_base = ray_collider as TowerBase
|
||||
var tower_base: TowerBase = ray_collider as TowerBase
|
||||
put_card_in_tower_base(tower_base)
|
||||
|
||||
|
||||
func build_wall():
|
||||
func build_wall() -> void:
|
||||
if point_id >= 0 and valid_point and hero.currency >= Data.wall_cost:
|
||||
hero.currency -= Data.wall_cost
|
||||
Game.level.a_star_graph_3d.toggle_point(point_id, multiplayer.get_unique_id())
|
||||
wall_preview.set_visible(false)
|
||||
|
||||
|
||||
func refund_wall(wall: TowerBase):
|
||||
func refund_wall(wall: TowerBase) -> void:
|
||||
last_collider = null
|
||||
if wall.has_card:
|
||||
wall.remove_card()
|
||||
Game.level.a_star_graph_3d.remove_wall(wall)
|
||||
|
||||
|
||||
func put_card_in_tower_base(tower_base: TowerBase):
|
||||
func put_card_in_tower_base(tower_base: TowerBase) -> void:
|
||||
if tower_base.has_card:
|
||||
tower_base.remove_card()
|
||||
else:
|
||||
var card = inventory.remove_at(hero.inventory_selected_index)
|
||||
var card: Card = inventory.remove_at(hero.inventory_selected_index)
|
||||
if !inventory.contents.has(card):
|
||||
hero.decrement_selected()
|
||||
tower_base.add_card(card, multiplayer.get_unique_id())
|
||||
|
||||
|
||||
func set_progress_percent(value: float):
|
||||
func set_progress_percent(value: float) -> void:
|
||||
progress_bar.value = progress_bar.max_value * value
|
||||
|
@ -1,22 +1,21 @@
|
||||
extends Sprite3D
|
||||
class_name EightDirectionSprite3D
|
||||
class_name EightDirectionSprite3D extends Sprite3D
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var cam = get_viewport().get_camera_3d()
|
||||
var cam: Camera3D = get_viewport().get_camera_3d()
|
||||
if !cam:
|
||||
return
|
||||
var tile_size = texture.region.size.x
|
||||
var tile_size: int = texture.region.size.x
|
||||
|
||||
#stupid algorithm for dummy game developers
|
||||
var camera_look_dir_3D = cam.global_position.direction_to(global_position).normalized()
|
||||
var a = Vector2(global_transform.basis.z.x, global_transform.basis.z.z).normalized()
|
||||
var b = Vector2(camera_look_dir_3D.x, camera_look_dir_3D.z).normalized()
|
||||
var dot = a.x * b.x + a.y * b.y
|
||||
var det = a.x * b.y - a.y * b.x
|
||||
var final = rad_to_deg(atan2(det, dot)) + 180
|
||||
var camera_look_dir_3D: Vector3 = cam.global_position.direction_to(global_position).normalized()
|
||||
var a: Vector2 = Vector2(global_transform.basis.z.x, global_transform.basis.z.z).normalized()
|
||||
var b: Vector2 = Vector2(camera_look_dir_3D.x, camera_look_dir_3D.z).normalized()
|
||||
var dot: float = a.x * b.x + a.y * b.y
|
||||
var det: float = a.x * b.y - a.y * b.x
|
||||
var final: float = rad_to_deg(atan2(det, dot)) + 180
|
||||
|
||||
var t = texture.region
|
||||
var t: Rect2 = texture.region
|
||||
if final > 337.5 or final < 22.5:
|
||||
t = Rect2(tile_size * 4, t.position.y, tile_size, tile_size)
|
||||
elif final > 22.5 and final < 67.5:
|
||||
|
@ -1,6 +1,6 @@
|
||||
extends Node3D
|
||||
class_name EnemyGoal extends Node3D
|
||||
|
||||
@export var audio_player : AudioStreamPlayer3D
|
||||
@export var audio_player: AudioStreamPlayer3D
|
||||
|
||||
|
||||
func _on_area_3d_body_entered(body: Node3D) -> void:
|
||||
|
@ -1,25 +1,23 @@
|
||||
extends Node3D
|
||||
class_name EnemySpawner
|
||||
class_name EnemySpawner extends Node3D
|
||||
|
||||
@export var own_id : int = 0
|
||||
@export var path : VisualizedPath
|
||||
@export var type : Data.EnemyType
|
||||
@export var dest : Node3D
|
||||
@export var enemy_path : Node
|
||||
signal enemy_spawned()
|
||||
|
||||
var signal_for_after_enemy_died
|
||||
var signal_for_after_enemy_reached_goal
|
||||
signal signal_for_when_enemy_spawns
|
||||
@export var land_enemy_scene: PackedScene
|
||||
@export var air_enemy_scene: PackedScene
|
||||
@export var own_id: int = 0
|
||||
@export var path: VisualizedPath
|
||||
@export var type: Data.EnemyType
|
||||
@export var dest: Node3D
|
||||
@export var enemy_path: Node
|
||||
|
||||
var current_wave
|
||||
var enemy_spawn_timers = {}
|
||||
var enemies_spawned = {}
|
||||
var enemies_to_spawn := 0
|
||||
var done_spawning = true
|
||||
var enemy_id = 0
|
||||
|
||||
@export var land_enemy_scene : PackedScene
|
||||
@export var air_enemy_scene : PackedScene
|
||||
var enemy_died_callback: Callable
|
||||
var enemy_reached_goal_callback: Callable
|
||||
var current_wave: Dictionary = {}
|
||||
var enemy_spawn_timers: Dictionary = {}
|
||||
var enemies_spawned: Dictionary = {}
|
||||
var enemies_to_spawn: int = 0
|
||||
var done_spawning: bool = true
|
||||
var enemy_id: int = 0
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
@ -27,11 +25,11 @@ func _process(delta: float) -> void:
|
||||
done_spawning = true
|
||||
return
|
||||
|
||||
for x in enemy_spawn_timers:
|
||||
for x: Enemy in enemy_spawn_timers:
|
||||
if enemies_spawned[x] == current_wave[x]:
|
||||
continue
|
||||
|
||||
var enemy_stats = x
|
||||
var enemy_stats: Enemy = x
|
||||
enemy_spawn_timers[x] += delta
|
||||
|
||||
if enemy_spawn_timers[x] >= enemy_stats.spawn_cooldown:
|
||||
@ -39,54 +37,54 @@ func _process(delta: float) -> void:
|
||||
if type == Data.EnemyType.LAND:
|
||||
networked_spawn_land_enemy.rpc(var_to_str(enemy_stats), own_id, enemy_id)
|
||||
if type == Data.EnemyType.AIR:
|
||||
var radius = 10.0
|
||||
var random_dir = Vector3(randf_range(-1, 1), randf_range(-1, 1), randf_range(-1, 1))
|
||||
var random_pos = randf_range(0, radius) * random_dir.normalized()
|
||||
var radius: float = 10.0
|
||||
var random_dir: Vector3 = Vector3(randf_range(-1, 1), randf_range(-1, 1), randf_range(-1, 1))
|
||||
var random_pos: Vector3 = randf_range(0, radius) * random_dir.normalized()
|
||||
networked_spawn_air_enemy.rpc(var_to_str(enemy_stats), random_pos, own_id, enemy_id)
|
||||
|
||||
enemy_spawn_timers[x] -= enemy_stats.spawn_cooldown
|
||||
signal_for_when_enemy_spawns.emit()
|
||||
enemy_spawned.emit()
|
||||
enemy_id += 1
|
||||
enemies_spawned[x] += 1
|
||||
enemies_to_spawn -= 1
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_land_enemy(enemy_stats, id1, id2):
|
||||
var enemy = land_enemy_scene.instantiate() as EnemyController
|
||||
func networked_spawn_land_enemy(enemy_stats: String, id1: int, id2: int) -> void:
|
||||
var enemy: EnemyController = land_enemy_scene.instantiate() as EnemyController
|
||||
enemy.name = str(id1) + str(id2)
|
||||
enemy.stats = str_to_var(enemy_stats)
|
||||
enemy.died.connect(signal_for_after_enemy_died)
|
||||
enemy.reached_goal.connect(signal_for_after_enemy_reached_goal)
|
||||
enemy.died.connect(enemy_died_callback)
|
||||
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
||||
enemy.movement_controller.path = path.curve
|
||||
enemy.position = global_position
|
||||
enemy_path.add_child(enemy)
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_air_enemy(enemy_stats, pos, id1, id2):
|
||||
var enemy = air_enemy_scene.instantiate() as EnemyController
|
||||
func networked_spawn_air_enemy(enemy_stats: String, pos: Vector3, id1: int, id2: int) -> void:
|
||||
var enemy: EnemyController = air_enemy_scene.instantiate() as EnemyController
|
||||
enemy.name = str(id1) + str(id2)
|
||||
enemy.position = pos + global_position
|
||||
enemy.stats = str_to_var(enemy_stats)
|
||||
enemy.died.connect(signal_for_after_enemy_died)
|
||||
enemy.reached_goal.connect(signal_for_after_enemy_reached_goal)
|
||||
enemy.died.connect(enemy_died_callback)
|
||||
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
||||
enemy.movement_controller.goal = dest
|
||||
enemy_path.add_child(enemy)
|
||||
|
||||
|
||||
func spawn_wave(value):
|
||||
var relevant_enemies = {}
|
||||
var wave = {}
|
||||
for index in value:
|
||||
func spawn_wave(value: Dictionary) -> void:
|
||||
var relevant_enemies: Dictionary = {}
|
||||
var wave: Dictionary = {}
|
||||
for index: int in value:
|
||||
wave[Data.enemies[index]] = value[index]
|
||||
for x in wave:
|
||||
for x: Enemy in wave:
|
||||
if x.target_type == type:
|
||||
relevant_enemies[x] = wave[x]
|
||||
current_wave = relevant_enemies
|
||||
enemies_to_spawn = 0
|
||||
enemy_spawn_timers = {}
|
||||
for x in current_wave:
|
||||
for x: Enemy in current_wave:
|
||||
enemies_to_spawn += current_wave[x]
|
||||
enemy_spawn_timers[x] = 0.0
|
||||
enemies_spawned[x] = 0
|
||||
|
@ -1,16 +1,17 @@
|
||||
extends RayCast3D
|
||||
class_name FloatAndSpin extends RayCast3D
|
||||
|
||||
@export_range(0.0, 3.0) var float_height := 1.5
|
||||
@export_range(0.0, 2.0) var bounce_dist := 0.5
|
||||
@export_range(0.0, 2.0) var bounce_speed := 0.4
|
||||
@export_range(0.0, 4.0) var spin_speed := 0.5
|
||||
@export_range(0.0, 3.0) var float_height: float = 1.5
|
||||
@export_range(0.0, 2.0) var bounce_dist: float = 0.5
|
||||
@export_range(0.0, 2.0) var bounce_speed: float = 0.4
|
||||
@export_range(0.0, 4.0) var spin_speed: float = 0.5
|
||||
@export var curve: Curve
|
||||
|
||||
var start_height = 0.0
|
||||
var dest_height = 0.0
|
||||
var t = 0.0
|
||||
var start_height: float = 0.0
|
||||
var dest_height: float = 0.0
|
||||
var t: float = 0.0
|
||||
|
||||
func _ready():
|
||||
|
||||
func _ready() -> void:
|
||||
start_height = position.y
|
||||
|
||||
#raycast downwards and position the item at a set height above the ground that the raycast
|
||||
@ -27,7 +28,8 @@ func _ready():
|
||||
start_height = get_collision_point().y + (1 * float_height) - (bounce_dist / 2.0)
|
||||
dest_height = start_height + (bounce_dist / 2.0)
|
||||
|
||||
func _process(delta):
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
t += bounce_speed * delta
|
||||
position.y = start_height + (dest_height - start_height) * curve.sample(t)
|
||||
if t >= 1.0:
|
||||
|
159
Scripts/game.gd
159
Scripts/game.gd
@ -1,34 +1,35 @@
|
||||
extends Node
|
||||
|
||||
signal wave_started(wave_number)
|
||||
signal wave_finished(wave_number)
|
||||
signal base_took_damage(remaining_health)
|
||||
signal wave_started(wave_number: int)
|
||||
signal wave_finished(wave_number: int)
|
||||
signal base_took_damage(remaining_health: int)
|
||||
signal game_started
|
||||
signal game_restarted
|
||||
signal lost_game
|
||||
signal won_game
|
||||
|
||||
var level_scene = load("res://Worlds/GreenPlanet/Levels/first_level.tscn")
|
||||
var player_scene = load("res://PCs/hero.tscn")
|
||||
var main_menu_scene_path = "res://Scenes/Menus/main_menu.tscn"
|
||||
var multiplayer_lobby_scene_path = "res://Scenes/Menus/multiplayer_lobby.tscn"
|
||||
var singleplayer_lobby_scene_path = "res://Scenes/Menus/singleplayer_lobby.tscn"
|
||||
var won_game_scene = load("res://Scenes/Menus/won_game_screen.tscn")
|
||||
var lose_game_scene = load("res://Scenes/Menus/lost_game_screen.tscn")
|
||||
var connected_players_nodes = {}
|
||||
var game_active := false
|
||||
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
|
||||
var shop_chance := 0.0
|
||||
var level_scene: PackedScene = load("res://Worlds/GreenPlanet/Levels/first_level.tscn")
|
||||
var player_scene: PackedScene = load("res://PCs/hero.tscn")
|
||||
var main_menu_scene_path: String = "res://Scenes/Menus/main_menu.tscn"
|
||||
var multiplayer_lobby_scene_path: String = "res://Scenes/Menus/multiplayer_lobby.tscn"
|
||||
var singleplayer_lobby_scene_path: String = "res://Scenes/Menus/singleplayer_lobby.tscn"
|
||||
var won_game_scene: PackedScene = load("res://Scenes/Menus/won_game_screen.tscn")
|
||||
var lose_game_scene: PackedScene = load("res://Scenes/Menus/lost_game_screen.tscn")
|
||||
var connected_players_nodes: Dictionary = {}
|
||||
var game_active: bool = false
|
||||
var level: Level
|
||||
var enemies: int = 0
|
||||
var objective_health: int = 120
|
||||
var wave: int = 0
|
||||
var endless_mode: bool = false
|
||||
var upcoming_wave: Dictionary
|
||||
var pot: float
|
||||
var UILayer: CanvasLayer
|
||||
var chatbox: Chatbox
|
||||
var wave_limit: int = 20
|
||||
var starting_cash: int = 16
|
||||
var shop_chance: float = 0.0
|
||||
var stats: RoundStats = RoundStats.new()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -37,11 +38,11 @@ func _ready() -> void:
|
||||
get_tree().root.add_child.call_deferred(UILayer)
|
||||
|
||||
|
||||
func parse_command(text : String, peer_id : int):
|
||||
func parse_command(text: String, peer_id: int) -> void:
|
||||
if text.substr(1, 4) == "give":
|
||||
var gift_name = text.substr(6) as String
|
||||
var gift = Data.cards[0]
|
||||
for x in Data.cards:
|
||||
var gift_name: String = text.substr(6) as String
|
||||
var gift: Card = Data.cards[0]
|
||||
for x: Card in Data.cards:
|
||||
if x.display_name == gift_name:
|
||||
gift = x
|
||||
connected_players_nodes[peer_id].inventory.add(gift)
|
||||
@ -52,7 +53,7 @@ func parse_command(text : String, peer_id : int):
|
||||
elif text.substr(1, 11) == "random_maze":
|
||||
level.a_star_graph_3d.build_random_maze(50)
|
||||
elif text.substr(1, 13) == "random_towers":
|
||||
level.a_star_graph_3d.place_random_towers(level.a_star_graph_3d.tower_bases.size() / 3.0)
|
||||
level.a_star_graph_3d.place_random_towers(floori(level.a_star_graph_3d.tower_bases.size() / 3.0))
|
||||
elif text.substr(1, 11) == "set_endless":
|
||||
if is_multiplayer_authority():
|
||||
networked_set_endless.rpc(true)
|
||||
@ -68,7 +69,7 @@ func parse_command(text : String, peer_id : int):
|
||||
elif text.substr(1, 10) == "spawn_shop":
|
||||
level.shop.randomize_cards()
|
||||
elif text.substr(1, 7) == "prosper":
|
||||
for id in connected_players_nodes:
|
||||
for id: int in connected_players_nodes:
|
||||
connected_players_nodes[id].currency += 50
|
||||
elif text.substr(1, 8) == "set_wave":
|
||||
if is_multiplayer_authority():
|
||||
@ -82,29 +83,29 @@ func parse_command(text : String, peer_id : int):
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_set_wave(wave_number):
|
||||
func networked_set_wave(wave_number: int) -> void:
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "Set to wave " + str(wave_number))
|
||||
for player in connected_players_nodes:
|
||||
for player: int in connected_players_nodes:
|
||||
connected_players_nodes[player].hud.set_wave_count(wave_number)
|
||||
wave = wave_number
|
||||
set_upcoming_wave()
|
||||
|
||||
|
||||
func spawn_level():
|
||||
func spawn_level() -> void:
|
||||
level = level_scene.instantiate() as Level
|
||||
for x in level.enemy_spawns:
|
||||
for x: EnemySpawner in level.enemy_spawns:
|
||||
#x.path = level.a_star_graph_3d.visualized_path
|
||||
x.signal_for_after_enemy_died = enemy_died
|
||||
x.signal_for_after_enemy_reached_goal = damage_goal
|
||||
x.signal_for_when_enemy_spawns.connect(increase_enemy_count)
|
||||
x.enemy_died_callback = enemy_died
|
||||
x.enemy_reached_goal_callback = damage_goal
|
||||
x.enemy_spawned.connect(increase_enemy_count)
|
||||
add_child(level)
|
||||
|
||||
|
||||
func spawn_players(player_array, player_profiles, chatbox_open_signal, chatbox_closed_signal):
|
||||
var p_i = 0
|
||||
func spawn_players(player_array: Array, player_profiles: Dictionary, chatbox_open_signal: Signal, chatbox_closed_signal: Signal) -> void:
|
||||
var p_i: int = 0
|
||||
player_array.sort()
|
||||
for peer_id in player_array:
|
||||
var player = player_scene.instantiate() as Hero
|
||||
for peer_id: int in player_array:
|
||||
var player: Hero = player_scene.instantiate() as Hero
|
||||
player.name = str(peer_id)
|
||||
player.player_name_tag.text = player_profiles[peer_id].display_name
|
||||
player.position = level.player_spawns[p_i].global_position
|
||||
@ -125,41 +126,41 @@ func spawn_players(player_array, player_profiles, chatbox_open_signal, chatbox_c
|
||||
start_game()
|
||||
|
||||
|
||||
func ready_player(_value):
|
||||
for key in connected_players_nodes:
|
||||
func ready_player(_value: int) -> void:
|
||||
for key: int in connected_players_nodes:
|
||||
if connected_players_nodes[key].ready_state == false:
|
||||
return
|
||||
spawn_enemy_wave()
|
||||
|
||||
|
||||
func spawn_enemy_wave():
|
||||
func spawn_enemy_wave() -> void:
|
||||
level.shop.close()
|
||||
wave += 1
|
||||
level.a_star_graph_3d.find_path()
|
||||
level.a_star_graph_3d.visualized_path.disable_visualization()
|
||||
level.a_star_graph_3d.disable_all_tower_frames()
|
||||
for spawn in level.enemy_spawns:
|
||||
for spawn: EnemySpawner in level.enemy_spawns:
|
||||
spawn.spawn_wave(upcoming_wave)
|
||||
wave_started.emit(wave)
|
||||
|
||||
|
||||
func set_upcoming_wave():
|
||||
func set_upcoming_wave() -> void:
|
||||
if is_multiplayer_authority():
|
||||
var spawn_power = WaveManager.calculate_spawn_power(wave + 1, connected_players_nodes.size())
|
||||
var new_wave = WaveManager.generate_wave(spawn_power, level.enemy_pool)
|
||||
networked_set_upcoming_wave.rpc(new_wave, 6 + floori(spawn_power / 70))
|
||||
var spawn_power: int = WaveManager.calculate_spawn_power(wave + 1, connected_players_nodes.size())
|
||||
var new_wave: Dictionary = WaveManager.generate_wave(spawn_power, level.enemy_pool)
|
||||
networked_set_upcoming_wave.rpc(new_wave, 6 + floori(spawn_power / 70.0))
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_set_upcoming_wave(wave_dict, coins):
|
||||
func networked_set_upcoming_wave(wave_dict: Dictionary, coins: int) -> void:
|
||||
upcoming_wave = wave_dict
|
||||
pot = coins
|
||||
for key in connected_players_nodes:
|
||||
for key: int in connected_players_nodes:
|
||||
connected_players_nodes[key].hud.set_upcoming_wave(upcoming_wave)
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_set_endless(value):
|
||||
func networked_set_endless(value: bool) -> void:
|
||||
endless_mode = value
|
||||
if endless_mode:
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "Endless mode enabled!")
|
||||
@ -167,15 +168,15 @@ func networked_set_endless(value):
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "Endless mode disabled!")
|
||||
|
||||
|
||||
func increase_enemy_count():
|
||||
func increase_enemy_count() -> void:
|
||||
enemies += 1
|
||||
|
||||
|
||||
func enemy_died(enemy):
|
||||
func enemy_died(enemy: Enemy) -> void:
|
||||
enemies -= 1
|
||||
for key in connected_players_nodes:
|
||||
for key: int in connected_players_nodes:
|
||||
connected_players_nodes[key].hud.enemy_count_down(enemy)
|
||||
for x in level.enemy_spawns:
|
||||
for x: EnemySpawner in level.enemy_spawns:
|
||||
if !x.done_spawning:
|
||||
return
|
||||
if enemies == 0:
|
||||
@ -184,9 +185,10 @@ func enemy_died(enemy):
|
||||
win_game()
|
||||
|
||||
|
||||
func damage_goal(enemy, penalty):
|
||||
func damage_goal(enemy: Enemy, penalty: int) -> void:
|
||||
enemies -= 1
|
||||
for key in connected_players_nodes:
|
||||
stats.add_enemy_undefeated(wave, enemy)
|
||||
for key: int in connected_players_nodes:
|
||||
connected_players_nodes[key].hud.enemy_count_down(enemy)
|
||||
objective_health -= penalty
|
||||
base_took_damage.emit(objective_health)
|
||||
@ -198,8 +200,8 @@ func damage_goal(enemy, penalty):
|
||||
win_game()
|
||||
|
||||
|
||||
func end_wave():
|
||||
for peer_id in connected_players_nodes:
|
||||
func end_wave() -> void:
|
||||
for peer_id: int in connected_players_nodes:
|
||||
connected_players_nodes[peer_id].currency += ceili(pot / connected_players_nodes.size())
|
||||
connected_players_nodes[peer_id].ready_state = false
|
||||
level.a_star_graph_3d.visualized_path.enable_visualization()
|
||||
@ -215,18 +217,18 @@ func end_wave():
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_shop():
|
||||
func networked_spawn_shop() -> void:
|
||||
level.shop.randomize_cards()
|
||||
chatbox.append_message("SERVER", Color.TOMATO, "A shopkeeper has arrived!")
|
||||
|
||||
|
||||
func remove_player(peer_id):
|
||||
func remove_player(peer_id: int) -> void:
|
||||
if connected_players_nodes.has(peer_id):
|
||||
connected_players_nodes[peer_id].queue_free()
|
||||
connected_players_nodes.erase(peer_id)
|
||||
|
||||
|
||||
func start_game():
|
||||
func start_game() -> void:
|
||||
game_active = true
|
||||
enemies = 0
|
||||
objective_health = 120
|
||||
@ -237,70 +239,71 @@ func start_game():
|
||||
level.a_star_graph_3d.enable_non_path_tower_frames()
|
||||
level.a_star_graph_3d.find_path()
|
||||
set_upcoming_wave()
|
||||
for peer_id in connected_players_nodes:
|
||||
connected_players_nodes[peer_id].currency = starting_cash / connected_players_nodes.size()
|
||||
for peer_id: int in connected_players_nodes:
|
||||
connected_players_nodes[peer_id].currency = roundi(float(starting_cash) / float(connected_players_nodes.size()))
|
||||
game_started.emit()
|
||||
|
||||
|
||||
func restart_game():
|
||||
func restart_game() -> void:
|
||||
#implement game reloading system
|
||||
for peer_id in connected_players_nodes:
|
||||
for peer_id: int in connected_players_nodes:
|
||||
connected_players_nodes[peer_id].queue_free()
|
||||
connected_players_nodes.clear()
|
||||
level.queue_free()
|
||||
enemies = 0
|
||||
objective_health = 120
|
||||
wave = 0
|
||||
stats = RoundStats.new()
|
||||
spawn_level()
|
||||
game_restarted.emit()
|
||||
pass
|
||||
|
||||
|
||||
func lose_game():
|
||||
func lose_game() -> void:
|
||||
if game_active == false:
|
||||
return
|
||||
game_active = false
|
||||
Data.save_stats.add_game_outcome(false)
|
||||
Data.save_stats.save_profile_to_disk()
|
||||
var menu = lose_game_scene.instantiate()
|
||||
var menu: Control = lose_game_scene.instantiate()
|
||||
UILayer.add_child(menu)
|
||||
lost_game.emit()
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
for peer_id in connected_players_nodes:
|
||||
for peer_id: int in connected_players_nodes:
|
||||
connected_players_nodes[peer_id].pause()
|
||||
|
||||
|
||||
func win_game():
|
||||
func win_game() -> void:
|
||||
if game_active == false:
|
||||
return
|
||||
game_active = false
|
||||
Data.save_stats.add_game_outcome(true)
|
||||
Data.save_stats.save_profile_to_disk()
|
||||
var menu = won_game_scene.instantiate()
|
||||
var menu: Control = won_game_scene.instantiate()
|
||||
UILayer.add_child(menu)
|
||||
won_game.emit()
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
for peer_id in connected_players_nodes:
|
||||
for peer_id: int in connected_players_nodes:
|
||||
connected_players_nodes[peer_id].pause()
|
||||
|
||||
|
||||
func quit_to_desktop():
|
||||
func quit_to_desktop() -> void:
|
||||
multiplayer.multiplayer_peer.close()
|
||||
multiplayer.multiplayer_peer = null
|
||||
get_tree().quit()
|
||||
|
||||
|
||||
func scene_switch_main_menu():
|
||||
for node in get_children():
|
||||
func scene_switch_main_menu() -> void:
|
||||
for node: Node in get_children():
|
||||
node.queue_free()
|
||||
multiplayer.multiplayer_peer.close()
|
||||
multiplayer.multiplayer_peer = null
|
||||
get_tree().change_scene_to_file(main_menu_scene_path)
|
||||
|
||||
|
||||
func scene_switch_to_multiplayer_lobby():
|
||||
func scene_switch_to_multiplayer_lobby() -> void:
|
||||
get_tree().change_scene_to_file(multiplayer_lobby_scene_path)
|
||||
|
||||
|
||||
func scene_switch_to_singleplayer_lobby():
|
||||
func scene_switch_to_singleplayer_lobby() -> void:
|
||||
get_tree().change_scene_to_file(singleplayer_lobby_scene_path)
|
||||
|
@ -1,16 +1,15 @@
|
||||
extends VBoxContainer
|
||||
class_name GameplayOptionsMenu
|
||||
class_name GameplayOptionsMenu extends VBoxContainer
|
||||
|
||||
@export var look_sens_slider : HSlider
|
||||
@export var look_sens_input : SpinBox
|
||||
@export var toggle_sprint_checkbox : CheckButton
|
||||
@export var invert_lookY : CheckButton
|
||||
@export var invert_lookX : CheckButton
|
||||
@export var fixed_minimap : CheckButton
|
||||
@export var tower_damage : Button
|
||||
@export var self_damage : Button
|
||||
@export var party_damage : Button
|
||||
@export var status_damage : Button
|
||||
@export var look_sens_slider: HSlider
|
||||
@export var look_sens_input: SpinBox
|
||||
@export var toggle_sprint_checkbox: CheckButton
|
||||
@export var invert_lookY: CheckButton
|
||||
@export var invert_lookX: CheckButton
|
||||
@export var fixed_minimap: CheckButton
|
||||
@export var tower_damage: Button
|
||||
@export var self_damage: Button
|
||||
@export var party_damage: Button
|
||||
@export var status_damage: Button
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
@ -1,21 +1,20 @@
|
||||
extends VBoxContainer
|
||||
class_name GraphicsOptionsMenu
|
||||
class_name GraphicsOptionsMenu extends VBoxContainer
|
||||
|
||||
@export var fov_input : SpinBox
|
||||
@export var fov_slider : HSlider
|
||||
@export var vsync_dropdown : OptionButton
|
||||
@export var aa_dropdown : OptionButton
|
||||
@export var window_dropdown : OptionButton
|
||||
@export var fov_input: SpinBox
|
||||
@export var fov_slider: HSlider
|
||||
@export var vsync_dropdown: OptionButton
|
||||
@export var aa_dropdown: OptionButton
|
||||
@export var window_dropdown: OptionButton
|
||||
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
fov_input.value = Data.graphics.hfov
|
||||
fov_slider.value = Data.graphics.hfov
|
||||
vsync_dropdown.selected = Data.graphics.vsync_mode
|
||||
aa_dropdown.selected = Data.graphics.aa_mode
|
||||
|
||||
|
||||
func save():
|
||||
func save() -> void:
|
||||
Data.graphics.hfov = fov_slider.value
|
||||
Data.graphics.vsync_mode = vsync_dropdown.selected
|
||||
Data.graphics.aa_mode = aa_dropdown.selected
|
||||
|
@ -1,22 +1,21 @@
|
||||
extends Node
|
||||
class_name Health
|
||||
class_name Health extends Node
|
||||
|
||||
signal health_depleted
|
||||
signal health_changed(health)
|
||||
signal health_changed(health: int)
|
||||
|
||||
@export var damage_particle_scene : PackedScene
|
||||
@export var damage_particle_scene: PackedScene
|
||||
@export var max_health: int = 10
|
||||
|
||||
@export var max_health := 10
|
||||
var current_health
|
||||
var current_health: int
|
||||
|
||||
func take_damage(damage):
|
||||
func take_damage(damage: int) -> void:
|
||||
current_health -= damage
|
||||
health_changed.emit(current_health)
|
||||
if current_health <= 0:
|
||||
health_depleted.emit()
|
||||
|
||||
|
||||
func heal_damage(healing):
|
||||
func heal_damage(healing: int) -> void:
|
||||
current_health += healing
|
||||
if current_health > max_health:
|
||||
current_health = max_health
|
||||
|
@ -1,24 +1,24 @@
|
||||
extends TextureProgressBar
|
||||
class_name HealthBar extends TextureProgressBar
|
||||
|
||||
@export var health_bar_gradient: Gradient
|
||||
|
||||
@onready var prev_bar = $PreviousHealthBar
|
||||
@onready var prev_bar: TextureProgressBar = $PreviousHealthBar
|
||||
|
||||
|
||||
func setup(health: float):
|
||||
func setup(health: float) -> void:
|
||||
max_value = health
|
||||
value = health
|
||||
prev_bar.max_value = health
|
||||
prev_bar.value = health
|
||||
|
||||
|
||||
func on_health_changed(health: float):
|
||||
func on_health_changed(health: float) -> void:
|
||||
set_visible(true)
|
||||
var health_went_down = true if health < value else false
|
||||
var health_went_down: bool = true if health < value else false
|
||||
value = health
|
||||
tint_progress = health_bar_gradient.sample(value / max_value)
|
||||
if health_went_down:
|
||||
var tween = create_tween()
|
||||
var tween: Tween = create_tween()
|
||||
tween.set_ease(Tween.EASE_OUT)
|
||||
tween.set_trans(Tween.TRANS_QUINT)
|
||||
tween.tween_interval(0.3)
|
||||
|
@ -1,8 +1,7 @@
|
||||
extends CollisionShape3D
|
||||
class_name Hitbox
|
||||
class_name Hitbox extends CollisionShape3D
|
||||
|
||||
signal took_damage(amount)
|
||||
signal took_damage(amount: float)
|
||||
|
||||
|
||||
func damage(amount):
|
||||
func damage(amount: float) -> void:
|
||||
took_damage.emit(amount)
|
||||
|
@ -1,11 +1,11 @@
|
||||
extends StaticBody3D
|
||||
class_name InteractButton
|
||||
class_name InteractButton extends StaticBody3D
|
||||
|
||||
signal button_interacted(value)
|
||||
signal button_interacted(value: int)
|
||||
|
||||
@export var button_press_value := 0
|
||||
@export var press_cost := 0
|
||||
@export var hover_text := "Press [Interact]"
|
||||
@export var button_press_value: int = 0
|
||||
@export var press_cost: int = 0
|
||||
@export var hover_text: String = "Press [Interact]"
|
||||
|
||||
func press():
|
||||
|
||||
func press() -> void:
|
||||
button_interacted.emit(button_press_value)
|
||||
|
@ -1,22 +1,21 @@
|
||||
extends Node
|
||||
class_name Inventory
|
||||
class_name Inventory extends Node
|
||||
|
||||
signal item_added(item)
|
||||
signal item_removed(item)
|
||||
signal item_added(item: Item)
|
||||
signal item_removed(item: Item)
|
||||
|
||||
@export var max_size := 0
|
||||
var contents = {}
|
||||
var size : int :
|
||||
@export var max_size: int = 0
|
||||
var contents: Dictionary = {}
|
||||
var size: int :
|
||||
get:
|
||||
var x = 0
|
||||
for key in contents:
|
||||
var x: int = 0
|
||||
for key: Item in contents:
|
||||
x += contents[key]
|
||||
return x
|
||||
set(_value):
|
||||
return
|
||||
|
||||
|
||||
func add(item : Item) -> bool:
|
||||
func add(item: Item) -> bool:
|
||||
if item != null and max_size == 0 or size < max_size:
|
||||
if contents.has(item):
|
||||
contents[item] += 1
|
||||
@ -28,8 +27,8 @@ func add(item : Item) -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func remove_at(index : int) -> Item:
|
||||
var item = contents.keys()[index]
|
||||
func remove_at(index: int) -> Item:
|
||||
var item: Item = contents.keys()[index]
|
||||
contents[item] -= 1
|
||||
if contents[item] == 0:
|
||||
contents.erase(item)
|
||||
@ -39,8 +38,8 @@ func remove_at(index : int) -> Item:
|
||||
|
||||
|
||||
@rpc("reliable", "any_peer")
|
||||
func networked_add(value):
|
||||
var item = Data.cards[value]
|
||||
func networked_add(value: int) -> void:
|
||||
var item: Item = Data.cards[value]
|
||||
if contents.has(item):
|
||||
contents[item] += 1
|
||||
else:
|
||||
@ -49,8 +48,8 @@ func networked_add(value):
|
||||
|
||||
|
||||
@rpc("reliable", "any_peer")
|
||||
func networked_remove_at(value):
|
||||
var item = contents.keys[value]
|
||||
func networked_remove_at(value: int) -> void:
|
||||
var item: Item = contents.keys[value]
|
||||
contents[item] -= 1
|
||||
if contents[item] == 0:
|
||||
contents.erase(item)
|
||||
|
@ -1,5 +1,4 @@
|
||||
extends StaticBody3D
|
||||
class_name ItemCard
|
||||
class_name ItemCard extends StaticBody3D
|
||||
|
||||
@export var card: Card
|
||||
|
||||
@ -13,7 +12,7 @@ func pick_up() -> Card:
|
||||
|
||||
|
||||
@rpc
|
||||
func networked_pick_up():
|
||||
func networked_pick_up() -> void:
|
||||
$CollisionShape3D.call_deferred("set_disabled", true)
|
||||
$model/CSGSphere3D.set_visible(false)
|
||||
$AudioStreamPlayer3D.play()
|
||||
|
@ -1 +1 @@
|
||||
extends StaticBody3D
|
||||
class_name ItemContainer extends StaticBody3D
|
||||
|
97
Scripts/key_icon_map.gd
Normal file
97
Scripts/key_icon_map.gd
Normal file
@ -0,0 +1,97 @@
|
||||
class_name KeyIconMap
|
||||
|
||||
|
||||
static var keys: Dictionary = {
|
||||
"48" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/0_Key_Light.png",
|
||||
"49" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/1_Key_Light.png",
|
||||
"50" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/2_Key_Light.png",
|
||||
"51" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/3_Key_Light.png",
|
||||
"52" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/4_Key_Light.png",
|
||||
"53" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/5_Key_Light.png",
|
||||
"54" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/6_Key_Light.png",
|
||||
"55" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/7_Key_Light.png",
|
||||
"56" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/8_Key_Light.png",
|
||||
"57" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/9_Key_Light.png",
|
||||
"65" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/A_Key_Light.png",
|
||||
"66" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/B_Key_Light.png",
|
||||
"67" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/C_Key_Light.png",
|
||||
"68" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/D_Key_Light.png",
|
||||
"69" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/E_Key_Light.png",
|
||||
"70" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F_Key_Light.png",
|
||||
"71" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/G_Key_Light.png",
|
||||
"72" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/H_Key_Light.png",
|
||||
"73" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/I_Key_Light.png",
|
||||
"74" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/J_Key_Light.png",
|
||||
"75" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/K_Key_Light.png",
|
||||
"76" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/L_Key_Light.png",
|
||||
"77" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/M_Key_Light.png",
|
||||
"78" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/N_Key_Light.png",
|
||||
"79" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/O_Key_Light.png",
|
||||
"80" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/P_Key_Light.png",
|
||||
"81" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Q_Key_Light.png",
|
||||
"82" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/R_Key_Light.png",
|
||||
"83" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/S_Key_Light.png",
|
||||
"84" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/T_Key_Light.png",
|
||||
"85" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/U_Key_Light.png",
|
||||
"86" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/V_Key_Light.png",
|
||||
"87" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/W_Key_Light.png",
|
||||
"88" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/X_Key_Light.png",
|
||||
"89" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Y_Key_Light.png",
|
||||
"90" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Z_Key_Light.png",
|
||||
"4194328" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Alt_Key_Light.png",
|
||||
"4194322" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Arrow_Down_Key_Light.png",
|
||||
"4194319" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Arrow_Left_Key_Light.png",
|
||||
"4194321" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Arrow_Right_Key_Light.png",
|
||||
"4194320" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Arrow_Up_Key_Light.png",
|
||||
"42" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Asterisk_Key_Light.png",
|
||||
"4194433" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Asterisk_Key_Light.png",
|
||||
"4194308" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Backspace_Alt_Key_Light.png",
|
||||
"91" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Bracket_Left_Key_Light.png",
|
||||
"93" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Bracket_Right_Key_Light.png",
|
||||
"4194329" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Caps_Lock_Key_Light.png",
|
||||
"4194327" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Command_Key_Light.png",
|
||||
"4194326" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Ctrl_Key_Light.png",
|
||||
"4194312" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Del_Key_Light.png",
|
||||
"4194318" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/End_Key_Light.png",
|
||||
"4194309" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Enter_Alt_Key_Light.png",
|
||||
"4194305" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Esc_Key_Light.png",
|
||||
"4194332" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F1_Key_Light.png",
|
||||
"4194333" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F2_Key_Light.png",
|
||||
"4194334" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F3_Key_Light.png",
|
||||
"4194335" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F4_Key_Light.png",
|
||||
"4194336" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F5_Key_Light.png",
|
||||
"4194337" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F6_Key_Light.png",
|
||||
"4194338" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F7_Key_Light.png",
|
||||
"4194339" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F8_Key_Light.png",
|
||||
"4194340" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F9_Key_Light.png",
|
||||
"4194341" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F10_Key_Light.png",
|
||||
"4194342" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F11_Key_Light.png",
|
||||
"4194343" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/F12_Key_Light.png",
|
||||
"4194317" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Home_Key_Light.png",
|
||||
"4194311" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Insert_Key_Light.png",
|
||||
"60" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Mark_Left_Key_Light.png",
|
||||
"62" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Mark_Right_Key_Light.png",
|
||||
"45" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Minus_Key_Light.png",
|
||||
"4194435" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Minus_Key_Light.png",
|
||||
"4194330" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Num_Lock_Key_Light.png",
|
||||
"4194324" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Page_Down_Key_Light.png",
|
||||
"4194323" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Page_Up_Key_Light.png",
|
||||
"43" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Plus_Key_Light.png",
|
||||
"4194437" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Plus_Key_Light.png",
|
||||
"4194314" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Print_Screen_Key_Light.png",
|
||||
"63" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Question_Key_Light.png",
|
||||
"34" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Quote_Key_Light.png",
|
||||
"59" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Semicolon_Key_Light.png",
|
||||
"4194325" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Shift_Key_Light.png",
|
||||
"47" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Slash_Key_Light.png",
|
||||
"4194434" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Slash_Key_Light.png",
|
||||
"32" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Space_Key_Light.png",
|
||||
"4194306" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Tab_Key_Light.png",
|
||||
"126" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Tilda_Key_Light.png",
|
||||
}
|
||||
|
||||
static var mouse_buttons: Dictionary = {
|
||||
"1" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Mouse_Left_Key_Light.png",
|
||||
"3" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Mouse_Middle_Key_Light.png",
|
||||
"2" = "res://XeluController&KeyPrompts/Keyboard & Mouse/Light/Mouse_Right_Key_Light.png",
|
||||
}
|
@ -1,64 +1,67 @@
|
||||
extends VBoxContainer
|
||||
class_name KeybindsOptionsMenu
|
||||
|
||||
var keybind_popup = load("res://Scenes/UI/keybind_popup.tscn")
|
||||
var keybind_boxes = []
|
||||
var keybind_buttons = {}
|
||||
var key_event
|
||||
var selected_button
|
||||
var selected_button_button
|
||||
var listening_for_key := false
|
||||
var keybind_entry_scene: PackedScene = load("res://Scenes/UI/keybind_entry.tscn")
|
||||
var keybind_popup: PackedScene = load("res://Scenes/UI/keybind_popup.tscn")
|
||||
var keybind_boxes: Array[KeybindEntry] = []
|
||||
var key_event: InputEvent
|
||||
var selected_entry: KeybindEntry
|
||||
var listening_for_key: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
for index in Data.keymaps.size():
|
||||
var map = Data.keymaps[index]
|
||||
var button = Button.new()
|
||||
for index: int in Data.keymaps.size():
|
||||
var map: PlayerKeymap = Data.keymaps[index]
|
||||
var button: Button = Button.new()
|
||||
button.text = map.title
|
||||
button.pressed.connect(set_keymap.bind(index))
|
||||
$HBoxContainer.add_child(button)
|
||||
load_keybind_labels()
|
||||
|
||||
|
||||
func set_keymap(keymap_index):
|
||||
func set_keymap(keymap_index: int) -> void:
|
||||
Data.player_keymap = Data.keymaps[keymap_index]
|
||||
Data.player_keymap.apply()
|
||||
load_keybind_labels()
|
||||
|
||||
|
||||
func load_keybind_labels():
|
||||
for box in keybind_boxes:
|
||||
func load_keybind_labels() -> void:
|
||||
for box: KeybindEntry in keybind_boxes:
|
||||
box.queue_free()
|
||||
keybind_boxes.clear()
|
||||
for action in InputMap.get_actions():
|
||||
for action: StringName in InputMap.get_actions():
|
||||
if !action.begins_with("ui_"):
|
||||
var box = HBoxContainer.new()
|
||||
var alabel = Label.new()
|
||||
var elabel = Button.new()
|
||||
alabel.text = action
|
||||
var entry: KeybindEntry = keybind_entry_scene.instantiate() as KeybindEntry
|
||||
entry.set_action_name(action)
|
||||
if InputMap.action_get_events(action).size() > 0:
|
||||
elabel.text = InputMap.action_get_events(action)[0].as_text()
|
||||
elabel.size_flags_horizontal += Control.SIZE_EXPAND
|
||||
alabel.size_flags_horizontal += Control.SIZE_EXPAND
|
||||
alabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
alabel.size_flags_stretch_ratio = 2.0
|
||||
#elabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||
box.add_child(alabel)
|
||||
box.add_child(elabel)
|
||||
elabel.pressed.connect(_on_keybind_button_pressed.bind(elabel))
|
||||
keybind_buttons[elabel] = action
|
||||
$ScrollContainer/VBoxContainer.add_child(box)
|
||||
keybind_boxes.append(box)
|
||||
entry.set_primary_bind(InputMap.action_get_events(action)[0])
|
||||
if InputMap.action_get_events(action).size() > 1:
|
||||
entry.set_secondary_bind(InputMap.action_get_events(action)[1])
|
||||
keybind_boxes.append(entry)
|
||||
entry.primary_bind_pressed.connect(_on_primary_keybind_button_pressed.bind(entry))
|
||||
entry.secondary_bind_pressed.connect(_on_secondary_keybind_button_pressed.bind(entry))
|
||||
$ScrollContainer/VBoxContainer.add_child(entry)
|
||||
|
||||
|
||||
func _on_keybind_button_pressed(value: Button) -> void:
|
||||
selected_button = keybind_buttons[value]
|
||||
selected_button_button = value
|
||||
var popup = keybind_popup.instantiate()
|
||||
popup.event_detected.connect(change_key)
|
||||
func _on_primary_keybind_button_pressed(keybind_entry: KeybindEntry) -> void:
|
||||
selected_entry = keybind_entry
|
||||
var popup: Control = keybind_popup.instantiate()
|
||||
popup.event_detected.connect(change_primary_key)
|
||||
Game.UILayer.add_child(popup)
|
||||
|
||||
|
||||
func change_key(event: InputEvent):
|
||||
Data.player_keymap.replace_action_event(selected_button, event)
|
||||
selected_button_button.text = event.as_text()
|
||||
func _on_secondary_keybind_button_pressed(keybind_entry: KeybindEntry) -> void:
|
||||
selected_entry = keybind_entry
|
||||
var popup: Control = keybind_popup.instantiate()
|
||||
popup.event_detected.connect(change_secondary_key)
|
||||
Game.UILayer.add_child(popup)
|
||||
|
||||
|
||||
func change_primary_key(event: InputEvent) -> void:
|
||||
Data.player_keymap.set_primary_action_event(selected_entry.action_string, event)
|
||||
selected_entry.set_primary_bind(event)
|
||||
|
||||
|
||||
func change_secondary_key(event: InputEvent) -> void:
|
||||
Data.player_keymap.set_secondary_action_event(selected_entry.action_string, event)
|
||||
selected_entry.set_secondary_bind(event)
|
||||
|
@ -1,5 +1,4 @@
|
||||
extends Area3D
|
||||
class_name KillBox
|
||||
class_name KillBox extends Area3D
|
||||
|
||||
@export var level: Level
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
extends GridMap
|
||||
class_name Level
|
||||
class_name Level extends GridMap
|
||||
|
||||
@export var enemy_pool: Array[Enemy]
|
||||
@export var player_spawns: Array[Node3D]
|
||||
@ -13,25 +12,25 @@ class_name Level
|
||||
@export var obstacle_scenes: Array[PackedScene]
|
||||
|
||||
|
||||
func generate_obstacles():
|
||||
var obstacle_count = randi_range(0, 5)
|
||||
for index in obstacle_count:
|
||||
var x = randi_range(0, a_star_graph_3d.grid_size.x - 1)
|
||||
var y = randi_range(0, a_star_graph_3d.grid_size.y - 1)
|
||||
var point_id = int(x * a_star_graph_3d.grid_size.y + y)
|
||||
var chosen_obstacle = randi_range(0, obstacle_scenes.size() - 1)
|
||||
var obstacle = obstacle_scenes[chosen_obstacle].instantiate() as GridMap
|
||||
var orientations = [0, 90, 180, 270]
|
||||
var chosen_orientation = orientations.pick_random()
|
||||
func generate_obstacles() -> void:
|
||||
var obstacle_count: int = randi_range(0, 5)
|
||||
for index: int in obstacle_count:
|
||||
var x: int = randi_range(0, a_star_graph_3d.grid_size.x - 1)
|
||||
var y: int = randi_range(0, a_star_graph_3d.grid_size.y - 1)
|
||||
var point_id: int = int(x * a_star_graph_3d.grid_size.y + y)
|
||||
var chosen_obstacle: int = randi_range(0, obstacle_scenes.size() - 1)
|
||||
var obstacle: GridMap = obstacle_scenes[chosen_obstacle].instantiate() as GridMap
|
||||
var orientations: Array[int] = [0, 90, 180, 270]
|
||||
var chosen_orientation: int = orientations.pick_random()
|
||||
obstacle.position = a_star_graph_3d.astar.get_point_position(point_id)
|
||||
obstacle.set_rotation_degrees(Vector3(0, chosen_orientation, 0))
|
||||
add_child(obstacle)
|
||||
for cell in obstacle.get_used_cells():
|
||||
var cell_pos = obstacle.to_global(obstacle.map_to_local(cell))
|
||||
var map_coord = Vector3i(round(cell_pos.x), 0, round(cell_pos.z))
|
||||
for cell: Vector3i in obstacle.get_used_cells():
|
||||
var cell_pos: Vector3 = obstacle.to_global(obstacle.map_to_local(cell))
|
||||
var map_coord: Vector3i = Vector3i(round(cell_pos.x), 0, round(cell_pos.z))
|
||||
#print("cell_pos: " + str(cell_pos) + "cell.z" + str(cell_pos.z) + ", map_coord: " + str(map_coord))
|
||||
var closest_point = a_star_graph_3d.astar.get_closest_point(cell_pos, true)
|
||||
var closest_point_pos = a_star_graph_3d.astar.get_point_position(closest_point)
|
||||
var closest_point: int = a_star_graph_3d.astar.get_closest_point(cell_pos, true)
|
||||
var closest_point_pos: Vector3 = a_star_graph_3d.astar.get_point_position(closest_point)
|
||||
if closest_point_pos.distance_to(Vector3(cell_pos.x, closest_point_pos.y, cell_pos.z)) <= 0.5:
|
||||
a_star_graph_3d.astar.set_point_disabled(closest_point)
|
||||
if get_cell_item(map_coord) == 1:
|
||||
|
@ -1,10 +1,10 @@
|
||||
extends Control
|
||||
class_name LivesBarSegment
|
||||
|
||||
var lives_left := 6
|
||||
var lives_left: int = 6
|
||||
|
||||
func take_life(value : int):
|
||||
for x in value:
|
||||
func take_life(value: int) -> void:
|
||||
for x: int in value:
|
||||
lives_left -= 1
|
||||
if lives_left == 5:
|
||||
$AnimationPlayer.play("lose1")
|
||||
|
@ -1,10 +1,10 @@
|
||||
extends TextureRect
|
||||
|
||||
@export var segments : Array[LivesBarSegment]
|
||||
var lives := 120.0
|
||||
@export var segments: Array[LivesBarSegment]
|
||||
var lives: float = 120.0
|
||||
|
||||
|
||||
func take_life():
|
||||
var segment_to_animate = ceil(lives / 6.0) - 1
|
||||
func take_life() -> void:
|
||||
var segment_to_animate: int = ceil(lives / 6.0) - 1
|
||||
lives -= 1
|
||||
segments[segment_to_animate].take_life(1)
|
||||
|
@ -1,15 +1,15 @@
|
||||
extends Panel
|
||||
class_name LoadoutEditor
|
||||
class_name LoadoutEditor extends Panel
|
||||
|
||||
signal character_selected(character: int)
|
||||
|
||||
signal character_selected(character)
|
||||
|
||||
func _ready() -> void:
|
||||
for i in Data.characters.size():
|
||||
var button = Button.new()
|
||||
for i: int in Data.characters.size():
|
||||
var button: Button = Button.new()
|
||||
button.text = Data.characters[i].hero_name
|
||||
button.pressed.connect(set_character.bind(i))
|
||||
$HBoxContainer.add_child(button)
|
||||
|
||||
|
||||
func set_character(i: int):
|
||||
func set_character(i: int) -> void:
|
||||
character_selected.emit(i)
|
||||
|
@ -1,14 +1,22 @@
|
||||
extends Control
|
||||
class_name LostGameScreen extends Control
|
||||
|
||||
@export var box: PackedScene
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var wins = float(Data.save_stats.twenty_game_history.count(true))
|
||||
var games = float(Data.save_stats.twenty_game_history.size())
|
||||
var winrate = int((wins / games) * 100.0)
|
||||
var wins: float = float(Data.save_stats.twenty_game_history.count(true))
|
||||
var games: float = float(Data.save_stats.twenty_game_history.size())
|
||||
var winrate: int = int((wins / games) * 100.0)
|
||||
$Label2.text = "Your 20-game winrate is now: " + str(winrate) + "%!"
|
||||
$Label3.text = "Total games: " + str(Data.save_stats.wins + Data.save_stats.losses)
|
||||
$Label4.text = "Total wins: " + str(Data.save_stats.wins)
|
||||
$Label5.text = "Total losses: " + str(Data.save_stats.losses)
|
||||
for wave_key: int in Game.stats.enemies_undefeated:
|
||||
var spawned_box: EnemyBox = box.instantiate() as EnemyBox
|
||||
$VBoxContainer.add_child(spawned_box)
|
||||
spawned_box.set_wave(wave_key)
|
||||
for enemy_key: Enemy in Game.stats.enemies_undefeated[wave_key]:
|
||||
spawned_box.add_enemy_tag(enemy_key, Game.stats.enemies_undefeated[wave_key][enemy_key])
|
||||
|
||||
|
||||
func _on_quit_button_pressed() -> void:
|
||||
|
@ -1,10 +1,11 @@
|
||||
extends Control
|
||||
class_name MainMenu extends Control
|
||||
|
||||
var confirmation_popup_scene = preload("res://Scenes/Menus/confirmation_popup.tscn")
|
||||
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
|
||||
@export var bg_level: Level
|
||||
|
||||
var confirmation_popup_scene: PackedScene = preload("res://Scenes/Menus/confirmation_popup.tscn")
|
||||
var text_input_popup_scene: PackedScene = preload("res://Scenes/Menus/text_input_popup.tscn")
|
||||
var multiplayer_lobby_scene_path: String = "res://Scenes/multiplayer_lobby.tscn"
|
||||
var options_menu_scene: PackedScene = preload("res://Scenes/Menus/options_menu.tscn")
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -15,42 +16,43 @@ func _ready() -> void:
|
||||
bg_level.a_star_graph_3d.place_random_towers(20)
|
||||
bg_level.a_star_graph_3d.disable_all_tower_frames()
|
||||
Game.level = bg_level
|
||||
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)
|
||||
var new_wave: Dictionary = WaveManager.generate_wave(400, bg_level.enemy_pool)
|
||||
for spawn: EnemySpawner in bg_level.enemy_spawns:
|
||||
spawn.enemy_died_callback = enemy_died
|
||||
spawn.enemy_reached_goal_callback = damage_goal
|
||||
spawn.enemy_spawned.connect(increase_enemy_count)
|
||||
spawn.spawn_wave(new_wave)
|
||||
|
||||
|
||||
#these exist purely to make the enemies that spawn on the main menu happy
|
||||
func enemy_died(_some_arg):
|
||||
func enemy_died(_some_arg: Enemy) -> void:
|
||||
pass
|
||||
func damage_goal(_some_arg1, _some_arg2):
|
||||
func damage_goal(_some_arg1: int, _some_arg2: int) -> void:
|
||||
pass
|
||||
func increase_enemy_count():
|
||||
func increase_enemy_count() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_display_name_edit_pressed() -> void:
|
||||
var popup = text_input_popup_scene.instantiate() as TextInputPopup
|
||||
var popup: TextInputPopup = text_input_popup_scene.instantiate() as TextInputPopup
|
||||
popup.set_popup(Data.player_profile.display_name, "Display Name", "Confirm")
|
||||
popup.completed.connect(change_profile_display_name)
|
||||
add_child(popup)
|
||||
|
||||
|
||||
func change_profile_display_name(display_name):
|
||||
func change_profile_display_name(display_name: String) -> void:
|
||||
$ProfileEditor/VBoxContainer/HBoxContainer/DisplayName.text = display_name
|
||||
Data.player_profile.set_display_name(display_name)
|
||||
|
||||
|
||||
func _on_quit_button_pressed() -> void:
|
||||
var popup = confirmation_popup_scene.instantiate() as ConfirmationPopup
|
||||
var popup: ConfirmationPopup = confirmation_popup_scene.instantiate() as ConfirmationPopup
|
||||
popup.set_popup("Are you sure you want to quit?", "Yes", "No")
|
||||
popup.completed.connect(quit_game)
|
||||
add_child(popup)
|
||||
|
||||
|
||||
func quit_game(confirmation):
|
||||
func quit_game(confirmation: bool) -> void:
|
||||
if confirmation:
|
||||
get_tree().quit()
|
||||
|
||||
@ -60,7 +62,7 @@ func _on_play_button_pressed() -> void:
|
||||
|
||||
|
||||
func _on_options_button_pressed() -> void:
|
||||
var menu = options_menu_scene.instantiate()
|
||||
var menu: OptionsMenu = options_menu_scene.instantiate()
|
||||
add_child(menu)
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
extends Camera3D
|
||||
class_name MinimapCamera3D
|
||||
|
||||
@export var anchor : Node3D
|
||||
#@export var face_north : bool
|
||||
@export var anchor: Node3D
|
||||
#@export var face_north: bool
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
global_position = anchor.global_position + (Vector3.UP * 100)
|
||||
|
@ -1,24 +1,23 @@
|
||||
extends Control
|
||||
class_name MultiplayerLobby
|
||||
class_name MultiplayerLobby extends Control
|
||||
|
||||
signal player_connected(peer_id, player_profile)
|
||||
signal player_disconnected(peer_id)
|
||||
signal player_connected(peer_id: int, player_profile: PlayerProfile)
|
||||
signal player_disconnected(peer_id: int)
|
||||
signal disconnected_from_server
|
||||
|
||||
const SERVER_PORT := 58008
|
||||
const MAX_PLAYERS := 4
|
||||
const SERVER_PORT: int = 58008
|
||||
const MAX_PLAYERS: int = 4
|
||||
|
||||
var enet_peer = ENetMultiplayerPeer.new()
|
||||
@export var server_form: ServerForm
|
||||
@export var scoreboard: Scoreboard
|
||||
@export var loadout_editor: HeroSelector
|
||||
@export var chatbox: Chatbox
|
||||
|
||||
@export var server_form : ServerForm
|
||||
@export var scoreboard : Scoreboard
|
||||
@export var loadout_editor : HeroSelector
|
||||
@export var chatbox : Chatbox
|
||||
var alert_popup_scene = preload("res://Scenes/Menus/alert_popup.tscn")
|
||||
var connected_players_profiles = {}
|
||||
var enet_peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new()
|
||||
var alert_popup_scene: PackedScene = preload("res://Scenes/Menus/alert_popup.tscn")
|
||||
var connected_players_profiles: Dictionary = {}
|
||||
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
multiplayer.peer_connected.connect(_on_player_connected)
|
||||
multiplayer.peer_disconnected.connect(_on_player_disconnected)
|
||||
multiplayer.connected_to_server.connect(_on_connection_succeeded)
|
||||
@ -26,29 +25,29 @@ func _ready():
|
||||
multiplayer.server_disconnected.connect(_on_server_disconnected)
|
||||
|
||||
|
||||
func _on_player_connected(peer_id):
|
||||
func _on_player_connected(peer_id: int) -> void:
|
||||
add_player.rpc_id(peer_id, Data.player_profile.to_dict())
|
||||
|
||||
|
||||
func _on_player_disconnected(peer_id):
|
||||
func _on_player_disconnected(peer_id: int) -> void:
|
||||
if chatbox:
|
||||
chatbox.append_message("SERVER", Color.TOMATO, connected_players_profiles[peer_id].display_name + " has disconnected!")
|
||||
connected_players_profiles.erase(peer_id)
|
||||
player_disconnected.emit(peer_id)
|
||||
|
||||
|
||||
func _on_connection_succeeded():
|
||||
func _on_connection_succeeded() -> void:
|
||||
setup_game(multiplayer.get_unique_id())
|
||||
|
||||
|
||||
func _on_connection_failed():
|
||||
func _on_connection_failed() -> void:
|
||||
multiplayer.multiplayer_peer = null
|
||||
var popup = alert_popup_scene.instantiate() as AlertPopup
|
||||
var popup: AlertPopup = alert_popup_scene.instantiate() as AlertPopup
|
||||
popup.set_popup("Unable to connect to server", "OK")
|
||||
add_child(popup)
|
||||
|
||||
|
||||
func _on_server_disconnected():
|
||||
func _on_server_disconnected() -> void:
|
||||
multiplayer.multiplayer_peer = null
|
||||
disconnected_from_server.emit()
|
||||
|
||||
@ -59,7 +58,7 @@ func create_server() -> void:
|
||||
setup_game(1)
|
||||
|
||||
|
||||
func setup_game(peer_id):
|
||||
func setup_game(peer_id: int) -> void:
|
||||
player_disconnected.connect(Game.remove_player)
|
||||
Game.spawn_level()
|
||||
scoreboard.all_players_ready.connect(start_game)
|
||||
@ -74,7 +73,7 @@ func setup_game(peer_id):
|
||||
player_connected.emit(peer_id, Data.player_profile)
|
||||
|
||||
|
||||
func setup_the_ui():
|
||||
func setup_the_ui() -> void:
|
||||
scoreboard.unready_all_players()
|
||||
scoreboard.set_visible(true)
|
||||
loadout_editor.set_visible(true)
|
||||
@ -83,39 +82,39 @@ func setup_the_ui():
|
||||
|
||||
|
||||
func connect_to_server() -> void:
|
||||
var ip = server_form.get_server_ip() if server_form.get_server_ip() else "localhost"
|
||||
var port = server_form.get_server_port() if server_form.get_server_port() else str(SERVER_PORT)
|
||||
var ip: String = server_form.get_server_ip() if server_form.get_server_ip() else "localhost"
|
||||
var port: String = server_form.get_server_port() if server_form.get_server_port() else str(SERVER_PORT)
|
||||
enet_peer.create_client(ip, int(port))
|
||||
multiplayer.multiplayer_peer = enet_peer
|
||||
|
||||
|
||||
func ready_player():
|
||||
var peer_id = multiplayer.get_unique_id()
|
||||
func ready_player() -> void:
|
||||
var peer_id: int = multiplayer.get_unique_id()
|
||||
networked_ready_player.rpc(peer_id)
|
||||
|
||||
|
||||
func start_game():
|
||||
func start_game() -> void:
|
||||
enet_peer.refuse_new_connections = true
|
||||
Game.spawn_players(connected_players_profiles.keys(), connected_players_profiles, chatbox.opened, chatbox.closed)
|
||||
scoreboard.set_visible(false)
|
||||
loadout_editor.set_visible(false)
|
||||
|
||||
|
||||
func edit_player_profile(_argument):
|
||||
var profile_dict = Data.player_profile.to_dict()
|
||||
func edit_player_profile(_argument: PlayerProfile) -> void:
|
||||
var profile_dict: Dictionary = Data.player_profile.to_dict()
|
||||
networked_edit_player_profile.rpc(multiplayer.get_unique_id(), profile_dict)
|
||||
|
||||
|
||||
@rpc("any_peer", "reliable", "call_local")
|
||||
func networked_edit_player_profile(peer_id, new_profile_dict):
|
||||
func networked_edit_player_profile(peer_id: int, new_profile_dict: Dictionary) -> void:
|
||||
connected_players_profiles[peer_id].set_display_name(new_profile_dict["display_name"])
|
||||
connected_players_profiles[peer_id].set_preferred_class(new_profile_dict["preferred_class"])
|
||||
|
||||
|
||||
@rpc("any_peer","reliable")
|
||||
func add_player(new_player_profile_dict):
|
||||
var new_player_peer_id = multiplayer.get_remote_sender_id()
|
||||
var new_player_profile = PlayerProfile.from_dict(new_player_profile_dict)
|
||||
func add_player(new_player_profile_dict: Dictionary) -> void:
|
||||
var new_player_peer_id: int = multiplayer.get_remote_sender_id()
|
||||
var new_player_profile: PlayerProfile = PlayerProfile.from_dict(new_player_profile_dict)
|
||||
if chatbox:
|
||||
chatbox.append_message("SERVER", Color.TOMATO, new_player_profile.display_name + " has connected!")
|
||||
connected_players_profiles[new_player_peer_id] = new_player_profile
|
||||
@ -123,7 +122,7 @@ func add_player(new_player_profile_dict):
|
||||
|
||||
|
||||
@rpc("any_peer", "reliable", "call_local")
|
||||
func networked_ready_player(peer_id):
|
||||
func networked_ready_player(peer_id: int) -> void:
|
||||
scoreboard.set_player_ready_state(peer_id, true)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
extends Camera3D
|
||||
class_name OnTopCamera extends Camera3D
|
||||
|
||||
@export var clone_camera : Node3D
|
||||
@export var clone_camera: Node3D
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
global_position = clone_camera.global_position
|
||||
|
@ -1,9 +1,8 @@
|
||||
extends Control
|
||||
class_name OptionsMenu
|
||||
class_name OptionsMenu extends Control
|
||||
|
||||
@export var gameplay : GameplayOptionsMenu
|
||||
@export var graphics : GraphicsOptionsMenu
|
||||
@export var keybinds : KeybindsOptionsMenu
|
||||
@export var gameplay: GameplayOptionsMenu
|
||||
@export var graphics: GraphicsOptionsMenu
|
||||
@export var keybinds: KeybindsOptionsMenu
|
||||
|
||||
|
||||
func _on_cancel_pressed() -> void:
|
||||
@ -19,4 +18,5 @@ func _on_confirm_pressed() -> void:
|
||||
Data.audio.save_profile_to_disk()
|
||||
Data.preferences.save_profile_to_disk()
|
||||
Data.player_keymap.save_profile_to_disk()
|
||||
Data.player_controller_keymap.append_input_map()
|
||||
queue_free()
|
||||
|
@ -1,16 +1,17 @@
|
||||
extends PathFollow3D
|
||||
class_name PathVisualThing extends PathFollow3D
|
||||
|
||||
@export var speed: float = 0.5
|
||||
@export var world_model: Node3D
|
||||
@export var minimap_model: Node3D
|
||||
|
||||
@export var speed = 0.5
|
||||
@export var world_model : Node3D
|
||||
@export var minimap_model : Node3D
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
progress += speed * delta
|
||||
|
||||
|
||||
func set_world_visible(value: bool):
|
||||
func set_world_visible(value: bool) -> void:
|
||||
world_model.set_visible(value)
|
||||
|
||||
|
||||
func set_minimap_visible(value: bool):
|
||||
func set_minimap_visible(value: bool) -> void:
|
||||
minimap_model.set_visible(value)
|
||||
|
@ -1,10 +1,10 @@
|
||||
extends Control
|
||||
class_name PauseMenu
|
||||
class_name PauseMenu extends Control
|
||||
|
||||
signal closed
|
||||
signal closed()
|
||||
|
||||
var options_menu_scene: PackedScene = preload("res://Scenes/Menus/options_menu.tscn")
|
||||
var confirmation_popup_scene: PackedScene = preload("res://Scenes/Menus/confirmation_popup.tscn")
|
||||
|
||||
var options_menu_scene = preload("res://Scenes/Menus/options_menu.tscn")
|
||||
var confirmation_popup_scene = preload("res://Scenes/Menus/confirmation_popup.tscn")
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("Pause"):
|
||||
@ -18,30 +18,30 @@ func _on_resume_pressed() -> void:
|
||||
|
||||
|
||||
func _on_options_pressed() -> void:
|
||||
var menu = options_menu_scene.instantiate()
|
||||
var menu: OptionsMenu = options_menu_scene.instantiate()
|
||||
add_child(menu)
|
||||
|
||||
|
||||
func _on_quit_to_main_menu_pressed() -> void:
|
||||
var popup = confirmation_popup_scene.instantiate() as ConfirmationPopup
|
||||
var popup: ConfirmationPopup = confirmation_popup_scene.instantiate() as ConfirmationPopup
|
||||
popup.set_popup("Are you sure you want to quit and return to main menu?", "Yes", "No")
|
||||
popup.completed.connect(return_to_menu)
|
||||
add_child(popup)
|
||||
|
||||
|
||||
func return_to_menu(confirmation):
|
||||
func return_to_menu(confirmation: bool) -> void:
|
||||
if confirmation:
|
||||
Game.scene_switch_main_menu()
|
||||
|
||||
|
||||
func _on_quit_to_desktop_pressed() -> void:
|
||||
var popup = confirmation_popup_scene.instantiate() as ConfirmationPopup
|
||||
var popup: ConfirmationPopup = confirmation_popup_scene.instantiate() as ConfirmationPopup
|
||||
popup.set_popup("Are you sure you want to quit?", "Yes", "No")
|
||||
popup.completed.connect(quit_game)
|
||||
add_child(popup)
|
||||
|
||||
|
||||
func quit_game(confirmation):
|
||||
func quit_game(confirmation: bool) -> void:
|
||||
if confirmation:
|
||||
Game.quit_to_desktop()
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
extends PanelContainer
|
||||
class_name PickupNotification extends PanelContainer
|
||||
|
||||
@export var fade_out_time: float
|
||||
@export var style: StyleBoxFlat
|
||||
@ -9,8 +9,8 @@ extends PanelContainer
|
||||
@export var epic_background: Color
|
||||
@export var legendary_background: Color
|
||||
|
||||
var fade_time = 0.0
|
||||
var fading = false
|
||||
var fade_time: float = 0.0
|
||||
var fading: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
15
Scripts/round_stats.gd
Normal file
15
Scripts/round_stats.gd
Normal file
@ -0,0 +1,15 @@
|
||||
class_name RoundStats extends RefCounted
|
||||
|
||||
var enemies_undefeated: Dictionary
|
||||
|
||||
|
||||
func add_enemy_undefeated(wave_num: int, enemy: Enemy) -> void:
|
||||
if enemies_undefeated.has(wave_num):
|
||||
var wave_dict: Dictionary = enemies_undefeated[wave_num] as Dictionary
|
||||
if wave_dict.has(enemy):
|
||||
wave_dict[enemy] += 1
|
||||
else:
|
||||
wave_dict[enemy] = 1
|
||||
else:
|
||||
enemies_undefeated[wave_num] = {}
|
||||
enemies_undefeated[wave_num][enemy] = 1
|
@ -1,10 +1,10 @@
|
||||
extends PanelContainer
|
||||
class_name Scoreboard
|
||||
class_name Scoreboard extends PanelContainer
|
||||
|
||||
signal all_players_ready
|
||||
signal all_players_ready()
|
||||
|
||||
var entry_scene: PackedScene = preload("res://Scenes/UI/scoreboard_entry.tscn")
|
||||
var entries: Dictionary = {}
|
||||
|
||||
var entry_scene = preload("res://Scenes/UI/scoreboard_entry.tscn")
|
||||
var entries = {}
|
||||
|
||||
func _ready() -> void:
|
||||
$VBoxContainer/DummyEntry1.queue_free()
|
||||
@ -12,26 +12,26 @@ func _ready() -> void:
|
||||
$VBoxContainer/DummyEntry3.queue_free()
|
||||
|
||||
|
||||
func get_player_entry(peer_id) -> ScoreboardEntry:
|
||||
func get_player_entry(peer_id: int) -> ScoreboardEntry:
|
||||
return entries[peer_id]
|
||||
|
||||
|
||||
func set_player_ready_state(peer_id: int, state: bool):
|
||||
func set_player_ready_state(peer_id: int, state: bool) -> void:
|
||||
entries[peer_id].set_ready_state(state)
|
||||
for id in entries:
|
||||
for id: int in entries:
|
||||
if !entries[id].get_ready_state():
|
||||
return
|
||||
all_players_ready.emit()
|
||||
unready_all_players()
|
||||
|
||||
|
||||
func unready_all_players():
|
||||
for peer_id in entries:
|
||||
func unready_all_players() -> void:
|
||||
for peer_id: int in entries:
|
||||
entries[peer_id].set_ready_state(false)
|
||||
|
||||
|
||||
func add_player(peer_id: int, player_profile: PlayerProfile):
|
||||
var entry = entry_scene.instantiate() as ScoreboardEntry
|
||||
func add_player(peer_id: int, player_profile: PlayerProfile) -> void:
|
||||
var entry: ScoreboardEntry = entry_scene.instantiate() as ScoreboardEntry
|
||||
entry.name = str(peer_id)
|
||||
entry.set_display_name("", player_profile.get_display_name())
|
||||
entry.set_character(0, player_profile.get_preferred_class())
|
||||
@ -41,6 +41,6 @@ func add_player(peer_id: int, player_profile: PlayerProfile):
|
||||
$VBoxContainer.add_child(entry)
|
||||
|
||||
|
||||
func remove_player(peer_id: int):
|
||||
func remove_player(peer_id: int) -> void:
|
||||
entries[peer_id].queue_free()
|
||||
entries.erase(peer_id)
|
||||
|
@ -1,24 +1,23 @@
|
||||
extends HBoxContainer
|
||||
class_name ScoreboardEntry
|
||||
class_name ScoreboardEntry extends HBoxContainer
|
||||
|
||||
var display_name: String
|
||||
var character: int
|
||||
var ready_state: bool
|
||||
|
||||
|
||||
func set_display_name(_old_name: String, new_name: String):
|
||||
func set_display_name(_old_name: String, new_name: String) -> void:
|
||||
display_name = new_name
|
||||
$DisplayName.text = new_name
|
||||
func get_display_name() -> String:
|
||||
return display_name
|
||||
|
||||
func set_character(_old_class: int, new_class: int):
|
||||
func set_character(_old_class: int, new_class: int) -> void:
|
||||
character = new_class
|
||||
$CharacterName.text = Data.characters[new_class].hero_name
|
||||
func get_character() -> int:
|
||||
return character
|
||||
|
||||
func set_ready_state(state: bool):
|
||||
func set_ready_state(state: bool) -> void:
|
||||
ready_state = state
|
||||
if state:
|
||||
$TextureRect.texture.region = Rect2(32, 0, 32, 32)
|
||||
|
@ -1,5 +1,4 @@
|
||||
extends PanelContainer
|
||||
class_name ServerForm
|
||||
class_name ServerForm extends PanelContainer
|
||||
|
||||
signal connect_button_pressed
|
||||
signal host_button_pressed
|
||||
|
@ -1,12 +1,12 @@
|
||||
extends Node3D
|
||||
class_name ShopStand
|
||||
class_name ShopStand extends Node3D
|
||||
|
||||
@export var cards : Array[CardInHand]
|
||||
@export var choice_colliders : Array[CollisionShape3D]
|
||||
@export var choice_buttons : Array[InteractButton]
|
||||
@export var choice_sprites : Array[Sprite3D]
|
||||
@export var item_card_scene : PackedScene
|
||||
var price_dict = {
|
||||
@export var cards: Array[CardInHand]
|
||||
@export var choice_colliders: Array[CollisionShape3D]
|
||||
@export var choice_buttons: Array[InteractButton]
|
||||
@export var choice_sprites: Array[Sprite3D]
|
||||
@export var item_card_scene: PackedScene
|
||||
|
||||
var price_dict: Dictionary = {
|
||||
Data.Rarity.UNCOMMON : 30,
|
||||
Data.Rarity.RARE : 50,
|
||||
Data.Rarity.EPIC : 75,
|
||||
@ -14,18 +14,18 @@ var price_dict = {
|
||||
}
|
||||
|
||||
|
||||
func close():
|
||||
for x in choice_colliders:
|
||||
func close() -> void:
|
||||
for x: CollisionShape3D in choice_colliders:
|
||||
x.disabled = true
|
||||
for x in choice_sprites:
|
||||
for x: Sprite3D in choice_sprites:
|
||||
x.set_visible(false)
|
||||
|
||||
|
||||
func randomize_cards():
|
||||
var cheap_cards = []
|
||||
var medium_cards = []
|
||||
var pricey_cards = []
|
||||
for card in Data.cards:
|
||||
func randomize_cards() -> void:
|
||||
var cheap_cards: Array[Card] = []
|
||||
var medium_cards: Array[Card] = []
|
||||
var pricey_cards: Array[Card] = []
|
||||
for card: Card in Data.cards:
|
||||
if card.rarity == Data.Rarity.UNCOMMON or card.rarity == Data.Rarity.RARE:
|
||||
cheap_cards.append(card)
|
||||
if card.rarity == Data.Rarity.RARE or card.rarity == Data.Rarity.EPIC:
|
||||
@ -33,36 +33,36 @@ func randomize_cards():
|
||||
if card.rarity == Data.Rarity.EPIC or card.rarity == Data.Rarity.LEGENDARY:
|
||||
pricey_cards.append(card)
|
||||
|
||||
for x in 3:
|
||||
var chosen_card = cheap_cards.pick_random()
|
||||
for x: int in 3:
|
||||
var chosen_card: Card = cheap_cards.pick_random()
|
||||
cards[x].set_card(chosen_card)
|
||||
cards[x].view_tower()
|
||||
choice_buttons[x].press_cost = price_dict[chosen_card.rarity]
|
||||
choice_buttons[x].hover_text = "Spend $" + str(choice_buttons[x].press_cost) + " to acquire " + chosen_card.display_name + "?"
|
||||
for x in 2:
|
||||
var chosen_card = medium_cards.pick_random()
|
||||
for x: int in 2:
|
||||
var chosen_card: Card = medium_cards.pick_random()
|
||||
cards[x+3].set_card(chosen_card)
|
||||
cards[x+3].view_tower()
|
||||
choice_buttons[x+3].press_cost = price_dict[chosen_card.rarity]
|
||||
choice_buttons[x+3].hover_text = "Spend $" + str(choice_buttons[x+3].press_cost) + " to acquire " + chosen_card.display_name + "?"
|
||||
for x in 1:
|
||||
var chosen_card = pricey_cards.pick_random()
|
||||
for x: int in 1:
|
||||
var chosen_card: Card = pricey_cards.pick_random()
|
||||
cards[x+5].set_card(chosen_card)
|
||||
cards[x+5].view_tower()
|
||||
choice_buttons[x+5].press_cost = price_dict[chosen_card.rarity]
|
||||
choice_buttons[x+5].hover_text = "Spend $" + str(choice_buttons[x+5].press_cost) + " to acquire " + chosen_card.display_name + "?"
|
||||
for x in choice_colliders:
|
||||
for x: CollisionShape3D in choice_colliders:
|
||||
x.set_deferred("disabled", false)
|
||||
for x in choice_sprites:
|
||||
for x: Sprite3D in choice_sprites:
|
||||
x.set_visible(true)
|
||||
|
||||
|
||||
func retrieve_card(i):
|
||||
func retrieve_card(i: int) -> void:
|
||||
#close()
|
||||
choice_colliders[i].disabled = true
|
||||
choice_sprites[i].set_visible(false)
|
||||
var card = cards[i].stats
|
||||
var item = item_card_scene.instantiate() as ItemCard
|
||||
var card: Card = cards[i].stats
|
||||
var item: ItemCard = item_card_scene.instantiate() as ItemCard
|
||||
item.card = card
|
||||
item.position = Vector3(2.128, 0, 0)
|
||||
add_child(item)
|
||||
|
@ -1,20 +1,21 @@
|
||||
extends Control
|
||||
class_name SinglePlayerLobby extends Control
|
||||
|
||||
@export var scoreboard : Scoreboard
|
||||
@export var loadout_editor : HeroSelector
|
||||
@export var chatbox : Chatbox
|
||||
var connected_players_profiles = {}
|
||||
@export var scoreboard: Scoreboard
|
||||
@export var loadout_editor: HeroSelector
|
||||
@export var chatbox: Chatbox
|
||||
|
||||
var connected_players_profiles: Dictionary = {}
|
||||
var enet_peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var enet_peer = ENetMultiplayerPeer.new()
|
||||
enet_peer.create_server(58008, 1)
|
||||
multiplayer.multiplayer_peer = enet_peer
|
||||
enet_peer.refuse_new_connections = true
|
||||
setup_game()
|
||||
|
||||
|
||||
func setup_game():
|
||||
func setup_game() -> void:
|
||||
Game.spawn_level()
|
||||
scoreboard.add_player(1, Data.player_profile)
|
||||
scoreboard.all_players_ready.connect(start_game)
|
||||
@ -24,21 +25,16 @@ func setup_game():
|
||||
chatbox.username = Data.player_profile.display_name
|
||||
Data.player_profile.display_name_changed.connect(chatbox.change_username)
|
||||
loadout_editor.hero_selected.connect(Data.player_profile.set_preferred_class)
|
||||
loadout_editor.hero_selected.connect(edit_player_profile)
|
||||
connected_players_profiles[1] = Data.player_profile
|
||||
|
||||
|
||||
func edit_player_profile(_argument):
|
||||
var profile_dict = Data.player_profile.to_dict()
|
||||
|
||||
|
||||
func start_game():
|
||||
func start_game() -> void:
|
||||
Game.spawn_players(connected_players_profiles.keys(), connected_players_profiles, chatbox.opened, chatbox.closed)
|
||||
scoreboard.set_visible(false)
|
||||
loadout_editor.set_visible(false)
|
||||
|
||||
|
||||
func setup_the_ui():
|
||||
func setup_the_ui() -> void:
|
||||
scoreboard.unready_all_players()
|
||||
scoreboard.set_visible(true)
|
||||
loadout_editor.set_visible(true)
|
||||
|
@ -1,5 +1,5 @@
|
||||
extends EnemyController
|
||||
class_name Dummy
|
||||
class_name Dummy extends EnemyController
|
||||
|
||||
|
||||
func _on_health_health_depleted() -> void:
|
||||
$Dog/Health.max_health = stats.health
|
||||
|
@ -1,9 +1,9 @@
|
||||
extends PanelContainer
|
||||
class_name TextInputPopup
|
||||
class_name TextInputPopup extends PanelContainer
|
||||
|
||||
signal completed(outcome)
|
||||
signal completed(outcome: bool)
|
||||
|
||||
func set_popup(prompt_text, placeholder_text, confirm_text):
|
||||
|
||||
func set_popup(prompt_text: String, placeholder_text: String, confirm_text: String) -> void:
|
||||
$VBoxContainer/LineEdit.text = prompt_text
|
||||
$VBoxContainer/LineEdit.placeholder_text = placeholder_text
|
||||
$VBoxContainer/Button.text = confirm_text
|
||||
|
@ -1,79 +1,78 @@
|
||||
extends StaticBody3D
|
||||
class_name TowerBase
|
||||
class_name TowerBase extends StaticBody3D
|
||||
|
||||
@export var inventory : Inventory
|
||||
@export var block : Node3D
|
||||
@export var collider : CollisionShape3D
|
||||
@export var minimap_icon : Sprite3D
|
||||
@export var north_icon : Sprite3D
|
||||
@export var south_icon : Sprite3D
|
||||
@export var east_icon : Sprite3D
|
||||
@export var west_icon : Sprite3D
|
||||
@export var north_mesh : CSGBox3D
|
||||
@export var south_mesh : CSGBox3D
|
||||
@export var east_mesh : CSGBox3D
|
||||
@export var west_mesh : CSGBox3D
|
||||
@export var north_collider : CollisionShape3D
|
||||
@export var south_collider : CollisionShape3D
|
||||
@export var east_collider : CollisionShape3D
|
||||
@export var west_collider : CollisionShape3D
|
||||
@export var inventory: Inventory
|
||||
@export var block: Node3D
|
||||
@export var collider: CollisionShape3D
|
||||
@export var minimap_icon: Sprite3D
|
||||
@export var north_icon: Sprite3D
|
||||
@export var south_icon: Sprite3D
|
||||
@export var east_icon: Sprite3D
|
||||
@export var west_icon: Sprite3D
|
||||
@export var north_mesh: CSGBox3D
|
||||
@export var south_mesh: CSGBox3D
|
||||
@export var east_mesh: CSGBox3D
|
||||
@export var west_mesh: CSGBox3D
|
||||
@export var north_collider: CollisionShape3D
|
||||
@export var south_collider: CollisionShape3D
|
||||
@export var east_collider: CollisionShape3D
|
||||
@export var west_collider: CollisionShape3D
|
||||
|
||||
var owner_id : int
|
||||
var point_id : int
|
||||
var tower = null
|
||||
var has_card : bool :
|
||||
var owner_id: int
|
||||
var point_id: int
|
||||
var tower: Tower = null
|
||||
var has_card: bool :
|
||||
set(_value):
|
||||
return
|
||||
get:
|
||||
return inventory.size != 0
|
||||
|
||||
|
||||
func set_color(color: Color):
|
||||
func set_color(color: Color) -> void:
|
||||
$MeshInstance3D.set_instance_shader_parameter("Color", color)
|
||||
|
||||
|
||||
func set_float(value: float):
|
||||
func set_float(value: float) -> void:
|
||||
$MeshInstance3D.set_instance_shader_parameter("Float", value)
|
||||
|
||||
|
||||
func add_card(card: Card, caller_id: int) -> bool:
|
||||
var result = inventory.add(card)
|
||||
var result: bool = inventory.add(card)
|
||||
if result:
|
||||
networked_spawn_tower.rpc(caller_id)
|
||||
return result
|
||||
|
||||
|
||||
func remove_card():
|
||||
func remove_card() -> void:
|
||||
Game.connected_players_nodes[tower.owner_id].add_card(inventory.remove_at(0))
|
||||
networked_remove_tower.rpc()
|
||||
|
||||
|
||||
func toggle_collision():
|
||||
func toggle_collision() -> void:
|
||||
collider.disabled = !collider.disabled
|
||||
|
||||
|
||||
func set_north_wall(value: bool):
|
||||
func set_north_wall(value: bool) -> void:
|
||||
north_mesh.set_visible(value)
|
||||
north_collider.disabled = !value
|
||||
|
||||
|
||||
func set_south_wall(value : bool):
|
||||
func set_south_wall(value: bool) -> void:
|
||||
south_mesh.set_visible(value)
|
||||
south_collider.disabled = !value
|
||||
|
||||
|
||||
func set_east_wall(value : bool):
|
||||
func set_east_wall(value: bool) -> void:
|
||||
east_mesh.set_visible(value)
|
||||
east_collider.disabled = !value
|
||||
|
||||
|
||||
func set_west_wall(value : bool):
|
||||
func set_west_wall(value: bool) -> void:
|
||||
west_mesh.set_visible(value)
|
||||
west_collider.disabled = !value
|
||||
|
||||
|
||||
@rpc("reliable", "call_local", "any_peer")
|
||||
func networked_spawn_tower(caller_id : int):
|
||||
func networked_spawn_tower(caller_id: int) -> void:
|
||||
tower = inventory.contents.keys()[0].turret_scene.instantiate() as Tower
|
||||
tower.stats = inventory.contents.keys()[0].tower_stats
|
||||
tower.name = "tower"
|
||||
@ -89,7 +88,7 @@ func networked_spawn_tower(caller_id : int):
|
||||
|
||||
|
||||
@rpc("reliable", "call_local", "any_peer")
|
||||
func networked_remove_tower():
|
||||
func networked_remove_tower() -> void:
|
||||
tower.queue_free()
|
||||
tower = null
|
||||
minimap_icon.modulate = Color.GREEN
|
||||
|
@ -1,27 +1,27 @@
|
||||
extends Path3D
|
||||
class_name VisualizedPath
|
||||
class_name VisualizedPath extends Path3D
|
||||
|
||||
var visual_scene: PackedScene = preload("res://Scenes/path_visual_thing.tscn")
|
||||
var length: float = 0.0
|
||||
var visualizer_points: Array = []
|
||||
|
||||
var visual_scene = preload("res://Scenes/path_visual_thing.tscn")
|
||||
var length := 0.0
|
||||
var visualizer_points = []
|
||||
|
||||
func spawn_visualizer_points() -> void:
|
||||
var new_length = curve.get_baked_length()
|
||||
for x in floori(new_length) - visualizer_points.size():
|
||||
var point = visual_scene.instantiate()
|
||||
var new_length: float = curve.get_baked_length()
|
||||
for x: int in floori(new_length) - visualizer_points.size():
|
||||
var point: PathFollow3D = visual_scene.instantiate()
|
||||
visualizer_points.append(point)
|
||||
add_child(point)
|
||||
length = new_length
|
||||
#print(str(int(length)) + " / " + str(visualizer_points.size()) + ", diff: " + str(visualizer_points.size() - length))
|
||||
for x in visualizer_points.size():
|
||||
for x: int in visualizer_points.size():
|
||||
visualizer_points[x].progress_ratio = float(x) / visualizer_points.size()
|
||||
|
||||
|
||||
func disable_visualization():
|
||||
for x in visualizer_points:
|
||||
func disable_visualization() -> void:
|
||||
for x: PathFollow3D in visualizer_points:
|
||||
x.set_world_visible(false)
|
||||
|
||||
|
||||
func enable_visualization():
|
||||
for x in visualizer_points:
|
||||
func enable_visualization() -> void:
|
||||
for x: PathFollow3D in visualizer_points:
|
||||
x.set_world_visible(true)
|
||||
|
@ -1,21 +1,21 @@
|
||||
extends Node
|
||||
|
||||
|
||||
func calculate_spawn_power(wave_number : int, number_of_players : int) -> int:
|
||||
func calculate_spawn_power(wave_number: int, number_of_players: int) -> int:
|
||||
return 20 + (50 * number_of_players) + (30 * wave_number)
|
||||
|
||||
|
||||
func generate_wave(spawn_power : int, spawn_pool : Array[Enemy]) -> Dictionary:
|
||||
var wave = {}
|
||||
func generate_wave(spawn_power: int, spawn_pool: Array[Enemy]) -> Dictionary:
|
||||
var wave: Dictionary = {}
|
||||
#var sp_used = 0
|
||||
var enemy_types = randi_range(1, 5)
|
||||
var enemy_choices = spawn_pool.duplicate()
|
||||
var sp_allotment = floori(spawn_power / enemy_types)
|
||||
for x in enemy_types:
|
||||
var choice = enemy_choices.pick_random()
|
||||
var enemy_types: int = randi_range(1, 5)
|
||||
var enemy_choices: Array[Enemy] = spawn_pool.duplicate()
|
||||
var sp_allotment: int = floori(float(spawn_power) / float(enemy_types))
|
||||
for x: int in enemy_types:
|
||||
var choice: Enemy = enemy_choices.pick_random()
|
||||
enemy_choices.erase(choice)
|
||||
if sp_allotment / choice.spawn_power > 0:
|
||||
wave[Data.enemies.find(choice)] = sp_allotment / choice.spawn_power
|
||||
if floori(float(sp_allotment) / float(choice.spawn_power)) > 0:
|
||||
wave[Data.enemies.find(choice)] = floori(float(sp_allotment) / float(choice.spawn_power))
|
||||
#sp_used += wave[Data.enemies.find(choice)] * choice.spawn_power
|
||||
#print("Generated wave with spawn power: " + str(sp_used) + "/" + str(spawn_power))
|
||||
return wave
|
||||
|
@ -1,14 +1,22 @@
|
||||
extends Control
|
||||
class_name WonGameScreen extends Control
|
||||
|
||||
@export var box: PackedScene
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var wins = float(Data.save_stats.twenty_game_history.count(true))
|
||||
var games = float(Data.save_stats.twenty_game_history.size())
|
||||
var winrate = int((wins / games) * 100.0)
|
||||
var wins: int = Data.save_stats.twenty_game_history.count(true)
|
||||
var games: int = Data.save_stats.twenty_game_history.size()
|
||||
var winrate: int = int((float(wins) / float(games)) * 100.0)
|
||||
$Label2.text = "Your 20-game winrate is now: " + str(winrate) + "%!"
|
||||
$Label3.text = "Total games: " + str(Data.save_stats.wins + Data.save_stats.losses)
|
||||
$Label4.text = "Total wins: " + str(Data.save_stats.wins)
|
||||
$Label5.text = "Total losses: " + str(Data.save_stats.losses)
|
||||
for wave_key: int in Game.stats.enemies_undefeated:
|
||||
var spawned_box: EnemyBox = box.instantiate() as EnemyBox
|
||||
$VBoxContainer.add_child(spawned_box)
|
||||
spawned_box.set_wave(wave_key)
|
||||
for enemy_key: Enemy in Game.stats.enemies_undefeated[wave_key]:
|
||||
spawned_box.add_enemy_tag(enemy_key, Game.stats.enemies_undefeated[wave_key][enemy_key])
|
||||
|
||||
|
||||
func _on_quit_button_pressed() -> void:
|
||||
|
Reference in New Issue
Block a user