TowerDefense/Towers/Scripts/TowerManager.gd

148 lines
3.9 KiB
GDScript3
Raw Normal View History

extends Node3D
2025-08-31 23:07:55 +02:00
class_name TowerManager
2025-08-29 20:07:36 +02:00
2025-08-29 12:11:51 +02:00
enum STATE { IDLE, PLACING }
2025-08-31 23:07:55 +02:00
var _state : int = STATE.IDLE
2025-09-01 13:52:14 +02:00
var selected_tower : Tower = null
var selected_tower_type : Tower.TYPE = Tower.TYPE.NONE
2025-09-01 13:52:14 +02:00
var the_cube : TheCube
@onready var cam : Camera3D = $"../Camera3D"
2025-08-28 18:59:03 +02:00
@onready var selection_icon : Sprite3D = $Sprite3DSelection
2025-08-29 12:11:51 +02:00
var towers : Dictionary
var selected_collider : CollisionObject3D
func _ready() -> void:
2025-08-29 12:11:51 +02:00
EventBus.tower_selected.connect(selectTower)
2025-09-01 13:52:14 +02:00
EventBus.cube_ready.connect(func(value): the_cube = value)
2025-08-28 20:35:45 +02:00
#$AnimationPlayer.play("arrow_bobbing")
func _process(delta: float) -> void:
handle_player_controls()
if Input.is_action_just_pressed("build"):
if not selected_collider:
return
if selected_collider.collision_layer == 1:
build_tower()
if selected_collider is TheCube:
EventBus.open_shop.emit()
else:
EventBus.close_shop.emit()
if Input.is_action_just_pressed("rest"):
2025-08-27 13:27:32 +02:00
if _state == STATE.PLACING:
quit_placing()
2025-08-27 14:37:26 +02:00
EventBus.close_shop.emit()
2025-08-29 12:11:51 +02:00
if selected_collider is Tower:
selected_collider.is_rest = true
2025-08-30 20:08:12 +02:00
selected_collider.global_position = Vector3.ZERO
2025-08-29 12:11:51 +02:00
emitTeamChanges()
func handle_player_controls() -> void:
var space_state : PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
var mouse_pos : Vector2 = get_viewport().get_mouse_position()
var origin : Vector3 = cam.project_ray_origin(mouse_pos)
var end : Vector3 = origin + cam.project_ray_normal(mouse_pos) * 100
var ray : PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(origin, end)
ray.collide_with_bodies = true
var ray_result : Dictionary = space_state.intersect_ray(ray)
if ray_result.is_empty():
visible = false
selected_collider = null
return
2025-08-29 12:11:51 +02:00
selected_collider = ray_result.get("collider")
visible = true
2025-08-30 20:08:12 +02:00
selection_icon.visible = true
2025-08-29 12:11:51 +02:00
global_position = selected_collider.global_position
2025-08-28 20:35:45 +02:00
global_position += Vector3(0.0,0.02,0.0)
2025-08-27 13:27:32 +02:00
if _state == STATE.PLACING:
2025-08-29 12:11:51 +02:00
selected_tower.sprite.modulate = "ff4545c8" #If the tower can't be placed he is red
selection_icon.visible = false
2025-08-27 13:27:32 +02:00
if selected_collider is BuildTile: #if we are placing a tower, hide the selector model
2025-08-29 12:11:51 +02:00
selected_tower.sprite.modulate = "61ff45c8" #If the tower can be placed he is green
2025-08-27 13:27:32 +02:00
func place_tower() -> void:
_state = STATE.PLACING
2025-08-29 12:11:51 +02:00
selected_tower = Game.towers.get(selected_tower_type).instantiate()
2025-08-29 12:11:51 +02:00
towers.set(selected_tower_type, selected_tower)
selected_tower.collision_layer = 0
add_child(selected_tower)
2025-08-27 13:27:32 +02:00
func quit_placing() -> void:
_state = STATE.IDLE
# Refactoriser ce code
func build_tower() -> void:
2025-08-29 12:11:51 +02:00
if !visible || !selected_tower:
2025-08-27 13:27:32 +02:00
return
2025-08-27 14:37:26 +02:00
2025-08-29 12:11:51 +02:00
if not selected_tower.builded && selected_tower.price > the_cube.money:
#Can't build
print("Too costly")
return
2025-08-29 12:11:51 +02:00
if selected_tower.is_rest:
if not selected_tower.builded:
#Build Tower
selected_tower.build()
2025-08-29 12:11:51 +02:00
remove_child(selected_tower)
$"../Towers".add_child(selected_tower)
quit_placing()
selected_tower.is_rest = false
2025-08-29 12:11:51 +02:00
move_tower()
emitTeamChanges()
func selectTower(towerType : Tower.TYPE):
2025-08-29 12:11:51 +02:00
if selected_tower && not selected_tower.builded:
selected_tower.visible = false
if towerType == selected_tower_type || towerType == Tower.TYPE.NONE:
2025-08-29 12:11:51 +02:00
selected_tower = null
selected_tower_type = Tower.TYPE.NONE
2025-08-29 12:11:51 +02:00
_state = STATE.IDLE
return
2025-08-29 12:11:51 +02:00
selected_tower_type = towerType
if towers.has(towerType):
_state = STATE.IDLE
selected_tower = towers.get(towerType)
selected_tower.visible = true
else:
place_tower()
func move_tower():
selected_tower.global_position = global_position
2025-08-29 12:11:51 +02:00
func emitTeamChanges() -> void:
var team_in_action : int = 0
var team_in_rest : int = 0
var tower_count : int = 0
for towerType in towers:
var tower : Tower = towers[towerType]
if tower.builded:
tower_count += 1
if tower.is_rest:
team_in_rest += 1
else:
team_in_action += 1
EventBus.team_in_action_changed.emit(team_in_action)
2025-08-29 12:11:51 +02:00
EventBus.team_in_rest_changed.emit(team_in_rest)
EventBus.tower_count_changed.emit(tower_count)