pathfinding rework for now
This commit is contained in:
@ -11,9 +11,9 @@ func apply_effect(effect: Effect, targets: Array[EnemyController]) -> void:
|
||||
if targets.has(enemy):
|
||||
enemy.apply_effect(effect)
|
||||
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
||||
spawn_damage_indicator(effect.damage, enemy.sprite.global_position)
|
||||
spawn_damage_indicator(effect.damage, enemy.d_n.global_position)
|
||||
else:
|
||||
for enemy: EnemyController in targets:
|
||||
enemy.apply_effect(effect)
|
||||
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
||||
spawn_damage_indicator(effect.damage, enemy.sprite.global_position)
|
||||
spawn_damage_indicator(effect.damage, enemy.d_n.global_position)
|
||||
|
@ -5,4 +5,4 @@ func apply_effect(effect: Effect, targets: Array[EnemyController]) -> void:
|
||||
for enemy: EnemyController in targets:
|
||||
enemy.apply_effect(effect)
|
||||
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
||||
spawn_damage_indicator(effect.damage, enemy.sprite.global_position)
|
||||
spawn_damage_indicator(effect.damage, enemy.d_n.global_position)
|
||||
|
@ -10,6 +10,7 @@ class_name LeapingController extends PathingController
|
||||
@export var souths: Sprite3D
|
||||
@export var box: CSGBox3D
|
||||
@export var tol: Label
|
||||
@export var jump_distance: float = 4.0
|
||||
|
||||
var tolerance: float = 50.0
|
||||
var jumping: bool = false
|
||||
@ -21,20 +22,19 @@ func _process(delta: float) -> void:
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if !path or jumping:
|
||||
if !next_node or jumping:
|
||||
return
|
||||
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: Transform3D = path.sample_baked_with_rotation(path_progress, true)
|
||||
character.global_position = sample.origin
|
||||
character.look_at(character.global_position + -sample.basis.z)
|
||||
var closest_point: int = astar.astar.get_closest_point(character.global_position, false)
|
||||
box.global_position = astar.astar.get_point_position(closest_point)
|
||||
var east: int = astar.get_east_point(closest_point)
|
||||
var west: int = astar.get_west_point(closest_point)
|
||||
var north: int = astar.get_north_point(closest_point)
|
||||
var south: int = astar.get_south_point(closest_point)
|
||||
walk(delta)
|
||||
consider_leap(Vector3.FORWARD)
|
||||
consider_leap(Vector3.LEFT)
|
||||
consider_leap(Vector3.BACK)
|
||||
consider_leap(Vector3.RIGHT)
|
||||
#var closest_point: int = astar.astar.get_closest_point(character.global_position, false)
|
||||
#box.global_position = astar.astar.get_point_position(closest_point)
|
||||
#var east: int = astar.get_east_point(closest_point)
|
||||
#var west: int = astar.get_west_point(closest_point)
|
||||
#var north: int = astar.get_north_point(closest_point)
|
||||
#var south: int = astar.get_south_point(closest_point)
|
||||
#if east >= 0 and astar.astar.is_point_disabled(east):
|
||||
#eastl.text = "fuck no"
|
||||
#else:
|
||||
@ -51,95 +51,117 @@ func _physics_process(delta: float) -> void:
|
||||
#southl.text = "fuck no"
|
||||
#else:
|
||||
#southl.text = "yeah"
|
||||
norths.global_position = character.global_position + Vector3(-1.0, 1.0, 0.0)
|
||||
souths.global_position = character.global_position + Vector3(1.0, 1.0, 0.0)
|
||||
easts.global_position = character.global_position + Vector3(0.0, 1.0, -1.0)
|
||||
wests.global_position = character.global_position + Vector3(0.0, 1.0, 1.0)
|
||||
if east >= 0:
|
||||
if astar.astar.is_point_disabled(east):
|
||||
var further_point: int = astar.get_east_point(east)
|
||||
if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||
var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(0.0, 0.0, -4.0))
|
||||
var current_offset: float = path.get_closest_offset(character.global_position)
|
||||
var gain: float = expected_offset - current_offset
|
||||
if gain >= tolerance:
|
||||
distance_remaining -= gain
|
||||
path_progress += gain
|
||||
leap(Vector3(0.0, 0.0, -4.0))
|
||||
eastl.text = str(gain)
|
||||
#easts.visible = true
|
||||
else:
|
||||
eastl.text = "cant"
|
||||
else:
|
||||
eastl.text = "clear"
|
||||
else:
|
||||
eastl.text = "invalid"
|
||||
if west >= 0:
|
||||
if astar.astar.is_point_disabled(west):
|
||||
var further_point: int = astar.get_west_point(west)
|
||||
if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||
var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(0.0, 0.0, 4.0))
|
||||
var current_offset: float = path.get_closest_offset(character.global_position)
|
||||
var gain: float = expected_offset - current_offset
|
||||
if gain >= tolerance:
|
||||
distance_remaining -= gain
|
||||
path_progress += gain
|
||||
leap(Vector3(0.0, 0.0, 4.0))
|
||||
westl.text = str(gain)
|
||||
#wests.visible = true
|
||||
else:
|
||||
westl.text = "cant"
|
||||
else:
|
||||
westl.text = "clear"
|
||||
else:
|
||||
westl.text = "invalid"
|
||||
if north >= 0:
|
||||
if astar.astar.is_point_disabled(north):
|
||||
var further_point: int = astar.get_north_point(north)
|
||||
if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||
var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(-4.0, 0.0, 0.0))
|
||||
var current_offset: float = path.get_closest_offset(character.global_position)
|
||||
var gain: float = expected_offset - current_offset
|
||||
if gain >= tolerance:
|
||||
distance_remaining -= gain
|
||||
path_progress += gain
|
||||
leap(Vector3(-4.0, 0.0, 0.0))
|
||||
northl.text = str(gain)
|
||||
#norths.visible = true
|
||||
else:
|
||||
northl.text = "cant"
|
||||
else:
|
||||
northl.text = "clear"
|
||||
else:
|
||||
northl.text = "invalid"
|
||||
if south >= 0:
|
||||
if astar.astar.is_point_disabled(south):
|
||||
var further_point: int = astar.get_south_point(south)
|
||||
if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||
var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(4.0, 0.0, 0.0))
|
||||
var current_offset: float = path.get_closest_offset(character.global_position)
|
||||
var gain: float = expected_offset - current_offset
|
||||
if gain >= tolerance:
|
||||
distance_remaining -= gain
|
||||
path_progress += gain
|
||||
leap(Vector3(4.0, 0.0, 0.0))
|
||||
southl.text = str(gain)
|
||||
#souths.visible = true
|
||||
else:
|
||||
southl.text = "cant"
|
||||
else:
|
||||
southl.text = "clear"
|
||||
else:
|
||||
southl.text = "invalid"
|
||||
#norths.global_position = character.global_position + Vector3(-1.0, 1.0, 0.0)
|
||||
#souths.global_position = character.global_position + Vector3(1.0, 1.0, 0.0)
|
||||
#easts.global_position = character.global_position + Vector3(0.0, 1.0, -1.0)
|
||||
#wests.global_position = character.global_position + Vector3(0.0, 1.0, 1.0)
|
||||
|
||||
|
||||
|
||||
#if east >= 0:
|
||||
#if astar.astar.is_point_disabled(east):
|
||||
#var further_point: int = astar.get_east_point(east)
|
||||
#if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||
#var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(0.0, 0.0, -4.0))
|
||||
#var current_offset: float = path.get_closest_offset(character.global_position)
|
||||
#var gain: float = expected_offset - current_offset
|
||||
#if gain >= tolerance:
|
||||
#distance_remaining -= gain
|
||||
##path_progress += gain
|
||||
#leap(Vector3(0.0, 0.0, -4.0))
|
||||
#eastl.text = str(gain)
|
||||
##easts.visible = true
|
||||
#else:
|
||||
#eastl.text = "cant"
|
||||
#else:
|
||||
#eastl.text = "clear"
|
||||
#else:
|
||||
#eastl.text = "invalid"
|
||||
#if west >= 0:
|
||||
#if astar.astar.is_point_disabled(west):
|
||||
#var further_point: int = astar.get_west_point(west)
|
||||
#if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||
#var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(0.0, 0.0, 4.0))
|
||||
#var current_offset: float = path.get_closest_offset(character.global_position)
|
||||
#var gain: float = expected_offset - current_offset
|
||||
#if gain >= tolerance:
|
||||
#distance_remaining -= gain
|
||||
##path_progress += gain
|
||||
#leap(Vector3(0.0, 0.0, 4.0))
|
||||
#westl.text = str(gain)
|
||||
##wests.visible = true
|
||||
#else:
|
||||
#westl.text = "cant"
|
||||
#else:
|
||||
#westl.text = "clear"
|
||||
#else:
|
||||
#westl.text = "invalid"
|
||||
#if north >= 0:
|
||||
#if astar.astar.is_point_disabled(north):
|
||||
#var further_point: int = astar.get_north_point(north)
|
||||
#if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||
#var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(-4.0, 0.0, 0.0))
|
||||
#var current_offset: float = path.get_closest_offset(character.global_position)
|
||||
#var gain: float = expected_offset - current_offset
|
||||
#if gain >= tolerance:
|
||||
#distance_remaining -= gain
|
||||
##path_progress += gain
|
||||
#leap(Vector3(-4.0, 0.0, 0.0))
|
||||
#northl.text = str(gain)
|
||||
##norths.visible = true
|
||||
#else:
|
||||
#northl.text = "cant"
|
||||
#else:
|
||||
#northl.text = "clear"
|
||||
#else:
|
||||
#northl.text = "invalid"
|
||||
#if south >= 0:
|
||||
#if astar.astar.is_point_disabled(south):
|
||||
#var further_point: int = astar.get_south_point(south)
|
||||
#if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||
#var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(4.0, 0.0, 0.0))
|
||||
#var current_offset: float = path.get_closest_offset(character.global_position)
|
||||
#var gain: float = expected_offset - current_offset
|
||||
#if gain >= tolerance:
|
||||
#distance_remaining -= gain
|
||||
##path_progress += gain
|
||||
#leap(Vector3(4.0, 0.0, 0.0))
|
||||
#southl.text = str(gain)
|
||||
##souths.visible = true
|
||||
#else:
|
||||
#southl.text = "cant"
|
||||
#else:
|
||||
#southl.text = "clear"
|
||||
#else:
|
||||
#southl.text = "invalid"
|
||||
|
||||
|
||||
func consider_leap(direction: Vector3) -> void:
|
||||
var node: FlowNode = check_jump(character.global_position + (direction * jump_distance))
|
||||
if node:
|
||||
var expected_distance_remaining: float = calculate_distance_to_goal(node)
|
||||
expected_distance_remaining += (character.global_position + (direction * jump_distance)).distance_to(node.global_position)
|
||||
var gain: float = distance_remaining - expected_distance_remaining
|
||||
if gain >= tolerance:
|
||||
distance_remaining -= gain
|
||||
leap(direction * jump_distance)
|
||||
next_node = node
|
||||
|
||||
|
||||
func finish_jump() -> void:
|
||||
jumping = false
|
||||
|
||||
|
||||
func check_jump(destination: Vector3) -> FlowNode:
|
||||
var closest_point: FlowNode = flow_field.get_closest_traversable_point(destination)
|
||||
if !closest_point.best_path or closest_point.global_position.distance_to(destination) > 1.2:
|
||||
return null
|
||||
return closest_point.best_path
|
||||
|
||||
|
||||
func leap(to_point: Vector3) -> void:
|
||||
jumping = true
|
||||
var tween: Tween = create_tween()
|
||||
tween.tween_property(character, "global_position", character.global_position + (to_point / 2.0) + Vector3.UP, 0.5)
|
||||
tween.tween_property(character, "global_position", character.global_position + to_point, 0.5)
|
||||
tween.tween_property(character, "global_position", character.global_position + (to_point / 2.0) + Vector3.UP, 0.3)
|
||||
tween.tween_property(character, "global_position", character.global_position + to_point, 0.3)
|
||||
tween.tween_callback(finish_jump)
|
||||
|
@ -1,21 +1,47 @@
|
||||
class_name PathingController extends EnemyMovement
|
||||
|
||||
var path: Curve3D
|
||||
var path_progress: float = 0.0
|
||||
#var path: Curve3D
|
||||
#var path_progress: float = 0.0
|
||||
var flow_field: FlowField
|
||||
var next_node: FlowNode
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if path:
|
||||
distance_remaining = path.get_baked_length()
|
||||
#if path:
|
||||
# distance_remaining = path.get_baked_length()
|
||||
next_node = flow_field.get_closest_traversable_point(character.global_position)
|
||||
distance_remaining += calculate_distance_to_goal(next_node)
|
||||
|
||||
|
||||
func calculate_distance_to_goal(node: FlowNode) -> float:
|
||||
var distance: float = 0.0
|
||||
distance += character.global_position.distance_to(node.global_position)
|
||||
if node.best_path:
|
||||
var then_next_node: FlowNode = node.best_path
|
||||
distance += node.global_position.distance_to(then_next_node.global_position)
|
||||
while then_next_node.best_path:
|
||||
distance += then_next_node.global_position.distance_to(then_next_node.best_path.global_position)
|
||||
then_next_node = then_next_node.best_path
|
||||
return distance
|
||||
|
||||
|
||||
func walk(delta: float) -> void:
|
||||
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.move_toward(next_node.global_position, distance_travelled)
|
||||
character.look_at(next_node.global_position)
|
||||
if character.global_position.distance_to(next_node.global_position) <= 0.05:
|
||||
next_node = next_node.best_path
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if !path:
|
||||
#if !path:
|
||||
# return
|
||||
if !next_node:
|
||||
return
|
||||
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: Transform3D = path.sample_baked_with_rotation(path_progress, true)
|
||||
character.global_position = sample.origin
|
||||
character.look_at(character.global_position + -sample.basis.z)
|
||||
var closest_point: Vector3 = path.get_closest_point(character.global_position)
|
||||
walk(delta)
|
||||
#path_progress += distance_travelled
|
||||
#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)
|
||||
#var closest_point: Vector3 = path.get_closest_point(character.global_position)
|
||||
|
@ -36,13 +36,13 @@ func hit(target: CharacterBody3D) -> void:
|
||||
target.apply_effect(effect)
|
||||
if owner_id == 0:
|
||||
if Data.preferences.display_tower_damage_indicators:
|
||||
spawn_damage_indicator(target.sprite.global_position)
|
||||
spawn_damage_indicator(target.d_n.global_position)
|
||||
if owner_id == multiplayer.get_unique_id():
|
||||
if Data.preferences.display_self_damage_indicators:
|
||||
spawn_damage_indicator(target.sprite.global_position)
|
||||
spawn_damage_indicator(target.d_n.global_position)
|
||||
if owner_id != 0 and owner_id != multiplayer.get_unique_id():
|
||||
if Data.preferences.display_party_damage_indicators:
|
||||
spawn_damage_indicator(target.sprite.global_position)
|
||||
spawn_damage_indicator(target.d_n.global_position)
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
|
@ -2,6 +2,7 @@ class_name Enemy extends Resource
|
||||
|
||||
@export var title: String = "dog"
|
||||
@export var target_type: Data.EnemyType
|
||||
@export var scene: PackedScene
|
||||
@export var icon: Texture
|
||||
@export var death_sprite: Texture
|
||||
@export var sprite: AtlasTexture
|
||||
|
@ -6,6 +6,11 @@ var save_slot: int = 0
|
||||
var twenty_game_history: Array[bool] = []
|
||||
var wins: int = 0
|
||||
var losses: int = 0
|
||||
var winrate: int :
|
||||
get():
|
||||
return int((float(twenty_game_history.count(true)) / float(twenty_game_history.size())) * 100.0)
|
||||
set(_value):
|
||||
return
|
||||
|
||||
#Engineer
|
||||
var engineer_cards_bought: int = 0
|
||||
|
@ -37,4 +37,4 @@ func networked_hit(target_path: String, target_hitbox_path: String) -> void:
|
||||
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)
|
||||
spawn_damage_indicator(target.d_n.global_position)
|
||||
|
@ -30,7 +30,7 @@ func shoot() -> void:
|
||||
if target_hitbox is Hitbox:
|
||||
hit(target, target_hitbox)
|
||||
if Data.preferences.display_self_damage_indicators:
|
||||
spawn_damage_indicator(target.sprite.global_position)
|
||||
spawn_damage_indicator(target.d_n.global_position)
|
||||
networked_hit.rpc(get_tree().root.get_path_to(target), get_tree().root.get_path_to(target_hitbox))
|
||||
|
||||
|
||||
@ -51,4 +51,4 @@ func networked_hit(target_path: String, target_hitbox_path: String) -> void:
|
||||
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)
|
||||
spawn_damage_indicator(target.d_n.global_position)
|
||||
|
@ -230,12 +230,13 @@ func find_path() -> bool:
|
||||
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)
|
||||
var point_position: Vector3 = Vector3((x - floori(grid_size.x / 2.0)) * point_gap, 0, (y - floori(grid_size.y / 2.0)) * point_gap)
|
||||
point_position += global_position
|
||||
astar.add_point(int(x * grid_size.y + y), point_position)
|
||||
var frame: Node3D = tower_frame_scene.instantiate()
|
||||
frame.position = point_position
|
||||
tower_frames.append(frame)
|
||||
add_child(frame)
|
||||
frame.global_position = point_position
|
||||
|
||||
for x: int in grid_size.x:
|
||||
for y: int in grid_size.y:
|
||||
|
@ -4,7 +4,7 @@ class_name CinematicCamManager extends Node3D
|
||||
@export var cameras: Array[Camera3D]
|
||||
@export var pan_speed: float = 1.0
|
||||
var current_cam: int = 0
|
||||
var does_its_thing: bool = true
|
||||
@export var does_its_thing: bool = true
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
@ -1,178 +0,0 @@
|
||||
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
|
||||
|
||||
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: 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 = Color.GREEN
|
||||
c.a = 0.8
|
||||
wall_preview.set_color(c)
|
||||
wall_preview.set_float(0.0)
|
||||
wall_preview.toggle_collision()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if !enabled:
|
||||
ray_collider = 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)
|
||||
last_collider = null
|
||||
return
|
||||
|
||||
if interact_key_held and !interacted_once and valid_point and hero.currency >= Data.wall_cost and ray.is_colliding() and Game.level.a_star_graph_3d.point_is_build_location(point_id):
|
||||
interact_held_time += delta
|
||||
set_progress_percent(interact_held_time / interact_hold_time)
|
||||
wall_preview.set_float(interact_held_time / interact_hold_time)
|
||||
if interact_held_time >= interact_hold_time:
|
||||
set_progress_percent(0)
|
||||
interacted_once = true
|
||||
build_wall()
|
||||
if interact_key_held and !interacted_once and last_collider and ray.is_colliding():
|
||||
interact_held_time += delta
|
||||
set_progress_percent(interact_held_time / interact_hold_time)
|
||||
if interact_held_time >= interact_hold_time:
|
||||
set_progress_percent(0)
|
||||
interacted_once = true
|
||||
refund_wall(last_collider)
|
||||
if !interact_key_held:
|
||||
interact_held_time = 0.0
|
||||
interacted_once = false
|
||||
set_progress_percent(0)
|
||||
wall_preview.set_float(0.0)
|
||||
|
||||
point_id = -1
|
||||
if !interacted_once and ray.is_colliding():
|
||||
if !interact_key_held:
|
||||
wall_preview.set_visible(true)
|
||||
ray_collider = ray.get_collider()
|
||||
ray_point = ray.get_collision_point()
|
||||
|
||||
is_looking_at_tower_base = ray_collider is TowerBase
|
||||
if is_looking_at_tower_base:
|
||||
valid_point = false
|
||||
point_id = ray_collider.point_id
|
||||
if obstacle_last_point != point_id:
|
||||
obstacle_last_point = point_id
|
||||
if is_instance_valid(last_collider):
|
||||
Game.level.a_star_graph_3d.tower_base_ids[last_collider.point_id].set_float(1.0)
|
||||
last_collider = null
|
||||
if tower_preview:
|
||||
delete_tower_preview()
|
||||
wall_preview.set_visible(false)
|
||||
last_collider = ray_collider
|
||||
ray_collider.set_color(Color.RED)
|
||||
ray_collider.set_float(0.0)
|
||||
if inventory.contents.size() > 0 and !ray_collider.has_card:
|
||||
if ray_collider != last_tower_base or inventory.selected_item != last_card:
|
||||
spawn_tower_preview()
|
||||
elif Game.level:
|
||||
if is_instance_valid(last_collider):
|
||||
Game.level.a_star_graph_3d.tower_base_ids[last_collider.point_id].set_float(1.0)
|
||||
last_collider = null
|
||||
if tower_preview:
|
||||
delete_tower_preview()
|
||||
point_id = Game.level.a_star_graph_3d.astar.get_closest_point(ray_point)
|
||||
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: 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 = Color.GREEN
|
||||
c.a = 0.8
|
||||
wall_preview.set_color(c)
|
||||
wall_preview.set_float(0.0)
|
||||
valid_point = true
|
||||
else:
|
||||
#build_preview_material.albedo_color = Color.RED
|
||||
#build_preview_material.albedo_color.a = 0.8
|
||||
valid_point = false
|
||||
else:
|
||||
ray_collider = null
|
||||
is_looking_at_tower_base = false
|
||||
delete_tower_preview()
|
||||
wall_preview.set_visible(false)
|
||||
if !valid_point:
|
||||
wall_preview.set_visible(false)
|
||||
|
||||
|
||||
func spawn_tower_preview() -> void:
|
||||
delete_tower_preview()
|
||||
last_tower_base = ray_collider
|
||||
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
|
||||
tower_preview.position = Vector3.UP
|
||||
tower_preview.preview_range(true)
|
||||
ray_collider.add_child(tower_preview)
|
||||
|
||||
|
||||
func delete_tower_preview() -> void:
|
||||
last_tower_base = null
|
||||
last_card = null
|
||||
if is_instance_valid(tower_preview):
|
||||
tower_preview.queue_free()
|
||||
tower_preview = null
|
||||
|
||||
|
||||
func interact() -> void:
|
||||
if ray_collider is TowerBase:
|
||||
var tower_base: TowerBase = ray_collider as TowerBase
|
||||
put_card_in_tower_base(tower_base)
|
||||
|
||||
|
||||
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) -> void:
|
||||
if !is_instance_valid(wall):
|
||||
return
|
||||
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) -> void:
|
||||
if tower_base.has_card:
|
||||
tower_base.remove_card()
|
||||
elif inventory.size > 0:
|
||||
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())
|
||||
hero.place_card_audio.play()
|
||||
|
||||
|
||||
func set_progress_percent(value: float) -> void:
|
||||
progress_bar.value = progress_bar.max_value * value
|
@ -1 +0,0 @@
|
||||
uid://ckm02cx0ai624
|
@ -7,6 +7,7 @@ signal enemy_spawned()
|
||||
@export var air_enemy_scene: PackedScene
|
||||
@export var path: VisualizedPath
|
||||
var astar: AStarGraph3D
|
||||
@export var flow_field: FlowField
|
||||
@export var own_id: int = 0
|
||||
@export var type: Data.EnemyType
|
||||
@export var dest: Node3D
|
||||
@ -22,6 +23,12 @@ var enemies_spawned: Dictionary = {}
|
||||
var enemies_to_spawn: int = 0
|
||||
var done_spawning: bool = true
|
||||
var enemy_id: int = 0
|
||||
var new_path: Path3D
|
||||
var path_polygon: PackedScene = preload("res://path_polygon.tscn")
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
create_path()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
@ -29,56 +36,88 @@ func _process(delta: float) -> void:
|
||||
done_spawning = true
|
||||
return
|
||||
|
||||
for x: Enemy in enemy_spawn_timers:
|
||||
if enemies_spawned[x] == enemy_types_to_spawn[x]:
|
||||
for enemy: Enemy in enemy_spawn_timers:
|
||||
if enemies_spawned[enemy] == enemy_types_to_spawn[enemy]:
|
||||
continue
|
||||
|
||||
var enemy_stats: Enemy = x
|
||||
enemy_spawn_timers[x] += delta
|
||||
enemy_spawn_timers[enemy] += delta
|
||||
|
||||
if enemy_spawn_timers[x] >= enemy_stats.spawn_cooldown:
|
||||
if enemy_spawn_timers[enemy] >= enemy.spawn_cooldown:
|
||||
if is_multiplayer_authority():
|
||||
if type == Data.EnemyType.LAND:
|
||||
networked_spawn_land_enemy.rpc(Data.enemies.find(enemy_stats), own_id, enemy_id)
|
||||
networked_spawn_land_enemy.rpc(enemy.title, own_id, enemy_id)
|
||||
if type == Data.EnemyType.AIR:
|
||||
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(Data.enemies.find(enemy_stats), random_pos, own_id, enemy_id)
|
||||
networked_spawn_air_enemy.rpc(enemy.title, random_pos, own_id, enemy_id)
|
||||
|
||||
enemy_spawn_timers[x] -= enemy_stats.spawn_cooldown
|
||||
enemy_spawn_timers[enemy] -= enemy.spawn_cooldown
|
||||
enemy_spawned.emit()
|
||||
enemy_id += 1
|
||||
enemies_spawned[x] += 1
|
||||
enemies_spawned[enemy] += 1
|
||||
enemies_to_spawn -= 1
|
||||
|
||||
|
||||
#TODO: not sure enemies need all this info over the network
|
||||
#TODO: generalize enemy scene selection, i.e. store the scenes in the enemy
|
||||
#card like towers do
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_land_enemy(enemy_stats: int, id1: int, id2: int) -> void:
|
||||
func networked_spawn_land_enemy(enemy_stats: String, id1: int, id2: int) -> void:
|
||||
var e_stats: Enemy = null
|
||||
for enemy: Enemy in Data.enemies:
|
||||
if enemy.title == enemy_stats:
|
||||
e_stats = enemy
|
||||
var enemy: EnemyController
|
||||
if enemy_stats != 6:
|
||||
enemy = land_enemy_scene.instantiate() as EnemyController
|
||||
else:
|
||||
enemy = leap_enemy_scene.instantiate() as EnemyController
|
||||
enemy = e_stats.scene.instantiate()
|
||||
enemy.name = str(id1) + str(id2)
|
||||
enemy.stats = Data.enemies[enemy_stats]
|
||||
enemy.stats = e_stats
|
||||
enemy.died.connect(enemy_died_callback)
|
||||
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
||||
enemy.movement_controller.path = path.curve
|
||||
enemy.movement_controller.astar = astar
|
||||
#enemy.movement_controller.path = path.curve
|
||||
#enemy.movement_controller.astar = astar
|
||||
enemy.movement_controller.flow_field = flow_field
|
||||
enemy.position = global_position
|
||||
enemy_path.add_child(enemy)
|
||||
|
||||
|
||||
func create_path() -> void:
|
||||
if type != Data.EnemyType.LAND:
|
||||
return
|
||||
new_path = Path3D.new()
|
||||
new_path.curve = Curve3D.new()
|
||||
add_child(new_path)
|
||||
var polygon: CSGPolygon3D = path_polygon.instantiate()
|
||||
new_path.add_child(polygon)
|
||||
polygon.mode = CSGPolygon3D.MODE_PATH
|
||||
polygon.path_node = new_path.get_path()
|
||||
new_path.global_position = Vector3.ZERO
|
||||
update_path()
|
||||
|
||||
|
||||
|
||||
func update_path() -> void:
|
||||
if type != Data.EnemyType.LAND:
|
||||
return
|
||||
new_path.curve.add_point(global_position + Vector3(0, 0.5, 0))
|
||||
new_path.curve = Curve3D.new()
|
||||
var node: FlowNode = flow_field.get_closest_traversable_point(global_position)
|
||||
new_path.curve.add_point(node.global_position + Vector3(0, 0.5, 0))
|
||||
while node.best_path:
|
||||
node = node.best_path
|
||||
new_path.curve.add_point(node.global_position + Vector3(0, 0.5, 0))
|
||||
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_air_enemy(enemy_stats: int, pos: Vector3, id1: int, id2: int) -> void:
|
||||
var enemy: EnemyController = air_enemy_scene.instantiate() as EnemyController
|
||||
func networked_spawn_air_enemy(enemy_stats: String, pos: Vector3, id1: int, id2: int) -> void:
|
||||
var e_stats: Enemy = null
|
||||
for enemy: Enemy in Data.enemies:
|
||||
if enemy.title == enemy_stats:
|
||||
e_stats = enemy
|
||||
var enemy: EnemyController
|
||||
enemy = e_stats.scene.instantiate()
|
||||
enemy.name = str(id1) + str(id2)
|
||||
enemy.position = pos + global_position
|
||||
enemy.stats = Data.enemies[enemy_stats]
|
||||
enemy.stats = e_stats
|
||||
enemy.died.connect(enemy_died_callback)
|
||||
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
||||
enemy.movement_controller.goal = dest
|
||||
|
155
Scripts/flow_field_tool.gd
Normal file
155
Scripts/flow_field_tool.gd
Normal file
@ -0,0 +1,155 @@
|
||||
class_name FlowFieldTool extends Node
|
||||
|
||||
@export var flow_field: FlowField
|
||||
@export var raycast: RayCast3D
|
||||
@export var project_raycast: RayCast3D
|
||||
@export var camera: Camera3D
|
||||
@export var camera_pivot: Node3D
|
||||
@export var position_field: HBoxContainer
|
||||
@export var x_field: LineEdit
|
||||
@export var y_field: LineEdit
|
||||
@export var z_field: LineEdit
|
||||
@export var x_size_field: LineEdit
|
||||
@export var y_size_field: LineEdit
|
||||
@export var gap_field: LineEdit
|
||||
|
||||
var hover: FlowNode = null
|
||||
var selected: Array[FlowNode] = []
|
||||
var vector_dirty: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
camera.make_current()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if raycast.is_colliding() and (!hover or hover != raycast.get_collider()):
|
||||
hover = raycast.get_collider()
|
||||
if hover and !raycast.is_colliding():
|
||||
hover = null
|
||||
if selected.size() == 1 and vector_dirty:
|
||||
position_field.visible = true
|
||||
x_field.text = str(selected[0].global_position.x)
|
||||
y_field.text = str(selected[0].global_position.y)
|
||||
z_field.text = str(selected[0].global_position.z)
|
||||
vector_dirty = false
|
||||
elif selected.size() != 1:
|
||||
position_field.visible = false
|
||||
|
||||
for node: FlowNode in flow_field.nodes:
|
||||
if node.traversable and node.buildable:
|
||||
node.set_color(Color.WEB_GRAY)
|
||||
elif node.traversable and !node.buildable:
|
||||
node.set_color(Color.CORAL)
|
||||
else:
|
||||
node.set_color(Color.BLACK)
|
||||
if flow_field.goals.has(node):
|
||||
node.set_color(Color.BLUE)
|
||||
if flow_field.starts.has(node):
|
||||
node.set_color(Color.PINK)
|
||||
if selected.has(node):
|
||||
node.set_color(Color.GREEN)
|
||||
if node == hover:
|
||||
node.set_color(Color.RED)
|
||||
|
||||
var y: float = Input.get_axis("Move Forward", "Move Backward")
|
||||
var x: float = Input.get_axis("Move Left", "Move Right")
|
||||
camera_pivot.position += Vector3(x, 0, y) * delta * 10
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseMotion:
|
||||
var from: Vector3 = camera.project_ray_origin(event.position)
|
||||
var to: Vector3 = camera.project_local_ray_normal(event.position)
|
||||
raycast.global_position = from
|
||||
raycast.target_position = to * 1000.0
|
||||
if event is InputEventMouseButton and event.button_index == 1 and hover:
|
||||
if !selected.has(hover):
|
||||
selected.append(hover)
|
||||
vector_dirty = true
|
||||
if event is InputEventMouseButton and event.button_index == 2 and selected.size() > 0:
|
||||
selected = []
|
||||
|
||||
|
||||
func _on_x_field_changed(text: String) -> void:
|
||||
selected[0].global_position.x = float(text)
|
||||
|
||||
|
||||
func _on_y_field_changed(text: String) -> void:
|
||||
selected[0].global_position.y = float(text)
|
||||
|
||||
|
||||
func _on_z_field_changed(text: String) -> void:
|
||||
selected[0].global_position.z = float(text)
|
||||
|
||||
|
||||
func _on_create_button_pressed() -> void:
|
||||
flow_field.create_node()
|
||||
|
||||
|
||||
func _on_generate_grid_button_pressed() -> void:
|
||||
flow_field.create_grid(int(x_size_field.text), int(y_size_field.text), float(gap_field.text))
|
||||
selected.append_array(flow_field.nodes)
|
||||
|
||||
|
||||
func _on_calculate_button_pressed() -> void:
|
||||
flow_field.calculate()
|
||||
|
||||
|
||||
func _on_connect_button_pressed() -> void:
|
||||
flow_field.connect_many_nodes(selected[0], selected.slice(1, selected.size()))
|
||||
|
||||
|
||||
func _on_mark_goal_button_pressed() -> void:
|
||||
flow_field.toggle_goal(selected)
|
||||
selected = []
|
||||
vector_dirty = true
|
||||
|
||||
|
||||
func _on_mark_start_button_pressed() -> void:
|
||||
flow_field.toggle_start(selected)
|
||||
selected = []
|
||||
vector_dirty = true
|
||||
|
||||
|
||||
func _on_extrude_button_pressed() -> void:
|
||||
if selected.size() == 1:
|
||||
var node: FlowNode = flow_field.create_node(selected[0].position)
|
||||
node.add_connection(selected[0])
|
||||
selected[0].add_connection(node)
|
||||
selected[0].set_color(Color.WEB_GRAY)
|
||||
selected = []
|
||||
selected.append(node)
|
||||
vector_dirty = true
|
||||
|
||||
|
||||
func _on_toggle_traversable_button_pressed() -> void:
|
||||
for node: FlowNode in selected:
|
||||
if !flow_field.toggle_traversable(node):
|
||||
flow_field.toggle_traversable(node)
|
||||
selected = []
|
||||
return
|
||||
selected = []
|
||||
|
||||
|
||||
func _on_toggle_buildable_button_pressed() -> void:
|
||||
for node: FlowNode in selected:
|
||||
flow_field.toggle_buildable(node)
|
||||
|
||||
|
||||
func _on_finalize_button_pressed() -> void:
|
||||
var packed_scene: PackedScene = PackedScene.new()
|
||||
packed_scene.pack(flow_field)
|
||||
ResourceSaver.save(packed_scene, "res://flow_field_tool_output.tscn")
|
||||
|
||||
#TODO: This doesnt work as you'd expect because of physics frames
|
||||
func _on_project_downwards_button_pressed() -> void:
|
||||
for node: FlowNode in selected:
|
||||
project_raycast.global_position = node.global_position + Vector3.UP
|
||||
project_raycast.target_position = Vector3.DOWN * 100.0
|
||||
await get_tree().physics_frame
|
||||
await get_tree().physics_frame
|
||||
await get_tree().physics_frame
|
||||
await get_tree().physics_frame
|
||||
if project_raycast.is_colliding():
|
||||
node.global_position = project_raycast.get_collision_point()
|
1
Scripts/flow_field_tool.gd.uid
Normal file
1
Scripts/flow_field_tool.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://05c5q1v2nv8p
|
@ -1,8 +1,10 @@
|
||||
class_name FlowNode extends StaticBody3D
|
||||
|
||||
var connections: Array[FlowNode]
|
||||
var visualisers: Array[CSGBox3D]
|
||||
var traversable: bool = true
|
||||
@export var connections: Array[FlowNode]
|
||||
@export var visualisers: Array[Node3D]
|
||||
var visual_scene: PackedScene = preload("res://cube2.tscn")
|
||||
@export var traversable: bool = true
|
||||
@export var buildable: bool = true
|
||||
var best_path: FlowNode :
|
||||
get():
|
||||
return best_path
|
||||
@ -12,33 +14,44 @@ var best_path: FlowNode :
|
||||
set_connector_color(best_path, Color.DARK_GREEN)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
visualisers = []
|
||||
for node: FlowNode in connections:
|
||||
var visual: Node3D = visual_scene.instantiate()
|
||||
add_child(visual)
|
||||
visual.owner = self
|
||||
visualisers.append(visual)
|
||||
set_connector_color(node, Color.WEB_GRAY)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
for i: int in connections.size():
|
||||
var distance: float = global_position.distance_to(connections[i].global_position)
|
||||
visualisers[i].size = Vector3(0.3, 0.3, 1.0 * (distance / 2.0))
|
||||
visualisers[i].position = to_local(connections[i].global_position) / 4.0
|
||||
if distance >= 0.05:
|
||||
visualisers[i].look_at(connections[i].global_position)
|
||||
if visible:
|
||||
for i: int in connections.size():
|
||||
var distance: float = global_position.distance_to(connections[i].global_position)
|
||||
visualisers[i].scale = Vector3(0.3, 0.3, 1.0 * (distance / 2.0))
|
||||
visualisers[i].position = to_local(connections[i].global_position) / 4.0
|
||||
if distance >= 0.05:
|
||||
visualisers[i].look_at(connections[i].global_position)
|
||||
|
||||
|
||||
func set_color(new_color: Color) -> void:
|
||||
$CSGSphere3D.material.albedo_color = new_color
|
||||
$flow_node/Sphere.material_override.albedo_color = new_color
|
||||
|
||||
|
||||
func set_connector_color(node: FlowNode, new_color: Color) -> void:
|
||||
var i: int = connections.find(node)
|
||||
visualisers[i].material.albedo_color = new_color
|
||||
if visible:
|
||||
var i: int = connections.find(node)
|
||||
visualisers[i].get_child(0).material_override.albedo_color = new_color
|
||||
|
||||
|
||||
func add_connection(node: FlowNode) -> void:
|
||||
if !connections.has(node):
|
||||
var visual: CSGBox3D = CSGBox3D.new()
|
||||
visual.material = StandardMaterial3D.new()
|
||||
visual.material.resource_local_to_scene = true
|
||||
visual.material.albedo_color = Color.DARK_GRAY
|
||||
var visual: Node3D = visual_scene.instantiate()
|
||||
add_child(visual)
|
||||
visual.owner = self
|
||||
connections.append(node)
|
||||
visualisers.append(visual)
|
||||
set_connector_color(node, Color.WEB_GRAY)
|
||||
|
||||
|
||||
func remove_connection(node: FlowNode) -> void:
|
||||
|
@ -39,6 +39,17 @@ func _ready() -> void:
|
||||
UILayer = CanvasLayer.new()
|
||||
UILayer.layer = 2
|
||||
get_tree().root.add_child.call_deferred(UILayer)
|
||||
var version_label: Label = Label.new()
|
||||
var version: String = ProjectSettings.get_setting("application/config/version")
|
||||
version_label.text = "WORK IN PROGRESS | ALPHA - VERSION " + version + " | PLAYTEST"
|
||||
version_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
version_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
version_label.add_theme_font_size_override("font_size", 18)
|
||||
version_label.add_theme_color_override("font_color", Color(0.85, 0.85, 0.85, 0.7))
|
||||
version_label.set_anchors_preset(Control.PRESET_TOP_WIDE)
|
||||
UILayer.add_child(version_label)
|
||||
Input.set_custom_mouse_cursor(load("res://Assets/Textures/cursor_none.png"), Input.CURSOR_ARROW, Vector2(9, 6))
|
||||
Input.set_custom_mouse_cursor(load("res://Assets/Textures/bracket_b_vertical.png"), Input.CURSOR_IBEAM, Vector2(16, 16))
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
@ -169,10 +180,12 @@ func ready_player(player_ready_true: bool) -> void:
|
||||
func spawn_enemy_wave() -> void:
|
||||
level.shop.close()
|
||||
wave += 1
|
||||
level.a_star_graph_3d.find_path()
|
||||
level.a_star_graph_3d.disable_all_tower_frames()
|
||||
level.disable_all_tower_frames()
|
||||
#level.a_star_graph_3d.find_path()
|
||||
#level.a_star_graph_3d.disable_all_tower_frames()
|
||||
level.flow_field.calculate()
|
||||
for spawn: EnemySpawner in level.enemy_spawns:
|
||||
spawn.path.disable_visualization()
|
||||
#spawn.path.disable_visualization()
|
||||
spawn.spawn_wave()
|
||||
wave_started.emit(wave)
|
||||
|
||||
@ -248,7 +261,7 @@ func end_wave() -> void:
|
||||
connected_players_nodes[peer_id].unready_self()
|
||||
for spawn: EnemySpawner in level.enemy_spawns:
|
||||
spawn.path.enable_visualization()
|
||||
level.a_star_graph_3d.enable_non_path_tower_frames()
|
||||
#level.a_star_graph_3d.enable_non_path_tower_frames()
|
||||
if is_multiplayer_authority():
|
||||
if randf_in_range(23 * wave, 0.0, 1.0) <= shop_chance:
|
||||
networked_spawn_shop.rpc()
|
||||
@ -304,11 +317,14 @@ func start() -> void:
|
||||
|
||||
#Relies on rng having been seeded
|
||||
set_upcoming_wave()
|
||||
level.a_star_graph_3d.make_grid()
|
||||
level.flow_field.calculate()
|
||||
level.enemy_spawns[0].update_path()
|
||||
#level.a_star_graph_3d.make_grid()
|
||||
level.generate_obstacles()
|
||||
level.a_star_graph_3d.disable_all_tower_frames()
|
||||
level.a_star_graph_3d.enable_non_path_tower_frames()
|
||||
level.a_star_graph_3d.find_path()
|
||||
level.enable_non_path_tower_frames()
|
||||
#level.a_star_graph_3d.disable_all_tower_frames()
|
||||
#level.a_star_graph_3d.enable_non_path_tower_frames()z
|
||||
#level.a_star_graph_3d.find_path()
|
||||
|
||||
#Start game
|
||||
game_active = true
|
||||
|
@ -1,157 +0,0 @@
|
||||
class_name KeyIconMap
|
||||
|
||||
|
||||
static var playstation_keys: Dictionary = {
|
||||
"0" = "res://KennyControllerPrompts/Playstation/playstation_button_color_cross.png",
|
||||
"1" = "res://KennyControllerPrompts/Playstation/playstation_button_color_circle.png",
|
||||
"2" = "res://KennyControllerPrompts/Playstation/playstation_button_color_square.png",
|
||||
"3" = "res://KennyControllerPrompts/Playstation/playstation_button_color_triangle.png",
|
||||
"4" = "res://KennyControllerPrompts/Playstation/playstation5_button_create.png",
|
||||
"6" = "res://KennyControllerPrompts/Playstation/playstation5_button_options.png",
|
||||
"7" = "res://KennyControllerPrompts/Playstation/playstation_stick_side_l.png",
|
||||
"8" = "res://KennyControllerPrompts/Playstation/playstation_stick_side_r.png",
|
||||
"9" = "res://KennyControllerPrompts/Playstation/playstation_trigger_l1_alternative.png",
|
||||
"10" = "res://KennyControllerPrompts/Playstation/playstation_trigger_r1_alternative.png",
|
||||
"11" = "res://KennyControllerPrompts/Playstation/playstation_dpad_up.png",
|
||||
"12" = "res://KennyControllerPrompts/Playstation/playstation_dpad_down.png",
|
||||
"13" = "res://KennyControllerPrompts/Playstation/playstation_dpad_left.png",
|
||||
"14" = "res://KennyControllerPrompts/Playstation/playstation_dpad_right.png",
|
||||
"15" = "res://KennyControllerPrompts/Playstation/playstation5_button_mute.png",
|
||||
}
|
||||
|
||||
|
||||
static var xbox_series_keys: Dictionary = {
|
||||
"0" = "res://KennyControllerPrompts/Xbox/xbox_button_a_outline.png",
|
||||
"1" = "res://KennyControllerPrompts/Xbox/xbox_button_b_outline.png",
|
||||
"2" = "res://KennyControllerPrompts/Xbox/xbox_button_x_outline.png",
|
||||
"3" = "res://KennyControllerPrompts/Xbox/xbox_button_y_outline.png",
|
||||
"4" = "res://KennyControllerPrompts/Xbox/xbox_button_view_outline.png",
|
||||
"5" = "res://KennyControllerPrompts/Xbox/xbox_guide.png",
|
||||
"6" = "res://KennyControllerPrompts/Xbox/xbox_button_menu_outline.png",
|
||||
"7" = "res://KennyControllerPrompts/Xbox/xbox_stick_side_l.png",
|
||||
"8" = "res://KennyControllerPrompts/Xbox/xbox_stick_side_r.png",
|
||||
"9" = "res://KennyControllerPrompts/Xbox/xbox_lb_outline.png",
|
||||
"10" = "res://KennyControllerPrompts/Xbox/xbox_rb_outline.png",
|
||||
"11" = "res://KennyControllerPrompts/Xbox/xbox_dpad_up_outline.png",
|
||||
"12" = "res://KennyControllerPrompts/Xbox/xbox_dpad_down_outline.png",
|
||||
"13" = "res://KennyControllerPrompts/Xbox/xbox_dpad_left_outline.png",
|
||||
"14" = "res://KennyControllerPrompts/Xbox/xbox_dpad_right_outline.png",
|
||||
"15" = "res://KennyControllerPrompts/Xbox/xbox_button_share_outline.png",
|
||||
}
|
||||
|
||||
|
||||
static var xbox_360_keys: Dictionary = {
|
||||
"0" = "res://KennyControllerPrompts/Xbox/xbox_button_color_a.png",
|
||||
"1" = "res://KennyControllerPrompts/Xbox/xbox_button_color_b.png",
|
||||
"2" = "res://KennyControllerPrompts/Xbox/xbox_button_color_x.png",
|
||||
"3" = "res://KennyControllerPrompts/Xbox/xbox_button_color_y.png",
|
||||
"4" = "res://KennyControllerPrompts/Xbox/xbox_button_back.png",
|
||||
"5" = "res://KennyControllerPrompts/Xbox/xbox_guide_outline.png",
|
||||
"6" = "res://KennyControllerPrompts/Xbox/xbox_button_start.png",
|
||||
"7" = "res://KennyControllerPrompts/Xbox/xbox_stick_side_l.png",
|
||||
"8" = "res://KennyControllerPrompts/Xbox/xbox_stick_side_r.png",
|
||||
"9" = "res://KennyControllerPrompts/Xbox/xbox_lb.png",
|
||||
"10" = "res://KennyControllerPrompts/Xbox/xbox_rb.png",
|
||||
"11" = "res://KennyControllerPrompts/Xbox/xbox_dpad_round_up.png",
|
||||
"12" = "res://KennyControllerPrompts/Xbox/xbox_dpad_round_down.png",
|
||||
"13" = "res://KennyControllerPrompts/Xbox/xbox_dpad_round_left.png",
|
||||
"14" = "res://KennyControllerPrompts/Xbox/xbox_dpad_round_right.png",
|
||||
}
|
||||
|
||||
|
||||
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://KennyControllerPrompts/Mouse/mouse_left.png",
|
||||
"3" = "res://KennyControllerPrompts/Mouse/mouse_scroll.png",
|
||||
"2" = "res://KennyControllerPrompts/Mouse/mouse_right.png",
|
||||
"4" = "res://KennyControllerPrompts/Mouse/mouse_scroll_up.png",
|
||||
"5" = "res://KennyControllerPrompts/Mouse/mouse_scroll_down.png",
|
||||
}
|
@ -1 +0,0 @@
|
||||
uid://nambgchluofc
|
133
Scripts/level.gd
133
Scripts/level.gd
@ -1,55 +1,120 @@
|
||||
class_name Level extends GridMap
|
||||
|
||||
@export var enemy_pool: Array[Enemy]
|
||||
@export var tower_path: Node
|
||||
@export var player_spawns: Array[Node3D]
|
||||
@export var enemy_spawns: Array[EnemySpawner]
|
||||
@export var enemy_goals: Array[Node3D]
|
||||
@export var corpses: Node3D
|
||||
@export var a_star_graph_3d: AStarGraph3D
|
||||
@export var flow_field: FlowField
|
||||
@export var cinematic_cam: CinematicCamManager
|
||||
@export var printer: CardPrinter
|
||||
@export var shop: ShopStand
|
||||
@export var obstacle_scenes: Array[PackedScene]
|
||||
var walls: Dictionary[FlowNode, TowerBase] = {}
|
||||
var wall_id: int = 0
|
||||
var tower_base_scene: PackedScene = load("res://Scenes/TowerBase/tower_base.tscn")
|
||||
var tower_frame_scene: PackedScene = load("res://Scenes/tower_frame.tscn")
|
||||
var tower_frames: Dictionary[FlowNode, Node3D] = {}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
flow_field.path_updated.connect(enemy_spawns[0].update_path)
|
||||
for node: FlowNode in flow_field.nodes:
|
||||
if node.buildable:
|
||||
var frame: Node3D = tower_frame_scene.instantiate()
|
||||
tower_frames[node] = frame
|
||||
add_child(frame)
|
||||
frame.global_position = node.global_position
|
||||
|
||||
|
||||
func disable_all_tower_frames() -> void:
|
||||
for node: FlowNode in tower_frames:
|
||||
tower_frames[node].visible = false
|
||||
|
||||
|
||||
func enable_non_path_tower_frames() -> void:
|
||||
for node: FlowNode in tower_frames:
|
||||
tower_frames[node].visible = true
|
||||
disable_path_tower_frames()
|
||||
|
||||
|
||||
func disable_path_tower_frames() -> void:
|
||||
for node: FlowNode in tower_frames:
|
||||
if !node.traversable and flow_field.traversable_after_blocking_point(node):
|
||||
tower_frames[node].visible = true
|
||||
|
||||
|
||||
func set_wall(point: FlowNode, caller_id: int) -> void:
|
||||
point.traversable = false
|
||||
flow_field.calculate()
|
||||
flow_field.path_updated.emit()
|
||||
if is_multiplayer_authority():
|
||||
spawn_wall(point, wall_id, caller_id)
|
||||
wall_id += 1
|
||||
|
||||
|
||||
func remove_wall(point: FlowNode) -> void:
|
||||
var wall: TowerBase = walls[point]
|
||||
Game.connected_players_nodes[wall.owner_id].currency += Data.wall_cost
|
||||
Game.connected_players_nodes[wall.owner_id].unready_self()
|
||||
walls.erase(point)
|
||||
wall.queue_free()
|
||||
point.traversable = true
|
||||
flow_field.calculate()
|
||||
flow_field.path_updated.emit()
|
||||
enable_non_path_tower_frames()
|
||||
|
||||
|
||||
func spawn_wall(point: FlowNode, name_id: int, caller_id: int) -> void:
|
||||
var base: TowerBase = tower_base_scene.instantiate() as TowerBase
|
||||
base.position = point.global_position
|
||||
base.name = "Wall" + str(name_id)
|
||||
base.owner_id = caller_id
|
||||
base.point = point
|
||||
walls[point] = base
|
||||
tower_path.add_child(base)
|
||||
disable_path_tower_frames()
|
||||
|
||||
|
||||
func generate_obstacles() -> void:
|
||||
#print(str(multiplayer.get_unique_id()) + " spawning obstacles with seed: " + str(Game.rng.seed))
|
||||
var obstacle_count: int = Game.randi_in_range(1, 0, 5)
|
||||
obstacle_count = 0
|
||||
for index: int in obstacle_count:
|
||||
var x: int = Game.randi_in_range(10 * index, 1 - a_star_graph_3d.grid_size.x, a_star_graph_3d.grid_size.x - 1)
|
||||
var y: int = Game.randi_in_range(32 * index, 1 - a_star_graph_3d.grid_size.y, a_star_graph_3d.grid_size.y - 1)
|
||||
var chosen_obstacle: int = Game.randi_in_range(4 * index, 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 = Game.randi_in_range(15 * index, 0, orientations.size() - 1)
|
||||
obstacle.position = Vector3(x, 0, y)
|
||||
obstacle.set_rotation_degrees(Vector3(0, chosen_orientation, 0))
|
||||
add_child(obstacle)
|
||||
for cell: Vector3i in obstacle.get_used_cells():
|
||||
var cell_coord: Vector3 = obstacle.to_global(obstacle.map_to_local(cell))
|
||||
remove_world_tile(round(cell_coord.x), round(cell_coord.z))
|
||||
obstacle.queue_free()
|
||||
# for index: int in obstacle_count:
|
||||
# #var x: int = Game.randi_in_range(10 * index, 1 - a_star_graph_3d.grid_size.x, a_star_graph_3d.grid_size.x - 1)
|
||||
#var y: int = Game.randi_in_range(32 * index, 1 - a_star_graph_3d.grid_size.y, a_star_graph_3d.grid_size.y - 1)
|
||||
# var chosen_obstacle: int = Game.randi_in_range(4 * index, 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 = Game.randi_in_range(15 * index, 0, orientations.size() - 1)
|
||||
# #obstacle.position = Vector3(x, 0, y)
|
||||
# obstacle.set_rotation_degrees(Vector3(0, chosen_orientation, 0))
|
||||
# add_child(obstacle)
|
||||
# for cell: Vector3i in obstacle.get_used_cells():
|
||||
# var cell_coord: Vector3 = obstacle.to_global(obstacle.map_to_local(cell))
|
||||
# remove_world_tile(round(cell_coord.x), round(cell_coord.z))
|
||||
# obstacle.queue_free()
|
||||
|
||||
|
||||
func cell_coord_to_astar_point(x: int, y: int) -> int:
|
||||
var center_point_x: int = floori(a_star_graph_3d.grid_size.x / 2.0) * a_star_graph_3d.grid_size.y
|
||||
var center_point_y: int = floori(a_star_graph_3d.grid_size.y / 2.0)
|
||||
return (center_point_x + (int(x / 2.0) * a_star_graph_3d.grid_size.y)) + (center_point_y + int(y / 2.0))
|
||||
#func cell_coord_to_astar_point(x: int, y: int) -> int:
|
||||
# var center_point_x: int = floori(a_star_graph_3d.grid_size.x / 2.0) * a_star_graph_3d.grid_size.y
|
||||
# var center_point_y: int = floori(a_star_graph_3d.grid_size.y / 2.0)
|
||||
# return (center_point_x + (int(x / 2.0) * a_star_graph_3d.grid_size.y)) + (center_point_y + int(y / 2.0))
|
||||
|
||||
|
||||
func remove_world_tile(x: int, y: int) -> void:
|
||||
if get_cell_item(Vector3i(x, 0, y)) != 1 or abs(x) >= a_star_graph_3d.grid_size.x or abs(y) >= a_star_graph_3d.grid_size.y:
|
||||
return
|
||||
set_cell_item(Vector3i(x, 0, y), INVALID_CELL_ITEM)
|
||||
var point: int = cell_coord_to_astar_point(x, y)
|
||||
var north_point: int = cell_coord_to_astar_point(x - 1, y)
|
||||
var south_point: int = cell_coord_to_astar_point(x + 1, y)
|
||||
var east_point: int = cell_coord_to_astar_point(x, y + 1)
|
||||
var west_point: int = cell_coord_to_astar_point(x, y - 1)
|
||||
if x % 2 == 0 and y % 2 == 0: #If the tile is on a point on the pathfinding grid
|
||||
a_star_graph_3d.astar.set_point_disabled(point)
|
||||
if x % 2 == 1 and y % 2 == 0: #If the cell breaks a north-south link
|
||||
a_star_graph_3d.astar.disconnect_points(north_point, south_point)
|
||||
if x % 2 == 0 and y % 2 == 1: #If the cell breaks a east-west link
|
||||
a_star_graph_3d.astar.disconnect_points(east_point, west_point)
|
||||
#func remove_world_tile(x: int, y: int) -> void:
|
||||
# if get_cell_item(Vector3i(x, 0, y)) != 1 or abs(x) >= a_star_graph_3d.grid_size.x or abs(y) >= a_star_graph_3d.grid_size.y:
|
||||
# return
|
||||
# set_cell_item(Vector3i(x, 0, y), INVALID_CELL_ITEM)
|
||||
# var point: int = cell_coord_to_astar_point(x, y)
|
||||
# var north_point: int = cell_coord_to_astar_point(x - 1, y)
|
||||
# var south_point: int = cell_coord_to_astar_point(x + 1, y)
|
||||
# var east_point: int = cell_coord_to_astar_point(x, y + 1)
|
||||
# var west_point: int = cell_coord_to_astar_point(x, y - 1)
|
||||
# if x % 2 == 0 and y % 2 == 0: #If the tile is on a point on the pathfinding grid
|
||||
# a_star_graph_3d.astar.set_point_disabled(point)
|
||||
# if x % 2 == 1 and y % 2 == 0: #If the cell breaks a north-south link
|
||||
# a_star_graph_3d.astar.disconnect_points(north_point, south_point)
|
||||
# if x % 2 == 0 and y % 2 == 1: #If the cell breaks a east-west link
|
||||
# a_star_graph_3d.astar.disconnect_points(east_point, west_point)
|
||||
|
@ -1,98 +0,0 @@
|
||||
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
|
||||
|
||||
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) -> void:
|
||||
$MeshInstance3D.set_instance_shader_parameter("Color", color)
|
||||
|
||||
|
||||
func set_float(value: float) -> void:
|
||||
$MeshInstance3D.set_instance_shader_parameter("Float", value)
|
||||
|
||||
|
||||
func add_card(card: Card, caller_id: int) -> void:
|
||||
networked_spawn_tower.rpc(Data.cards.find(card), caller_id)
|
||||
|
||||
|
||||
func remove_card() -> void:
|
||||
networked_remove_tower.rpc()
|
||||
|
||||
|
||||
func toggle_collision() -> void:
|
||||
collider.disabled = !collider.disabled
|
||||
|
||||
|
||||
func set_north_wall(value: bool) -> void:
|
||||
north_mesh.set_visible(value)
|
||||
north_collider.disabled = !value
|
||||
|
||||
|
||||
func set_south_wall(value: bool) -> void:
|
||||
south_mesh.set_visible(value)
|
||||
south_collider.disabled = !value
|
||||
|
||||
|
||||
func set_east_wall(value: bool) -> void:
|
||||
east_mesh.set_visible(value)
|
||||
east_collider.disabled = !value
|
||||
|
||||
|
||||
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(card_index: int, caller_id: int) -> void:
|
||||
var card: Card = Data.cards[card_index]
|
||||
inventory.add(card)
|
||||
tower = inventory.contents.keys()[0].turret_scene.instantiate() as Tower
|
||||
tower.stats = inventory.contents.keys()[0].tower_stats
|
||||
tower.name = "tower"
|
||||
tower.base_name = name
|
||||
tower.owner_id = caller_id
|
||||
tower.position = Vector3(0, 1.2, 0)
|
||||
minimap_icon.modulate = Color.RED
|
||||
north_icon.modulate = Color.RED
|
||||
south_icon.modulate = Color.RED
|
||||
west_icon.modulate = Color.RED
|
||||
east_icon.modulate = Color.RED
|
||||
add_child(tower)
|
||||
|
||||
|
||||
@rpc("reliable", "call_local", "any_peer")
|
||||
func networked_remove_tower() -> void:
|
||||
Game.connected_players_nodes[tower.owner_id].add_card(inventory.remove_at(0))
|
||||
Game.connected_players_nodes[tower.owner_id].unready_self()
|
||||
tower.queue_free()
|
||||
tower = null
|
||||
minimap_icon.modulate = Color.GREEN
|
||||
north_icon.modulate = Color.GREEN
|
||||
south_icon.modulate = Color.GREEN
|
||||
west_icon.modulate = Color.GREEN
|
||||
east_icon.modulate = Color.GREEN
|
@ -1 +0,0 @@
|
||||
uid://si58bm4r7r2i
|
@ -18,7 +18,7 @@ func to_dict() -> Dictionary:
|
||||
enemy_count = group.enemy.epic_group
|
||||
elif group.rarity == Data.Rarity.LEGENDARY:
|
||||
enemy_count = group.enemy.legendary_group
|
||||
if !dict.has(Data.enemies.find(group.enemy)):
|
||||
dict[Data.enemies.find(group.enemy)] = 0
|
||||
dict[Data.enemies.find(group.enemy)] += enemy_count
|
||||
if !dict.has(group.enemy.title):
|
||||
dict[group.enemy.title] = 0
|
||||
dict[group.enemy.title] += enemy_count
|
||||
return dict
|
||||
|
@ -33,6 +33,7 @@ static func generate_wave(spawn_power: int, spawn_pool: Array[Enemy], spawners:
|
||||
var new_card: EnemyCard = EnemyCard.new()
|
||||
|
||||
#First, choose an enemy at random
|
||||
#TODO: Use seeded random
|
||||
new_card.enemy = spawn_pool.pick_random()
|
||||
|
||||
#Next, we have to figure out if we can actually buy that enemy
|
||||
@ -61,10 +62,11 @@ static func generate_wave(spawn_power: int, spawn_pool: Array[Enemy], spawners:
|
||||
#Even the common rarity was too expensive, so we have to choose
|
||||
#a different enemy and try this process again
|
||||
var enemy_id: int = spawn_pool.find(new_card.enemy)
|
||||
enemy_id -= 1
|
||||
if enemy_id <= 0:
|
||||
new_card.enemy = spawn_pool[spawn_pool.size() - 1]
|
||||
else:
|
||||
new_card.enemy = spawn_pool[enemy_id - 1]
|
||||
new_card.enemy = spawn_pool[enemy_id]
|
||||
|
||||
#Now that we know which rarities we could afford, lets just choose a
|
||||
#random one
|
||||
|
Reference in New Issue
Block a user