mirror of
https://gitlab.com/open-fpsz/open-fpsz.git
synced 2026-01-20 03:54:47 +00:00
60 lines
2.5 KiB
GDScript
60 lines
2.5 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 GrenadeLauncherProjectile extends ArcProjectile
|
|
|
|
## The time before
|
|
@export var fuse_time : float = 1.
|
|
@export_range(0., 1.) var bounce_velocity_modifier: float = .24
|
|
|
|
var fuse_timer := Timer.new()
|
|
|
|
func _ready() -> void:
|
|
fuse_timer.wait_time = fuse_time
|
|
fuse_timer.one_shot = true
|
|
fuse_timer.autostart = true
|
|
add_child(fuse_timer)
|
|
# remove exceptions after a short time so that it can collide again with owner
|
|
get_tree().create_timer(.3).timeout.connect(func() -> void:
|
|
shape_cast.clear_exceptions())
|
|
|
|
func _physics_process(delta : float) -> void:
|
|
if not shape_cast: set_physics_process(false)
|
|
velocity += _gravity * delta
|
|
shape_cast.target_position = to_local(global_position + velocity * delta)
|
|
shape_cast.force_shapecast_update()
|
|
if shape_cast.is_colliding():
|
|
var collider: Node = shape_cast.get_collider(0)
|
|
var hit_point: Vector3 = shape_cast.get_collision_point(0)
|
|
# explode on player hit or when fuse timer is exhausted
|
|
if collider is Player or fuse_timer.is_stopped():
|
|
destroy(hit_point)
|
|
return
|
|
# bounce projectile
|
|
var hit_normal : Vector3 = shape_cast.get_collision_normal(0)
|
|
velocity = calc_bounce_velocity(velocity, hit_normal.normalized())
|
|
global_position = hit_point + hit_normal.normalized() * shape_cast.shape.radius
|
|
global_position += velocity * delta
|
|
else:
|
|
# move projectile
|
|
global_position += velocity * delta
|
|
|
|
## This method computes projectile bounce velocity.
|
|
func calc_bounce_velocity(_velocity: Vector3, hit_normal: Vector3) -> Vector3:
|
|
return mirror_vector_by_normal(_velocity, hit_normal.normalized()) * bounce_velocity_modifier
|
|
|
|
## This method computes reflected vector using the formula: R = V - 2 * (V dot N) * N
|
|
func mirror_vector_by_normal(_velocity: Vector3, hit_normal_unit_vector: Vector3) -> Vector3:
|
|
return _velocity - 2 * _velocity.dot(hit_normal_unit_vector) * hit_normal_unit_vector
|