👽 interstellar delivery

This commit is contained in:
anyreso 2024-10-16 21:43:01 +00:00
parent 547c97bfba
commit 97c8292858
257 changed files with 7309 additions and 4637 deletions

View file

@ -0,0 +1,29 @@
# 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 AutomaticWeapon extends Weapon
var _auto_trigger := Timer.new()
func _init() -> void:
super._init()
_auto_trigger.timeout.connect(trigger)
add_child(_auto_trigger)
func _on_primary(pressed: bool) -> void:
if pressed:
trigger()
_auto_trigger.start(cooldown)
else:
_auto_trigger.stop()

View file

@ -12,33 +12,44 @@
#
# 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 ChainGun extends Node3D
class_name ChainGun extends AutomaticWeapon
@export_range(0, 250) var ammo : int = 250
@export var fire_rate : float = .1 # seconds
@export var reload_time : float = 0. # seconds
@export var _PROJECTILE : PackedScene
## The factor of velocity from the owner of this [Weapon] inherited by this [Projectile].
@export_range(0., 1., .01) var inheritance : float = 1.
@export_category("Animations")
@export var anim_player : AnimationPlayer
## The angular deviation from ideal line of fire in degrees
@export var min_spread: float
## The maximum angle the spread will increase to during heatup.
@export var max_spread: float
## The amount of time it takes for the chaingun to spin up or spin down.
@export var spin_period: float
## The amount of time it takes for the chaingun to overheat.
@export var heat_period: float
#@export var heat_time: float
## The fraction of the [member heat_period] at which the gun can start firing again
@export var cooldown_threshold: float
## Multiplier for the speed when calculating cooldown/heatup
@export var speed_cooldown_factor: float
## The [Shader] responsible for rendering heat while firing.
@export var heat_shader: Shader
# heat flag
var overheated: bool
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
func trigger() -> void:
func _on_triggered() -> void:
# play the fire animation
anim_player.play("fire")
# init projectile
var projectile : Node3D = $ProjectileSpawner.new_projectile(
ChainGunProjectile,
owner.linear_velocity,
owner.match_participant
)
# add to owner of player for now
Global.type.add_child(projectile)
var projectile : ChainGunProjectile = _PROJECTILE.instantiate()
projectile.velocity = projectile.speed * $Nozzle.global_basis.z.normalized() + owner.linear_velocity * inheritance
projectile.source = owner
owner.add_child(projectile)
projectile.global_transform = $Nozzle.global_transform
projectile.shape_cast.add_exception(owner)
func _on_visibility_changed() -> void:
if self.visible:
anim_player.play("equip")
#anim_player.play("equip")
#self.sounds.play("equip")
pass

View file

@ -1,19 +1,23 @@
[gd_scene load_steps=5 format=3 uid="uid://b0xql5hi0b52y"]
[gd_scene load_steps=4 format=3 uid="uid://b0xql5hi0b52y"]
[ext_resource type="PackedScene" uid="uid://cumv8wij5uufk" path="res://entities/weapons/chaingun/assets/chaingun.glb" id="1_d8tdv"]
[ext_resource type="Script" path="res://entities/weapons/chaingun/chaingun.gd" id="2_qsqeh"]
[ext_resource type="Script" path="res://entities/components/projectile_spawner.gd" id="3_knyrc"]
[ext_resource type="PackedScene" uid="uid://b0sfwgilfbpx5" path="res://entities/weapons/chaingun/projectile.tscn" id="4_p63ts"]
[node name="ChainGun" node_paths=PackedStringArray("anim_player") instance=ExtResource("1_d8tdv")]
script = ExtResource("2_qsqeh")
_PROJECTILE = ExtResource("4_p63ts")
anim_player = NodePath("AnimationPlayer")
[node name="ProjectileSpawner" type="Marker3D" parent="." index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.124544, 0.476417)
script = ExtResource("3_knyrc")
PROJECTILE = ExtResource("4_p63ts")
inheritance = 1.0
min_spread = 1.0
max_spread = 4.0
spin_period = 0.5
heat_period = 3.0
cooldown_threshold = 1.7
speed_cooldown_factor = 0.001
ammo = 150
max_ammo = 150
ammo_usage = 1
cooldown = 0.1
[node name="Skeleton3D" parent="Armature" index="0"]
bones/1/rotation = Quaternion(3.09086e-08, 0.707107, 0.707107, 3.09086e-08)
@ -32,14 +36,18 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.692504, 1.30946)
[node name="Grip" parent="Armature/Skeleton3D" index="3"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.692504, 1.30946)
[node name="AnimationPlayer" parent="." index="2"]
[node name="AnimationPlayer" parent="." index="1"]
autoplay = "idle"
[node name="Barrels" type="BoneAttachment3D" parent="." index="3"]
[node name="Barrels" type="BoneAttachment3D" parent="." index="2"]
transform = Transform3D(-1, 0, 8.74227e-08, 8.74227e-08, 0, 1, 0, 1, 0, -2.32831e-10, 0.692504, 0.756307)
bone_name = "barrels"
bone_idx = 1
use_external_skeleton = true
external_skeleton = NodePath("../Armature/Skeleton3D")
[node name="Nozzle" type="Marker3D" parent="." index="3"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.98023e-08, 0.123522, 0.477262)
[connection signal="triggered" from="." to="." method="_on_triggered"]
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]

View file

@ -12,44 +12,19 @@
#
# 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 ChainGunProjectile extends Node3D
class_name ChainGunProjectile extends Projectile
@export var speed : float = 180. # m/s
@export var lifespan : float = .5 # in seconds
@export var build_up_time : float = .6 # seconds
var shooter : MatchParticipant
var velocity : Vector3 = Vector3.ZERO
@onready var shape_cast : ShapeCast3D = $ShapeCast3D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
$Timer.wait_time = lifespan
func _on_timer_timeout() -> void:
queue_free()
func _physics_process(delta : float) -> void:
func _physics_process(delta: float) -> void:
var previous_global_position: Vector3 = global_position
global_position += velocity * delta
if shape_cast.is_colliding():
for collision_id in shape_cast.get_collision_count():
var collider : Object = shape_cast.get_collider(collision_id)
# handle collision
if shape_cast:
var local_global_position: Vector3 = to_local(previous_global_position)
shape_cast.target_position = Vector3(
local_global_position.x, -local_global_position.z, local_global_position.y)
shape_cast.target_position = shape_cast.target_position
if shape_cast.is_colliding():
var collider: Node = shape_cast.get_collider(0)
if collider is Player:
if is_multiplayer_authority():
assert(shooter)
collider.health_component.damage.rpc(25, shooter.player_id, shooter.team_id)
queue_free()
## This method is a parameterized constructor for the [ChainGunProjectile] scene of the [ChainGun]
static func new_projectile(
origin : Marker3D,
inherited_velocity : Vector3,
_shooter : MatchParticipant,
scene : PackedScene
) -> ChainGunProjectile:
var projectile : ChainGunProjectile = scene.instantiate()
projectile.shooter = _shooter
projectile.transform = origin.global_transform
projectile.velocity = origin.global_basis.z.normalized() * projectile.speed + inherited_velocity
return projectile
collider.damage.emit(source, collider, damage)
destroy(shape_cast.collision_result[0].point)

View file

@ -9,17 +9,15 @@ height = 2.5
[node name="ChainGunProjectile" instance=ExtResource("1_p7mmn")]
script = ExtResource("2_jjfwk")
speed = 128.0
lifespan = 3.0
damage = 15
[node name="ShapeCast3D" type="ShapeCast3D" parent="." index="0"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 4.29628)
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 1.25)
shape = SubResource("CapsuleShape3D_dbodg")
target_position = Vector3(0, -3, 0)
target_position = Vector3(0, 0, 0)
collision_mask = 2147483653
[node name="tracerinner" parent="." index="1"]
transform = Transform3D(0.0505494, 0, 0, 0, 0.0505494, 0, 0, 0, 0.0505494, 0, 0, 2.49628)
[node name="Timer" type="Timer" parent="." index="2"]
autostart = true
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
transform = Transform3D(0.0505494, 0, 0, 0, 0.0505494, 0, 0, 0, 0.0505494, 0, 0, 2.5)

View file

@ -0,0 +1,19 @@
[gd_resource type="ShaderMaterial" load_steps=4 format=3 uid="uid://c80t026c2gpxx"]
[ext_resource type="Shader" uid="uid://d2aeepgs6xnsg" path="res://entities/weapons/grenade_launcher/assets/resources/explosion_shader.tres" id="1_dmawi"]
[ext_resource type="Texture2D" uid="uid://dt6c44uknktrg" path="res://entities/weapons/grenade_launcher/assets/textures/explosion_texture_alb.png" id="2_4up7w"]
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_itmuc"]
load_path = "res://.godot/imported/explosion_texture_flowmap.png-3137b307308713f172b3be796ef584b9.s3tc.ctex"
[resource]
render_priority = 0
shader = ExtResource("1_dmawi")
shader_parameter/albedo = Color(0.941176, 0.941176, 0.941176, 1)
shader_parameter/particles_anim_h_frames = 5
shader_parameter/particles_anim_v_frames = 5
shader_parameter/particles_anim_loop = false
shader_parameter/smoothing = true
shader_parameter/flow_strength = 0.015
shader_parameter/texture_albedo = ExtResource("2_4up7w")
shader_parameter/texture_flow = SubResource("CompressedTexture2D_itmuc")

View file

@ -0,0 +1,58 @@
[gd_resource type="Shader" format=3 uid="uid://d2aeepgs6xnsg"]
[resource]
code = "shader_type spatial;
render_mode unshaded;
// @TODO: add support for `Keep scale` billboard option so that we can spawn
// different scale using a curve in the particles process material
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_disable;
uniform sampler2D texture_flow : hint_normal,filter_linear_mipmap,repeat_disable;
uniform int particles_anim_h_frames;
uniform int particles_anim_v_frames;
uniform bool particles_anim_loop;
uniform bool smoothing = false;
uniform float flow_strength = 0.015;
varying vec2 next_UV;
varying float timer;
void vertex() {
mat4 mat_world = mat4(normalize(INV_VIEW_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]) ,normalize(INV_VIEW_MATRIX[2]), MODEL_MATRIX[3]);
mat_world = mat_world * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
MODELVIEW_MATRIX = VIEW_MATRIX * mat_world;
MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);
float h_frames = float(particles_anim_h_frames);
float v_frames = float(particles_anim_v_frames);
float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);
float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));
if (!particles_anim_loop) {
particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);
} else {
particle_frame = mod(particle_frame, particle_total_frames);
}
UV /= vec2(h_frames, v_frames);
next_UV = UV;
UV += vec2(mod(particle_frame, h_frames) / h_frames, floor((particle_frame + 0.5) / h_frames) / v_frames);
next_UV += vec2(mod(particle_frame + 1.0, h_frames) / h_frames, floor((particle_frame + 1.0 + 0.5) / h_frames) / v_frames);
timer = fract(INSTANCE_CUSTOM.y * h_frames * v_frames);
}
void fragment() {
vec4 albedo_tex;
if (smoothing) {
vec2 flow_tex = texture(texture_flow, UV).rg;
flow_tex -= 0.5;
flow_tex *= 2.0;
vec2 flow_uv = UV + flow_tex * timer * -flow_strength;
vec2 reverse_flow_uv = next_UV + flow_tex * (1.0 - timer) * flow_strength;
albedo_tex = mix(texture(texture_albedo, flow_uv), texture(texture_albedo, reverse_flow_uv), timer);
} else {
albedo_tex = texture(texture_albedo, UV);
}
albedo_tex *= COLOR;
ALBEDO = albedo.rgb * albedo_tex.rgb;
ALPHA *= albedo.a * albedo_tex.a;
}"

View file

@ -0,0 +1,4 @@
[gd_resource type="CompressedTexture2D" format=3 uid="uid://b0003clv8jv3n"]
[resource]
load_path = "res://.godot/imported/explosion_texture_alb.png-1ff7964ed65c51040c0956ec9ef6a893.s3tc.ctex"

View file

@ -0,0 +1,4 @@
[gd_resource type="CompressedTexture2D" format=3 uid="uid://ddlahr6k2hg5g"]
[resource]
load_path = "res://.godot/imported/explosion_texture_flowmap.png-3137b307308713f172b3be796ef584b9.s3tc.ctex"

View file

@ -10,4 +10,3 @@ shading_mode = 0
vertex_color_use_as_albedo = true
albedo_color = Color(0.860369, 0.860369, 0.860369, 1)
albedo_texture = SubResource("CompressedTexture2D_uiuwk")
billboard_keep_scale = true

View file

@ -1,27 +0,0 @@
[gd_resource type="ParticleProcessMaterial" load_steps=5 format=3 uid="uid://c78xg30ynapmt"]
[sub_resource type="Gradient" id="Gradient_q75yo"]
offsets = PackedFloat32Array(0.00806452, 1)
colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 0)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_gt2l8"]
gradient = SubResource("Gradient_q75yo")
[sub_resource type="Curve" id="Curve_jt11q"]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(0.980263, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_nb67t"]
curve = SubResource("Curve_jt11q")
[resource]
lifetime_randomness = 1.0
emission_shape = 1
emission_sphere_radius = 0.3
spread = 180.0
gravity = Vector3(0, -2, 0)
scale_min = 0.75
scale_max = 1.5
scale_curve = SubResource("CurveTexture_nb67t")
color = Color(5, 2, 1, 1)
color_ramp = SubResource("GradientTexture1D_gt2l8")

View file

@ -9,23 +9,28 @@ max_value = 5.0
_data = [Vector2(0, 5), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="Curve" id="Curve_1s1qr"]
[sub_resource type="Curve" id="Curve_26exw"]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveXYZTexture" id="CurveXYZTexture_eoauk"]
curve_x = SubResource("Curve_ei0ls")
curve_y = SubResource("Curve_q68ud")
curve_z = SubResource("Curve_1s1qr")
curve_z = SubResource("Curve_26exw")
[resource]
particle_flag_align_y = true
emission_shape = 1
emission_sphere_radius = 0.2
spread = 180.0
initial_velocity_min = 20.0
direction = Vector3(0, 1, 0)
spread = 90.0
initial_velocity_min = 15.0
initial_velocity_max = 25.0
gravity = Vector3(0, -19.6, 0)
radial_velocity_min = 10.0
radial_velocity_max = 10.0
gravity = Vector3(0, 0, 0)
scale_min = 0.2
scale_curve = SubResource("CurveXYZTexture_eoauk")
color = Color(5, 2, 1, 1)
turbulence_influence_min = 0.01
turbulence_influence_max = 0.01

View file

@ -0,0 +1,4 @@
[gd_resource type="SphereShape3D" format=3 uid="uid://b8d4jwso2dcdu"]
[resource]
radius = 0.062

View file

@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://chchhrpwmho2c"
path.s3tc="res://.godot/imported/Flare00.png-75515c1e8df86aba86a9e55bb8ca7901.s3tc.ctex"
path.etc2="res://.godot/imported/Flare00.png-75515c1e8df86aba86a9e55bb8ca7901.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://entities/weapons/grenade_launcher/assets/textures/Flare00.png"
dest_files=["res://.godot/imported/Flare00.png-75515c1e8df86aba86a9e55bb8ca7901.s3tc.ctex"]
dest_files=["res://.godot/imported/Flare00.png-75515c1e8df86aba86a9e55bb8ca7901.s3tc.ctex", "res://.godot/imported/Flare00.png-75515c1e8df86aba86a9e55bb8ca7901.etc2.ctex"]
[params]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View file

@ -0,0 +1,36 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dt6c44uknktrg"
path.s3tc="res://.godot/imported/explosion_texture_alb.png-1ff7964ed65c51040c0956ec9ef6a893.s3tc.ctex"
path.etc2="res://.godot/imported/explosion_texture_alb.png-1ff7964ed65c51040c0956ec9ef6a893.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://entities/weapons/grenade_launcher/assets/textures/explosion_texture_alb.png"
dest_files=["res://.godot/imported/explosion_texture_alb.png-1ff7964ed65c51040c0956ec9ef6a893.s3tc.ctex", "res://.godot/imported/explosion_texture_alb.png-1ff7964ed65c51040c0956ec9ef6a893.etc2.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

View file

@ -0,0 +1,36 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b6pjaen40x34u"
path.s3tc="res://.godot/imported/explosion_texture_flowmap.png-3137b307308713f172b3be796ef584b9.s3tc.ctex"
path.etc2="res://.godot/imported/explosion_texture_flowmap.png-3137b307308713f172b3be796ef584b9.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://entities/weapons/grenade_launcher/assets/textures/explosion_texture_flowmap.png"
dest_files=["res://.godot/imported/explosion_texture_flowmap.png-3137b307308713f172b3be796ef584b9.s3tc.ctex", "res://.godot/imported/explosion_texture_flowmap.png-3137b307308713f172b3be796ef584b9.etc2.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=1
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View file

@ -1,13 +1,29 @@
# 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 GrenadeLauncherProjectileExplosion extends Node3D
## The component responsible for explosion damages
@export var explosive_damage : ExplosiveDamageComponent
@export var explosive_damage : ExplosiveDamage
## The component responsible for owner identification
var shooter : MatchParticipant:
set(value):
shooter = value
explosive_damage.damage_dealer = value
## The source of explosion.
var source: Node:
set = set_source
func set_source(new_source: Node) -> void:
source = new_source
explosive_damage.source = new_source
## This is increment by 1 when a particle emitter is finished
var _finished_count : int = 0
@ -25,14 +41,3 @@ func _on_finished() -> void:
if _finished_count == $Particles.get_child_count():
queue_free()
## This method is a static factory constructor for the
## [GrenadeLauncherProjectileExplosion] scene of the [GrenadeLauncherProjectile].
static func new_explosion(
origin : Vector3,
_shooter : MatchParticipant,
scene : PackedScene
) -> GrenadeLauncherProjectileExplosion:
var explosion : GrenadeLauncherProjectileExplosion = scene.instantiate()
explosion.position = origin
explosion.shooter = _shooter
return explosion

View file

@ -1,11 +1,37 @@
[gd_scene load_steps=9 format=3 uid="uid://bb43ae1f5j8lw"]
[gd_scene load_steps=13 format=3 uid="uid://bb43ae1f5j8lw"]
[ext_resource type="Script" path="res://entities/weapons/grenade_launcher/explosion.gd" id="1_xb4jo"]
[ext_resource type="PackedScene" uid="uid://qb5sf7awdeui" path="res://entities/components/explosive_damage/explosive_damage.tscn" id="2_rq8du"]
[ext_resource type="Script" path="res://entities/projectiles/damages/explosive_damage.gd" id="2_r5wb7"]
[ext_resource type="Material" uid="uid://v7s5w3uw4hmb" path="res://entities/weapons/grenade_launcher/assets/resources/particle_process_material_sparks.tres" id="3_4u6ue"]
[ext_resource type="Material" uid="uid://c80t026c2gpxx" path="res://entities/weapons/grenade_launcher/assets/resources/explosion_material.tres" id="3_tsixm"]
[ext_resource type="Material" uid="uid://bbqjhgs44rnss" path="res://entities/weapons/grenade_launcher/assets/resources/material_flare.tres" id="4_634rq"]
[ext_resource type="Material" uid="uid://cykwajkj5aaqx" path="res://entities/weapons/grenade_launcher/assets/resources/particle_process_material_flash.tres" id="5_mntrp"]
[ext_resource type="Material" uid="uid://c78xg30ynapmt" path="res://entities/weapons/grenade_launcher/assets/resources/particle_process_material_fire.tres" id="6_s25g3"]
[sub_resource type="Curve" id="Curve_m5722"]
_data = [Vector2(0.247387, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="SphereShape3D" id="SphereShape3D_1htx7"]
radius = 10.6
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_dlm7y"]
emission_shape_offset = Vector3(0, 0.25, 0)
angle_min = -20.0
angle_max = 20.0
direction = Vector3(0, 1, 0)
initial_velocity_min = 2.0
initial_velocity_max = 2.0
gravity = Vector3(0, 0, 0)
damping_min = 1.0
damping_max = 1.0
color = Color(1.5, 1.5, 1.5, 1)
hue_variation_max = 0.05
anim_speed_min = 1.0
anim_speed_max = 1.0
[sub_resource type="QuadMesh" id="QuadMesh_35tvq"]
material = ExtResource("3_tsixm")
size = Vector2(5, 5)
[sub_resource type="QuadMesh" id="QuadMesh_wt5ts"]
material = ExtResource("4_634rq")
@ -17,18 +43,39 @@ material = ExtResource("4_634rq")
script = ExtResource("1_xb4jo")
explosive_damage = NodePath("ExplosiveDamage")
[node name="ExplosiveDamage" parent="." instance=ExtResource("2_rq8du")]
[node name="ExplosiveDamage" type="Area3D" parent="."]
collision_mask = 13
script = ExtResource("2_r5wb7")
damage = 128
blast_force = 2000
falloff = SubResource("Curve_m5722")
[node name="CollisionShape3D" type="CollisionShape3D" parent="ExplosiveDamage"]
shape = SubResource("SphereShape3D_1htx7")
[node name="Particles" type="Node3D" parent="."]
[node name="Explosion" type="GPUParticles3D" parent="Particles"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
emitting = false
amount = 1
lifetime = 2.0
one_shot = true
speed_scale = 3.0
fixed_fps = 60
draw_order = 3
process_material = SubResource("ParticleProcessMaterial_dlm7y")
draw_pass_1 = SubResource("QuadMesh_35tvq")
[node name="Sparks" type="GPUParticles3D" parent="Particles"]
process_priority = 1
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00311279, 0.0152655, -0.000196457)
emitting = false
amount = 20
amount = 12
lifetime = 0.3
one_shot = true
explosiveness = 1.0
fixed_fps = 60
randomness = 0.3
process_material = ExtResource("3_4u6ue")
draw_pass_1 = SubResource("QuadMesh_wt5ts")
@ -41,16 +88,3 @@ explosiveness = 1.0
fixed_fps = 60
process_material = ExtResource("5_mntrp")
draw_pass_1 = SubResource("QuadMesh_mv2qw")
[node name="Fire" type="GPUParticles3D" parent="Particles"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00311279, 0.0152655, -0.000196457)
emitting = false
amount = 13
lifetime = 0.55
one_shot = true
explosiveness = 1.0
fixed_fps = 60
process_material = ExtResource("6_s25g3")
draw_pass_1 = SubResource("QuadMesh_wt5ts")
[editable path="ExplosiveDamage"]

View file

@ -1,29 +1,39 @@
class_name GrenadeLauncher extends Node3D
# 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 GrenadeLauncher extends Weapon
@export_range(0, 24) var ammo : int = 24
@export var fire_rate : float = 1. # seconds
@export var reload_time : float = 1. # seconds
@export_category("Animations")
@export var _PROJECTILE : PackedScene
## The factor of velocity from the owner of this [Weapon] inherited by this [Projectile].
@export_range(0., 1., .01) var inheritance : float = 1.
@export var anim_player : AnimationPlayer
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
func trigger() -> void:
func _on_triggered() -> void:
# play the fire animation
anim_player.play("fire")
# init projectile
var projectile : Node3D = $ProjectileSpawner.new_projectile(
GrenadeLauncherProjectile,
owner.linear_velocity,
owner.match_participant
)
# add to owner of player for now
Global.type.add_child(projectile)
var projectile : GrenadeLauncherProjectile = _PROJECTILE.instantiate()
var direction: Vector3 = $Nozzle.global_basis.z.normalized()
projectile.velocity = direction * projectile.speed + owner.linear_velocity * inheritance
projectile.source = owner
owner.add_child(projectile)
projectile.global_position = $Nozzle.global_position
projectile.global_basis = $Nozzle.global_basis
projectile.shape_cast.add_exception(owner)
func _on_visibility_changed() -> void:
if self.visible:
anim_player.play("equip")
#anim_player.play("equip")
#self.sounds.play("equip")
pass

View file

@ -1,19 +1,17 @@
[gd_scene load_steps=5 format=3 uid="uid://cstl7yxc75572"]
[gd_scene load_steps=4 format=3 uid="uid://cstl7yxc75572"]
[ext_resource type="PackedScene" uid="uid://bbp260t2qivxk" path="res://entities/weapons/grenade_launcher/assets/models/grenade_launcher.glb" id="1_keuur"]
[ext_resource type="Script" path="res://entities/weapons/grenade_launcher/grenade_launcher.gd" id="2_38xn3"]
[ext_resource type="PackedScene" uid="uid://dak767xehqa6x" path="res://entities/weapons/grenade_launcher/projectile.tscn" id="3_rg5nk"]
[ext_resource type="Script" path="res://entities/components/projectile_spawner.gd" id="4_5h5sw"]
[node name="GrenadeLauncher" node_paths=PackedStringArray("anim_player") instance=ExtResource("1_keuur")]
script = ExtResource("2_38xn3")
_PROJECTILE = ExtResource("3_rg5nk")
inheritance = 0.8
anim_player = NodePath("AnimationPlayer")
[node name="ProjectileSpawner" type="Node3D" parent="." index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.266945)
script = ExtResource("4_5h5sw")
PROJECTILE = ExtResource("3_rg5nk")
inheritance = 0.75
ammo = 12
max_ammo = 12
ammo_usage = 1
[node name="barrel" parent="Armature/Skeleton3D" index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.19209e-07, 0)
@ -24,4 +22,8 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.082471, -0.0653242)
[node name="main" parent="Armature/Skeleton3D" index="2"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.19209e-07, 0)
[node name="Nozzle" type="Marker3D" parent="." index="2"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.259886)
[connection signal="triggered" from="." to="." method="_on_triggered"]
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]

View file

@ -12,46 +12,48 @@
#
# 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 RigidBody3D
class_name GrenadeLauncherProjectile extends ArcProjectile
@export_category("Parameters")
@export var EXPLOSION : PackedScene
@export var collider : CollisionShape3D
@export var speed : float = 44. # m/s
@export var lifespan : float = 1.6 # in seconds
## The time before
@export var fuse_time : float = 1.
@export_range(0., 1.) var bounce_velocity_modifier: float = .24
var shooter : MatchParticipant
var pending_explosion : bool = false
var fuse_timer := Timer.new()
## Called when the node enters the scene tree for the first time.
func _ready() -> void:
$Timer.wait_time = lifespan
$Timer.start()
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())
## This method enable collision signals to be emitted when the lifespan timer
## is finished.
func _on_timer_timeout() -> void:
max_contacts_reported = 1
set_contact_monitor(true)
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 is responsible for spawning the projectile explosion and freeing
## it when a collision is detected once the lifespan timer is finished.
func _on_body_entered(_body : Node) -> void:
var explosion : GrenadeLauncherProjectileExplosion = \
GrenadeLauncherProjectileExplosion.new_explosion(position, shooter, EXPLOSION)
add_sibling(explosion)
queue_free()
## 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 is a static factory constructor for the [GrenadeLauncherProjectile]
## scene of the [GrenadeLauncher].
static func new_projectile(
origin : Node3D,
inherited_velocity : Vector3,
_shooter : MatchParticipant,
scene : PackedScene
) -> GrenadeLauncherProjectile:
var projectile : GrenadeLauncherProjectile = scene.instantiate()
projectile.shooter = _shooter
projectile.transform = origin.global_transform
projectile.linear_velocity = origin.global_basis.z.normalized() * projectile.speed + inherited_velocity
return projectile
## 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

View file

@ -1,46 +1,30 @@
[gd_scene load_steps=7 format=3 uid="uid://dak767xehqa6x"]
[gd_scene load_steps=5 format=3 uid="uid://dak767xehqa6x"]
[ext_resource type="Script" path="res://entities/weapons/grenade_launcher/projectile.gd" id="1_i8v2u"]
[ext_resource type="PackedScene" uid="uid://bb43ae1f5j8lw" path="res://entities/weapons/grenade_launcher/explosion.tscn" id="2_cxty7"]
[ext_resource type="Script" path="res://addons/smoothing/smoothing.gd" id="3_wyge0"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_r263x"]
rough = true
bounce = 0.5
[sub_resource type="SphereShape3D" id="SphereShape3D_kipwv"]
radius = 0.062
[ext_resource type="Shape3D" uid="uid://b8d4jwso2dcdu" path="res://entities/weapons/grenade_launcher/assets/resources/projectile_shape.tres" id="3_fxdq6"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_miu4v"]
albedo_color = Color(0.2, 0.2, 0.2, 1)
[node name="GrenadeLauncherProjectile" type="RigidBody3D" node_paths=PackedStringArray("collider")]
collision_layer = 2147483648
collision_mask = 2147483648
mass = 5.0
physics_material_override = SubResource("PhysicsMaterial_r263x")
continuous_cd = true
[node name="GrenadeLauncherProjectile" type="Node3D"]
script = ExtResource("1_i8v2u")
EXPLOSION = ExtResource("2_cxty7")
collider = NodePath("CollisionShape3D")
speed = 54.0
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("SphereShape3D_kipwv")
[node name="ShapeCast3D" type="ShapeCast3D" parent="."]
shape = ExtResource("3_fxdq6")
target_position = Vector3(0, 0, 0)
collision_mask = 2147483649
[node name="Timer" type="Timer" parent="."]
one_shot = true
[node name="Smoothing" type="Node3D" parent="."]
[node name="Head" type="CSGSphere3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.000792712, 0, -0.000432983)
script = ExtResource("3_wyge0")
flags = 3
[node name="Mesh" type="CSGSphere3D" parent="Smoothing"]
radius = 0.062
radial_segments = 24
rings = 12
material = SubResource("StandardMaterial3D_miu4v")
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
[connection signal="body_shape_entered" from="." to="." method="_on_body_shape_entered"]
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
[node name="Body" type="CSGCylinder3D" parent="."]
transform = Transform3D(0.125, 0, -2.64698e-23, 2.64698e-23, -2.71011e-09, 0.125, 0, -0.062, -5.46392e-09, 0, 0, -0.062)
sides = 12
material = SubResource("StandardMaterial3D_miu4v")

View file

@ -0,0 +1,33 @@
# 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 SpaceGunProjectileExplosion extends Node3D
@export var explosive_damage : ExplosiveDamage
var source: Node:
set = set_source
func set_source(new_source: Node) -> void:
source = new_source
explosive_damage.source = new_source
@onready var particles : GPUParticles3D = $Fire
func _ready() -> void:
top_level = true
particles.emitting = true
particles.finished.connect(func() -> void: queue_free())
if source:
explosive_damage.source = source

View file

@ -0,0 +1,68 @@
[gd_scene load_steps=12 format=3 uid="uid://00uv1dfxlv47"]
[ext_resource type="Script" path="res://entities/weapons/space_gun/explosion.gd" id="1_3xpsk"]
[ext_resource type="Script" path="res://entities/projectiles/damages/explosive_damage.gd" id="2_beh8d"]
[sub_resource type="Curve" id="Curve_l54ao"]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_08dbu"]
curve = SubResource("Curve_l54ao")
[sub_resource type="Curve" id="Curve_21akj"]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_b4xy8"]
curve = SubResource("Curve_21akj")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_i271t"]
direction = Vector3(0, 1, 0)
spread = 180.0
initial_velocity_min = 24.0
initial_velocity_max = 24.0
scale_curve = SubResource("CurveTexture_08dbu")
turbulence_enabled = true
turbulence_influence_over_life = SubResource("CurveTexture_b4xy8")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_wpu51"]
albedo_color = Color(0.819608, 0, 0, 1)
emission_enabled = true
emission = Color(1, 0.254902, 0.109804, 1)
emission_energy_multiplier = 4.0
[sub_resource type="SphereMesh" id="SphereMesh_k7x87"]
material = SubResource("StandardMaterial3D_wpu51")
[sub_resource type="Curve" id="Curve_ck840"]
_data = [Vector2(0.254355, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="SphereShape3D" id="SphereShape3D_s611t"]
radius = 7.2
[node name="SpaceGunProjectileExplosion" type="Node3D" node_paths=PackedStringArray("explosive_damage")]
top_level = true
script = ExtResource("1_3xpsk")
explosive_damage = NodePath("ExplosiveDamage")
[node name="Fire" type="GPUParticles3D" parent="."]
emitting = false
amount = 24
lifetime = 0.5
one_shot = true
explosiveness = 1.0
fixed_fps = 60
process_material = SubResource("ParticleProcessMaterial_i271t")
draw_pass_1 = SubResource("SphereMesh_k7x87")
[node name="ExplosiveDamage" type="Area3D" parent="."]
collision_layer = 0
collision_mask = 13
script = ExtResource("2_beh8d")
damage = 102
falloff = SubResource("Curve_ck840")
[node name="CollisionShape3D" type="CollisionShape3D" parent="ExplosiveDamage"]
shape = SubResource("SphereShape3D_s611t")

View file

@ -12,63 +12,5 @@
#
# 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 SpaceGunProjectile extends Node3D
@export_category("Parameters")
@export var EXPLOSION : PackedScene
@export var speed : float = 78.4 # m/s
@export var lifespan : float = 5.0 # in seconds
@export var _time_to_trail_enable : float = 0.05 # in seconds
@onready var shape_cast : ShapeCast3D = $ShapeCast3D
@onready var game : Node3D = get_tree().get_current_scene()
@onready var projectile_trail : Trail3D = $Smoothing/ProjectileTrail
var velocity : Vector3 = Vector3.ZERO
var shooter : MatchParticipant
func _ready() -> void:
var lifespan_timer : Timer = Timer.new()
lifespan_timer.wait_time = lifespan
lifespan_timer.one_shot = true
lifespan_timer.autostart = true
lifespan_timer.timeout.connect(self_destruct)
add_child(lifespan_timer)
projectile_trail._trail_enabled = false
var trail_enable_timer : Timer = Timer.new()
trail_enable_timer.wait_time = _time_to_trail_enable
trail_enable_timer.one_shot = true
trail_enable_timer.autostart = true
trail_enable_timer.timeout.connect(_enable_trail)
add_child(trail_enable_timer)
func self_destruct() -> void:
explode(position)
func explode(spawn_position : Vector3) -> void:
game.add_child(SpaceGunProjectileExplosion.new_explosion(spawn_position, shooter, EXPLOSION))
queue_free()
func _physics_process(delta : float) -> void:
var previous_position : Vector3 = global_position
global_position += velocity * delta
shape_cast.target_position = to_local(previous_position)
if shape_cast.is_colliding():
var contact_point : Vector3 = shape_cast.collision_result[0].point
explode(contact_point)
## This method is a parameterized constructor for the [SpaceGunProjectile] scene of the [SpaceGun]
static func new_projectile(
origin : Marker3D,
inherited_velocity : Vector3,
_shooter : MatchParticipant,
scene : PackedScene
) -> SpaceGunProjectile:
var projectile : SpaceGunProjectile = scene.instantiate()
projectile.shooter = _shooter
projectile.transform = origin.global_transform
projectile.velocity = origin.global_basis.z.normalized() * projectile.speed + inherited_velocity
return projectile
func _enable_trail() -> void:
projectile_trail._trail_enabled = true
## This class defines the projectile of a [SpaceGun].
class_name SpaceGunProjectile extends ExplosiveProjectile

View file

@ -1,53 +1,47 @@
[gd_scene load_steps=8 format=3 uid="uid://dn1tcakam5egs"]
[gd_scene load_steps=7 format=3 uid="uid://61mogxsei3rq"]
[ext_resource type="Script" path="res://entities/weapons/space_gun/projectile.gd" id="1_4j1dp"]
[ext_resource type="PackedScene" path="res://entities/weapons/space_gun/projectile_explosion.tscn" id="2_llml6"]
[ext_resource type="Script" path="res://addons/smoothing/smoothing.gd" id="3_dmi64"]
[ext_resource type="Script" path="res://entities/weapons/space_gun/projectile_trail.gd" id="3_ygqbh"]
[sub_resource type="SphereShape3D" id="SphereShape3D_umtte"]
radius = 0.15
[ext_resource type="Script" path="res://entities/weapons/space_gun/projectile.gd" id="2_n6e2j"]
[ext_resource type="PackedScene" uid="uid://00uv1dfxlv47" path="res://entities/weapons/space_gun/explosion.tscn" id="2_s8tpq"]
[ext_resource type="Shape3D" uid="uid://dkhoeg2bwfbga" path="res://entities/weapons/space_gun/projectile_shape.tres" id="3_j3hyk"]
[ext_resource type="Script" path="res://entities/weapons/space_gun/projectile_trail.gd" id="4_ojig2"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o6j55"]
albedo_color = Color(0, 0.498039, 0.854902, 1)
emission_enabled = true
emission = Color(0.482353, 0.65098, 1, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4a265"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_wqkw2"]
transparency = 1
blend_mode = 1
cull_mode = 2
shading_mode = 0
vertex_color_use_as_albedo = true
[node name="Projectile" type="Node3D"]
script = ExtResource("1_4j1dp")
EXPLOSION = ExtResource("2_llml6")
[node name="SpaceGunProjectile" type="Node3D"]
top_level = true
script = ExtResource("2_n6e2j")
EXPLOSION = ExtResource("2_s8tpq")
speed = 78.4
lifespan = 6.0
[node name="ShapeCast3D" type="ShapeCast3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.2, 0, 0, 0, 1, 0, 0, 0)
shape = SubResource("SphereShape3D_umtte")
shape = ExtResource("3_j3hyk")
target_position = Vector3(0, 0, 0)
margin = 0.1
max_results = 1
collision_mask = 2147483649
collide_with_areas = true
debug_shape_custom_color = Color(1, 0, 0, 1)
[node name="Smoothing" type="Node3D" parent="."]
script = ExtResource("3_dmi64")
target = NodePath("..")
[node name="Mesh" type="CSGSphere3D" parent="Smoothing"]
[node name="Mesh" type="CSGSphere3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.2, 0, 0, 0, 1, 0, 0, 0)
radius = 0.15
radial_segments = 24
rings = 8
material = SubResource("StandardMaterial3D_o6j55")
[node name="ProjectileTrail" type="MeshInstance3D" parent="Smoothing"]
material_override = SubResource("StandardMaterial3D_4a265")
skeleton = NodePath("../..")
script = ExtResource("3_ygqbh")
[node name="ProjectileTrail" type="MeshInstance3D" parent="."]
material_override = SubResource("StandardMaterial3D_wqkw2")
script = ExtResource("4_ojig2")
_start_width = 0.15
_lifespan = 0.25
_start_color = Color(0, 0.498039, 0.854902, 1)

View file

@ -1,38 +0,0 @@
# 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 SpaceGunProjectileExplosion extends Node3D
@export var explosive_damage : ExplosiveDamageComponent
@onready var fire : GPUParticles3D = $Fire
var explosion_effect_pending : bool = false
var shooter : MatchParticipant:
set(value):
shooter = value
assert(explosive_damage)
explosive_damage.damage_dealer = value
func _ready() -> void:
fire.emitting = true
fire.finished.connect(func() -> void: queue_free())
## This method is a parameterized constructor for the [SpaceGunProjectileExplosion] scene of the [SpaceGunProjectile]
static func new_explosion(spawn_position : Vector3, _shooter : MatchParticipant, scene : PackedScene) -> SpaceGunProjectileExplosion:
var explosion : SpaceGunProjectileExplosion = scene.instantiate()
explosion.shooter = _shooter
explosion.position = spawn_position
return explosion

View file

@ -1,44 +0,0 @@
[gd_scene load_steps=8 format=3 uid="uid://8atq41j7wd55"]
[ext_resource type="Script" path="res://entities/weapons/space_gun/projectile_explosion.gd" id="1_fp5td"]
[ext_resource type="PackedScene" uid="uid://qb5sf7awdeui" path="res://entities/components/explosive_damage/explosive_damage.tscn" id="2_js0ht"]
[sub_resource type="Curve" id="Curve_rg204"]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_08dbu"]
curve = SubResource("Curve_rg204")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_3mf41"]
spread = 180.0
initial_velocity_min = 12.0
initial_velocity_max = 12.0
scale_curve = SubResource("CurveTexture_08dbu")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_wpu51"]
albedo_color = Color(0.819608, 0, 0, 1)
emission_enabled = true
emission = Color(1, 0.254902, 0.109804, 1)
emission_energy_multiplier = 4.0
[sub_resource type="SphereMesh" id="SphereMesh_k3pnh"]
material = SubResource("StandardMaterial3D_wpu51")
[node name="ProjectileExplosion" type="Node3D" node_paths=PackedStringArray("explosive_damage")]
script = ExtResource("1_fp5td")
explosive_damage = NodePath("ExplosiveDamage")
[node name="Fire" type="GPUParticles3D" parent="."]
emitting = false
amount = 24
lifetime = 0.5
one_shot = true
explosiveness = 1.0
fixed_fps = 60
process_material = SubResource("ParticleProcessMaterial_3mf41")
draw_pass_1 = SubResource("SphereMesh_k3pnh")
[node name="ExplosiveDamage" parent="." instance=ExtResource("2_js0ht")]
[editable path="ExplosiveDamage"]

View file

@ -0,0 +1,4 @@
[gd_resource type="SphereShape3D" format=3 uid="uid://dkhoeg2bwfbga"]
[resource]
radius = 0.15

View file

@ -12,40 +12,26 @@
#
# 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 SpaceGun extends Node3D
## This class defines a SpaceGun.
class_name SpaceGun extends Weapon
@export var fire_rate : float = 1. # seconds
@export var reload_time : float = 1. # seconds
@export var _PROJECTILE : PackedScene
## The factor of velocity from the owner of this [Weapon] inherited by this [Projectile].
@export_range(0., 1., .01) var inheritance : float = 1.
@export var anim_player : AnimationPlayer
enum WeaponState { WEAPON_READY, WEAPON_RELOADING }
var state : WeaponState = WeaponState.WEAPON_READY
func can_fire() -> bool:
return state == WeaponState.WEAPON_READY
func trigger() -> void:
# check permission
if not can_fire():
return
func _on_triggered() -> void:
# play the fire animation
anim_player.play("fire")
var projectile : Node3D = $ProjectileSpawner.new_projectile(
SpaceGunProjectile,
owner.linear_velocity,
owner.match_participant
)
# add to owner of player for now
Global.type.add_child(projectile)
# ensure projectile does not collide with owner
var collider : ShapeCast3D = projectile.shape_cast
collider.add_exception(owner)
# update states
state = WeaponState.WEAPON_RELOADING
await get_tree().create_timer(reload_time).timeout
state = WeaponState.WEAPON_READY
var projectile : SpaceGunProjectile = _PROJECTILE.instantiate()
projectile.velocity = projectile.speed * $Nozzle.global_basis.z.normalized() + owner.linear_velocity * inheritance
projectile.source = owner
owner.add_child(projectile)
projectile.global_transform = $Nozzle.global_transform
projectile.shape_cast.add_exception(owner)
func _on_visibility_changed() -> void:
if self.visible:
anim_player.play("equip")
#self.sounds.play("equip")
#anim_player.play("equip")
#sounds.play("equip")
pass

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,64 @@
# 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 class defines a [Weapon].
class_name Weapon extends Node3D
## Emitted after [member Weapon.trigger] is called.
signal triggered
## Emitted when [member ammo] is changed (useful for [HUD] display).
signal ammo_changed(new_ammo: int)
# enum WeaponState { EQUIPPED, UNEQUIPPED }
## The ammunition count.
@export_range(0, 9223372036854775295) var ammo: int:
set = set_ammo
@rpc("authority", "call_local", "reliable")
func set_ammo(new_ammo: int) -> void:
ammo = new_ammo
ammo_changed.emit(new_ammo)
## The maxmimum ammunition count.
@export_range(0, 9223372036854775295) var max_ammo: int
## The number of ammo used when [member triggered] is emitted.
@export_range(0, 9223372036854775295) var ammo_usage: int
## The cooldown until this [Weapon] can be triggered again.
@export var cooldown: float = 1.
## The internal timer to handle trigger cooldown
var _cooldown_timer: Timer
func _init() -> void:
_cooldown_timer = Timer.new()
_cooldown_timer.one_shot = true
_cooldown_timer.wait_time = cooldown
add_child(_cooldown_timer)
## This methods triggers the [Weapon].
func trigger() -> void:
if not _cooldown_timer.is_stopped() or ammo < ammo_usage:
return
# deduct ammo_usage from ammo count
ammo -= ammo_usage
# start cooldown timer
_cooldown_timer.start(cooldown)
# emit triggered signal
triggered.emit()
# primary action handler
func _on_primary(pressed: bool) -> void:
if pressed: trigger()