Files
fps_project_1/scripts/weapon_uberscript.gd
2025-03-19 14:25:21 -05:00

301 lines
11 KiB
GDScript

extends Node3D
class_name weapon
@export var weapon_info : weapon_resource
@export var anim_player : AnimationPlayer
@export var barrel_ray : RayCast3D
@export var casing_ejector : RayCast3D
@export var mag_ejector : RayCast3D
@export var audio_fire : AudioStreamPlayer3D
@export var audio_empty : AudioStreamPlayer3D
@export var audio_reload : AudioStreamPlayer3D
@export_group("Barrel Smoke")
@export var fire_smoke : GPUParticles3D
@export var smoke_timer : Timer
@export_group("Revolver")
@export var casing_array : Array[MeshInstance3D]
@export var bullet_array : Array[MeshInstance3D]
@export var chamber : Node
@export_group("Melee")
@export var melee_collision_shape : Node
@export_group("Tracker Gun")
@export var looking_mesh : Node
@onready var player = get_tree().current_scene.player
# Revolver vars
var revolver_chamber_rot_amt = 0
var casings_chamber_last
# Tracker vars
var tracker
var check_track
const TRACKER_ASSIGNED_COLOR: Color = Color(0, 0.853, 0, 1)
const TRACKER_NULL_COLOR :Color = Color(0.743, 0.359, 0, 1)
var remaining_ammo
var start_position
var start_rotation
var cycle_count_start
var cycle_count
# Called when the node enters the scene tree for the first time.
func _ready():
if melee_collision_shape != null:
melee_collision_shape.disabled = true
if weapon_info.weapon_type != 1:
casings_chamber_last = weapon_info.max_ammo
if weapon_info.fire_mode == 0:
cycle_count_start = 1
elif weapon_info.fire_mode == 1:
cycle_count_start = 1
elif weapon_info.fire_mode == 2:
cycle_count_start = 3
cycle_count = cycle_count_start
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
if chamber != null:
var rot_amount = revolver_chamber_rot_amt * _delta * 10
chamber.rotate_object_local(Vector3(0,-1,0),deg_to_rad(rot_amount))
revolver_chamber_rot_amt -= rot_amount
if Input.is_action_just_released("shoot"):
cycle_count = cycle_count_start
if weapon_info.weapon_type == 2:
if tracker != null:
weapon_info.tracker_asset.tracker_indicator_material.emission = TRACKER_ASSIGNED_COLOR
if looking_mesh != null:
looking_mesh.look_at(tracker.global_position)
else:
weapon_info.tracker_asset.tracker_indicator_material.emission = TRACKER_NULL_COLOR
looking_mesh.rotation = lerp(rotation, Vector3(0,0,0), _delta * 4)
if check_track:
tracker_checker(_delta)
func reload_finished():
match weapon_info.reload_type:
0: #MAGAZINE
#calculate ammo to add from reserve --- discards ammo in previous mag
var ammo_added = clamp(weapon_info.max_ammo,1,GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)])
#add to gun and remove from reserve
GameGlobals.gun_ammo[weapon_info.gun_name] += ammo_added
GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)] -= ammo_added
1: #REVOLVER
#calculate ammo to add from reserve --- only pulls from what it is missing
var ammo_needed = weapon_info.max_ammo - GameGlobals.gun_ammo[weapon_info.gun_name]
var ammo_added = clamp(ammo_needed,1,GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)])
#add to gun and remove from reserve
GameGlobals.gun_ammo[weapon_info.gun_name] += ammo_added
GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)] -= ammo_added
#make the added-back casings visible
var index = 0
while index <= (ammo_added - 1):
if index < bullet_array.size():
bullet_array[index].visible = true
if index < casing_array.size():
casing_array[index].visible = true
index += 1
func shoot():
if weapon_info.weapon_type == 0:
if GameGlobals.gun_ammo[weapon_info.gun_name] > 0 and cycle_count > 0:
if !anim_player.is_playing():
GameGlobals.gun_ammo[weapon_info.gun_name] -= 1
if weapon_info.fire_mode != 0:
cycle_count -= 1
#audio and anims
anim_player.play("shoot")
elif !anim_player.is_playing() and cycle_count != 0:
anim_player.play("empty")
audio_empty.play()
elif weapon_info.weapon_type == 1:
if !anim_player.is_playing():
#audio and anims
anim_player.play("shoot")
vibration()
player.recoil.add_recoil(Vector3(0,weapon_info.recoil_amount.y,weapon_info.recoil_amount.z),10,10)
player.recoil.add_gun_recoil(weapon_info.recoil_amount.x)
elif weapon_info.weapon_type == 2:
if !anim_player.is_playing():
if tracker == null and Input.is_action_just_pressed("shoot"):
check_track = true
weapon_info.tracker_check_mesh.visible = true
weapon_info.tracker_check_mesh.anim_player.play("check")
if tracker != null and !check_track:
anim_player.play("shoot")
func reload():
match weapon_info.weapon_type:
0:
match weapon_info.reload_type:
0:
if GameGlobals.gun_ammo[weapon_info.gun_name] < weapon_info.max_ammo and anim_player.get_current_animation() != "reload" and GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)] > 0:
anim_player.play("reload")
audio_reload.play()
if anim_player.is_playing() and anim_player.current_animation == "reload":
if GameGlobals.gun_ammo[weapon_info.gun_name] == 0:
GameGlobals.gun_ammo[weapon_info.gun_name] = 0
else:
GameGlobals.gun_ammo[weapon_info.gun_name] = 1
1:
if GameGlobals.gun_ammo[weapon_info.gun_name] < weapon_info.max_ammo and anim_player.get_current_animation() != "reload" and GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)] > 0:
anim_player.play("reload")
audio_reload.play()
func spawn_mag():
var instance_mag = weapon_info.mag.instantiate()
instance_mag.position = mag_ejector.global_position
instance_mag.transform.basis = mag_ejector.global_transform.basis
instance_mag.linear_velocity += transform.basis * Vector3(0, -20, 0) + player.velocity
get_tree().get_root().add_child(instance_mag)
func spawn_casing():
if weapon_info.casing != null and casing_ejector != null:
# Casing transform
var instance_casing = weapon_info.casing.instantiate()
instance_casing.position = casing_ejector.global_position
instance_casing.transform.basis = casing_ejector.global_transform.basis
instance_casing.player_velocity = player.velocity * transform.basis
get_tree().get_root().add_child(instance_casing)
func spawn_revolver_casings():
if casing_array.size() > 0:
var ammo_needed = weapon_info.max_ammo - GameGlobals.gun_ammo[weapon_info.gun_name]
var index = 0
while index <= ammo_needed - 1:
if index < bullet_array.size():
bullet_array[index].visible = false
if index < casing_array.size():
casing_array[index].visible = false
var instance_casing = weapon_info.casing.instantiate()
instance_casing.position = casing_array[index].global_position
instance_casing.random_rotation = false
instance_casing.transform.basis = casing_array[index].global_transform.basis
instance_casing.player_velocity = player.velocity * transform.basis
instance_casing.rotation.x += deg_to_rad(90)
instance_casing.linear_velocity.y = -(8 + randf_range(0,3))
get_tree().get_root().add_child(instance_casing)
index += 1
func fire_tracker():
var instance_tracker = weapon_info.tracker_asset.instantiate()
get_tree().current_scene.add_child(instance_tracker)
if player.bullet_ray.is_colliding():
var spawn_loc = player.bullet_ray.get_collision_point()
var spawn_parent = player.bullet_ray.get_collider()
if spawn_parent != null:
spawn_parent.add_child(instance_tracker)
instance_tracker.global_transform.origin = spawn_loc
instance_tracker.anim_player.play("mark")
tracker = instance_tracker
func tracker_checker(_delta):
if player.bullet_ray.is_colliding():
var tracker_check_mesh = weapon_info.tracker_asset.instantiate()
var spawn_loc = player.bullet_ray.get_collision_point()
var distance_to_point = self.global_position.distance_to(spawn_loc)
var scale_adjusted = distance_to_point/5
tracker_check_mesh.global_transform.origin = spawn_loc
tracker_check_mesh.global_rotation = Vector3(0,0,0)
tracker_check_mesh.scale = Vector3(scale_adjusted,scale_adjusted,scale_adjusted)
if check_track == true and Input.is_action_just_released("shoot"):
fire_tracker()
check_track = false
func shotgun_pellet_spawn():
SignalBus.emit_signal("shot_fired",weapon_info.crosshair_jump_amount)
audio_fire.play()
spawn_casing()
var pellets_remaining = weapon_info.pellets_per_shot
while pellets_remaining > 0:
var lv_x = randf_range(-weapon_info.shotgun_spread.x,weapon_info.shotgun_spread.x)
var lv_y = randf_range(-weapon_info.shotgun_spread.y,weapon_info.shotgun_spread.y)
# instance bullet
var instance_bullet = projectile_initialize()
instance_bullet.linear_velocity += instance_bullet.transform.basis * Vector3(lv_x, lv_y, -weapon_info.bullet_speed) + player.velocity
get_tree().get_root().add_child(instance_bullet)
pellets_remaining -= 1
vibration()
if fire_smoke != null:
fire_smoke.restart()
fire_smoke.emitting = true
smoke_timer.start()
player.recoil.add_recoil(Vector3(0,weapon_info.recoil_amount.y,weapon_info.recoil_amount.z),10,10)
player.recoil.add_gun_recoil(weapon_info.recoil_amount.x)
player.velocity += player.bullet_ray.global_basis * Vector3(0,0, weapon_info.kick_amount)
SignalBus.emit_signal("shot_fired")
func spawn_muzzle_smoke():
var instance_smoke = weapon_info.muzzle_smoke.instantiate()
instance_smoke.global_transform.basis = barrel_ray.global_transform.basis
add_child(instance_smoke)
func projectile_initialize():
var instance_bullet = weapon_info.bullet.asset.instantiate()
instance_bullet.position = player.bullet_ray.global_position
#shoot bullet from real gun if gun is folded up
if player.gun_folded == false:
instance_bullet.transform.basis = player.bullet_ray.global_transform.basis
else:
instance_bullet.transform.basis = barrel_ray.global_transform.basis
instance_bullet.bullet_speed = weapon_info.bullet_speed
instance_bullet.player_velocity = player.velocity * transform.basis
instance_bullet.bullet_damage = weapon_info.bullet_damage
instance_bullet.blast_power = weapon_info.blast_power
instance_bullet.bullet_force_mod = weapon_info.bullet_force_mod
if weapon_info.bullet.bullet_hole != null:
instance_bullet.instance_bullethole = weapon_info.bullet.bullet_hole.instantiate()
instance_bullet.player_position = player.global_position
return instance_bullet
func bullet_fire():
SignalBus.emit_signal("shot_fired",weapon_info.crosshair_jump_amount)
audio_fire.play()
get_tree().current_scene.add_child(projectile_initialize())
spawn_casing()
vibration()
if chamber != null:
revolver_chamber_rot_amt += weapon_info.chamber_rot_amount
if weapon_info.smoke_enabled:
spawn_muzzle_smoke()
player.recoil.add_recoil(Vector3(0,weapon_info.recoil_amount.y,weapon_info.recoil_amount.z),10,10)
player.recoil.add_gun_recoil(weapon_info.recoil_amount.x)
SignalBus.emit_signal("shot_fired")
func can_fire():
if anim_player.is_playing() and anim_player.current_animation == "reload":
return false
else:
return true
func hitscan_fire():
# Fire hitscan
pass
func swapped_out():
queue_free()
func melee_collider_enable():
melee_collision_shape.disabled = false
func melee_collider_disable():
melee_collision_shape.disabled = true
func vibration():
Input.start_joy_vibration(0,weapon_info.vibration_weak_magnitude,weapon_info.vibration_strong_magnitude,weapon_info.vibration_duration)