open-fpsz/entities/components/flag_carry_component.gd

49 lines
1.9 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/>.
## This component allows its entity to interact with flags
class_name FlagCarryComponent extends Node3D
@export var throw_force : int = 12
@export var mesh : Node3D
var _flag : Flag
func grab(flag : Flag) -> void:
if flag.state < Flag.FlagState.TAKEN:
show()
_flag = flag
flag.grabbed.emit(self)
func drop(inherited_velocity : Vector3 = Vector3.ZERO) -> void:
_release(inherited_velocity, 0)
func throw(inherited_velocity : Vector3 = Vector3.ZERO, _force: int = throw_force) -> void:
_release(inherited_velocity, _force)
func _release(inherited_velocity : Vector3 = Vector3.ZERO, _force: int = throw_force) -> void:
if not _flag or !is_inside_tree(): return
_flag.dropped.emit(self)
var impulse : Vector3 = _flag.mass * (inherited_velocity + global_basis.z * _force)
_flag.apply_central_impulse(impulse) # wake up the flag
# @NOTE: throw the flag from some distance in front of the player to avoid regrabbing mid-air
# @FIXME: there is a small chance to send the flag under the map
_flag.global_position = global_position + (global_basis.z * 1.7)
# rotate carried flag based on flag carry global rotation
_flag.global_rotation = Vector3(.0, global_rotation.y, .0)
# drop reference to flag
_flag = null
# hide carried flag mesh
hide()