open-fpsz/entities/flag/flag.gd
2024-10-16 19:59:38 -04:00

74 lines
2.2 KiB
GDScript

# This file is part of open-fpsz.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class_name Flag extends RigidBody3D
signal grabbed(carry: FlagCarryComponent)
signal dropped(carry: FlagCarryComponent)
enum FlagState {
ON_STAND,
DROPPED,
TAKEN
}
@export var state : FlagState = FlagState.ON_STAND
@onready var area : Area3D = $GripArea
@onready var mesh : Node3D = $Mesh
@onready var waypoint : Waypoint3D = $Waypoint
var last_carrier : FlagCarryComponent
var dropped_duration_max := 30.
## This timer is responsible for returning the flag when it is dropped for more than [member dropped_duration_max].
var respawn_timer := Timer.new()
func _process(_delta:float) -> void:
if state == FlagState.DROPPED and not respawn_timer.is_stopped():
waypoint.text = "%.2f s" % respawn_timer.time_left
else:
waypoint.text = ""
func _ready() -> void:
area.body_entered.connect(_on_body_entered)
grabbed.connect(_on_grabbed)
dropped.connect(_on_dropped)
if multiplayer.is_server():
respawn_timer.wait_time = dropped_duration_max
respawn_timer.one_shot = true
add_child(respawn_timer)
func _on_body_entered(body: Node) -> void:
if body is Player:
assert(body.flag_carry_component)
if state < FlagState.TAKEN:
body.flag_carry_component.grab(self)
hide()
func _on_grabbed(_carry: FlagCarryComponent) -> void:
assert(state < FlagState.TAKEN)
hide()
state = FlagState.TAKEN
sleeping = true
area.set_deferred("monitoring", false)
func _on_dropped(carry: FlagCarryComponent) -> void:
assert(state == FlagState.TAKEN)
sleeping = false
area.set_deferred("monitoring", true)
state = FlagState.DROPPED
last_carrier = carry
show()