inching towards better class inheritence and multiplayer compatibility
This commit is contained in:
13
Scripts/Towers/hitscan_tower.gd
Normal file
13
Scripts/Towers/hitscan_tower.gd
Normal file
@ -0,0 +1,13 @@
|
||||
extends Tower
|
||||
class_name HitscanTower
|
||||
|
||||
|
||||
func shoot():
|
||||
super.shoot()
|
||||
if targeted_enemy and is_instance_valid(targeted_enemy) and targeted_enemy.alive:
|
||||
targeted_enemy.damage(damage)
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_shoot():
|
||||
super.networked_shoot()
|
30
Scripts/Towers/projectile_tower.gd
Normal file
30
Scripts/Towers/projectile_tower.gd
Normal file
@ -0,0 +1,30 @@
|
||||
extends Tower
|
||||
class_name ProjectileTower
|
||||
|
||||
@export var projectile_scene : PackedScene
|
||||
|
||||
var force := 2.0
|
||||
var projectile_id := 0
|
||||
|
||||
|
||||
func shoot():
|
||||
if is_multiplayer_authority():
|
||||
networked_spawn_projectile.rpc(multiplayer.get_unique_id())
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_shoot():
|
||||
super.networked_shoot()
|
||||
shoot()
|
||||
|
||||
|
||||
@rpc("reliable", "call_local")
|
||||
func networked_spawn_projectile(peer_id):
|
||||
var projectile = projectile_scene.instantiate() as Projectile
|
||||
projectile.position = global_position + Vector3.UP
|
||||
projectile.damage = damage
|
||||
projectile.direction = -yaw_model.global_transform.basis.z
|
||||
projectile.force = force
|
||||
projectile.name = base_name + str(peer_id) + str(projectile_id)
|
||||
get_tree().root.add_child(projectile)
|
||||
projectile_id += 1
|
92
Scripts/Towers/tower.gd
Normal file
92
Scripts/Towers/tower.gd
Normal file
@ -0,0 +1,92 @@
|
||||
extends Node3D
|
||||
class_name Tower
|
||||
|
||||
@export var stats : CardText
|
||||
@export var animator : AnimationPlayer
|
||||
@export var pitch_model : MeshInstance3D
|
||||
@export var yaw_model : MeshInstance3D
|
||||
@export var range_indicator : CSGSphere3D
|
||||
|
||||
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
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
time_between_shots = stats.get_attribute("Fire Delay")
|
||||
damage = stats.get_attribute("Damage")
|
||||
target_range = stats.get_attribute("Range")
|
||||
range_indicator.radius = target_range
|
||||
|
||||
|
||||
func preview_range(value):
|
||||
range_indicator.set_visible(value)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if !is_multiplayer_authority():
|
||||
return
|
||||
if time_since_firing < time_between_shots:
|
||||
time_since_firing += delta
|
||||
|
||||
|
||||
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:
|
||||
aim()
|
||||
if time_since_firing >= time_between_shots:
|
||||
time_since_firing -= time_between_shots
|
||||
shoot()
|
||||
|
||||
|
||||
func aim():
|
||||
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"):
|
||||
if global_position.distance_to(enemy.global_position) > target_range:
|
||||
continue
|
||||
var em_1 = enemy.movement_controller as EnemyMovement
|
||||
var em_2 : EnemyMovement
|
||||
if most_progressed_enemy != null:
|
||||
em_2 = most_progressed_enemy.movement_controller as EnemyMovement
|
||||
if (most_progressed_enemy == null or em_1.distance_remaining < em_2.distance_remaining) and enemy.stats.target_type & stats.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():
|
||||
animator.play("shoot")
|
||||
if is_multiplayer_authority():
|
||||
networked_shoot.rpc()
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_shoot():
|
||||
shoot()
|
||||
|
||||
|
||||
@rpc("reliable")
|
||||
func networked_acquire_target(target_node_path):
|
||||
targeted_enemy = get_tree().root.get_node(target_node_path)
|
Reference in New Issue
Block a user