pulled out target selection to its own node

This commit is contained in:
2024-04-01 17:08:47 +11:00
parent 05914a3c64
commit 16951a9beb
11 changed files with 117 additions and 112 deletions

View File

@ -5,7 +5,7 @@ var direction: Vector3
func _ready() -> void:
distance_remaining = character.global_position.distance_squared_to(goal.global_position)
distance_remaining = character.global_position.distance_to(goal.global_position)
direction = character.global_position.direction_to(goal.global_position)

View File

@ -3,10 +3,9 @@ class_name HitscanTower extends Tower
func shoot() -> void:
super.shoot()
if targeted_enemy and is_instance_valid(targeted_enemy) and targeted_enemy.alive:
targeted_enemy.damage(damage)
if Data.preferences.display_tower_damage_indicators:
spawn_damage_indicator(targeted_enemy.sprite.global_position)
target_finder.get_target().damage(damage)
if Data.preferences.display_tower_damage_indicators:
spawn_damage_indicator(target_finder.get_target().sprite.global_position)
@rpc("reliable")

View File

@ -7,7 +7,7 @@ class_name ShapecastTower extends Tower
func _process(delta: float) -> void:
super._process(delta)
if targeted_enemy:
if target_finder.get_target():
particlesystem.emitting = true
else:
particlesystem.emitting = false
@ -20,8 +20,8 @@ func shoot() -> void:
func aim() -> void:
yaw_model.look_at(targeted_enemy.global_position)
pitch_model.look_at(targeted_enemy.global_position)
yaw_model.look_at(target_finder.get_target().global_position)
pitch_model.look_at(target_finder.get_target().global_position)
pitch_model.rotation.x = 0.0

View File

@ -5,9 +5,9 @@ class_name StatusApplyingTower extends HitscanTower
func shoot() -> void:
super.shoot()
if targeted_enemy and is_instance_valid(targeted_enemy) and targeted_enemy.alive:
targeted_enemy.damage(damage)
targeted_enemy.status_manager.add_effect(build_status_object())
if target_finder.get_target():
target_finder.get_target().damage(damage)
target_finder.get_target().status_manager.add_effect(build_status_object())
func build_status_object() -> StatusEffect:

View File

@ -1,6 +1,7 @@
class_name Tower extends Node3D
@export var stats: CardText
@export var target_finder: TargetFinder
@export var animator: AnimationPlayer
@export var pitch_model: MeshInstance3D
@export var yaw_model: MeshInstance3D
@ -10,7 +11,7 @@ class_name Tower extends Node3D
var owner_id: int
var damage_particle_scene: PackedScene = preload("res://Scenes/damage_particle.tscn")
var base_name: String
var targeted_enemy: EnemyController
#var targeted_enemy: EnemyController
var time_since_firing: float = 0.0
var time_between_shots: float = 0.0
var damage: float = 0.0
@ -38,46 +39,22 @@ func _process(delta: float) -> void:
func _physics_process(_delta: float) -> void:
if !is_multiplayer_authority():
#only doing the graphical sort of stuff but not shoot logic
if targeted_enemy:
if !is_instance_valid(targeted_enemy) or !targeted_enemy.alive or global_position.distance_to(targeted_enemy.global_position) > target_range:
targeted_enemy = null
else:
aim()
return
if !targeted_enemy:
acquire_target()
else:
if !is_instance_valid(targeted_enemy) or !targeted_enemy.alive or global_position.distance_to(targeted_enemy.global_position) > target_range:
targeted_enemy = null
if targeted_enemy:
if target_finder.get_target():
aim()
if time_since_firing >= time_between_shots:
time_since_firing -= time_between_shots
shoot()
return
if target_finder.get_target():
aim()
if time_since_firing >= time_between_shots:
time_since_firing -= time_between_shots
shoot()
func aim() -> void:
yaw_model.look_at(targeted_enemy.global_position)
pitch_model.look_at(targeted_enemy.global_position)
yaw_model.look_at(target_finder.get_target().global_position)
pitch_model.look_at(target_finder.get_target().global_position)
pitch_model.rotation.x = 0.0
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: 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:
most_progressed_enemy = enemy
if most_progressed_enemy != null:
targeted_enemy = most_progressed_enemy
networked_acquire_target.rpc(get_tree().root.get_path_to(most_progressed_enemy))
func shoot() -> void:
animator.play("shoot")
audio_player.play()
@ -98,6 +75,6 @@ func networked_shoot() -> void:
shoot()
@rpc("reliable")
func networked_acquire_target(target_node_path: String) -> void:
targeted_enemy = get_tree().root.get_node(target_node_path)
#@rpc("reliable")
#func networked_acquire_target(target_node_path: String) -> void:
#targeted_enemy = get_tree().root.get_node(target_node_path)

62
Scripts/target_finder.gd Normal file
View File

@ -0,0 +1,62 @@
class_name TargetFinder extends Node
@export var tower: Tower
@export var max_targets: int = 1
var target_cache: EnemyController
var multiple_targets_cache: Array[EnemyController]
func get_multiple_targets() -> Array[EnemyController]:
var new_cache: Array[EnemyController] = []
for enemy: EnemyController in multiple_targets_cache:
if is_instance_valid(enemy) and enemy.alive and enemy.global_position.distance_to(tower.global_position) <= tower.target_range:
new_cache.append(enemy)
if new_cache.size() < max_targets:
multiple_targets_cache = find_multiple_targets(new_cache)
return multiple_targets_cache
func get_target() -> EnemyController:
if !is_instance_valid(target_cache) or !target_cache.alive or tower.global_position.distance_to(target_cache.global_position) > tower.target_range:
target_cache = find_enemy()
return target_cache
func find_enemy() -> EnemyController:
var most_progressed_enemy: EnemyController = null
for enemy: EnemyController in get_tree().get_nodes_in_group("Enemies"):
if tower.global_position.distance_to(enemy.global_position) > tower.target_range:
continue
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 & tower.stats.target_type:
most_progressed_enemy = enemy
return most_progressed_enemy
#TODO: Figure out how to multiplayer-ize this
#networked_acquire_target.rpc(get_tree().root.get_path_to(most_progressed_enemy))
func find_multiple_targets(existing_cache: Array[EnemyController]) -> Array[EnemyController]:
var possible_enemies: Array[EnemyController] = []
for enemy: EnemyController in get_tree().get_nodes_in_group("Enemies"):
if !is_instance_valid(enemy):
continue
if tower.global_position.distance_to(enemy.global_position) > tower.target_range:
continue
if !(enemy.stats.target_type & tower.stats.target_type):
continue
if multiple_targets_cache.has(enemy):
continue
possible_enemies.append(enemy)
for x: int in max_targets - existing_cache.size():
if possible_enemies.size() == 0:
break
var chosen: EnemyController = possible_enemies.pick_random()
possible_enemies.erase(chosen)
existing_cache.append(chosen)
return existing_cache