extends Node3D var start_position var start_rotation var random_spread_start var cycle_count_start var cycle_count @export_group("Gun Feel") @export var gun_name : String @export_enum("Auto", "Single", "Burst") var fire_mode: int @export var fov_zoom_amt = .98 @export var recoil_amount : Vector3 = Vector3(1,.1,.1) @export var recoil_speed_change : float = 4 @export var max_ammo = 15 @export var start_mags = 3 @export var bullet_damage = 1 @export var kick_amount = 1 @export var bullet_force_mod = 5 @export var bullet_speed = 150 @export var bullet_drop = .3 @export var random_spread_amt = 1.0 @export var fire_pitch_scale_amt = .2 @export_group("Gun Assets") @export_subgroup("Main Assets") @export var r_hand_location : Node @export var l_hand_location : Node @export var chamber : Node @export var bullet : Resource @export var bullethole : Resource @export var spawn_casing : Resource @export_subgroup("Revolver/Casings") @export var casing0 : Node @export var casing1 : Node @export var casing2 : Node @export var casing3 : Node @export var casing4 : Node @export var casing5 : Node @export var casing_spawn0 : Node @export var casing_spawn1 : Node @export var casing_spawn2 : Node @export var casing_spawn3 : Node @export var casing_spawn4 : Node @export var casing_spawn5 : Node @export_subgroup("Revolver/Bullets") @export var bullet0 : Node @export var bullet1 : Node @export var bullet2 : Node @export var bullet3 : Node @export var bullet4 : Node @export var bullet5 : Node @export_subgroup("Raycast Nodes") @export var anim_player : Node @export var barrel_raycast : Node @export_subgroup("Audio Clips") @export var audio_fire : Node @export var audio_empty : Node @export var audio_reload : Node @onready var player = get_tree().current_scene.player @onready var level_control = get_tree().current_scene @onready var ammo_current var casing_array = [] var casing_spawn_array = [] var bullet_array = [] var rng = RandomNumberGenerator.new() var gun_index var casings_chamber_last #var ammo_current var ammo_reserve # Called when the node enters the scene tree for the first time. func _ready(): start_position = self.position start_rotation = self.rotation random_spread_start = random_spread_amt ammo_current = level_control.ammo_current[gun_index] ammo_reserve = level_control.ammo_reserve[gun_index] casings_chamber_last = max_ammo casing_array = [casing0,casing1,casing2,casing3,casing4,casing5] casing_spawn_array = [casing_spawn0,casing_spawn1,casing_spawn2,casing_spawn3,casing_spawn4,casing_spawn5] bullet_array = [bullet0,bullet1,bullet2,bullet3,bullet4,bullet5] if fire_mode == 0: cycle_count = 1 cycle_count_start = 1 elif fire_mode == 1: cycle_count = 1 cycle_count_start = 1 elif fire_mode == 2: cycle_count = 3 cycle_count_start = 3 # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): pass func reload_finished(): #if max ammo in reserve fill all the way if level_control.ammo_reserve[gun_index] >= max_ammo: level_control.ammo_current[gun_index] += max_ammo level_control.ammo_reserve[gun_index] -= max_ammo casings_chamber_last = max_ammo for i in casing_array: i.visible = true for i in bullet_array: i.visible = true player.reloading = false #if not max ammo in reserve add remaining ammo else: level_control.ammo_current[gun_index] += level_control.ammo_reserve[gun_index] var casings_in_chamber = level_control.ammo_reserve[gun_index] casings_chamber_last = level_control.ammo_reserve[gun_index] level_control.ammo_reserve[gun_index] -= level_control.ammo_reserve[gun_index] while casings_in_chamber > 0: casing_array[casings_in_chamber].visible = true bullet_array[casings_in_chamber].visible = true casings_in_chamber -= 1 await get_tree().create_timer(.01).timeout player.reloading = false func shoot(delta): if level_control.ammo_current[gun_index] > 0 and cycle_count > 0: if !anim_player.is_playing(): level_control.ammo_current[gun_index] -= 1 audio_fire.pitch_scale = 1 + rng.randf_range(-fire_pitch_scale_amt,fire_pitch_scale_amt) audio_fire.play() anim_player.play("shoot") #actual bullet spawn triggered by animation player.velocity += player.bullet_ray.global_basis * Vector3(0,0, kick_amount) if fire_mode != 0: cycle_count -= 1 elif !anim_player.is_playing() and cycle_count != 0: anim_player.play("empty") audio_empty.play() func fire(delta): var instance_bullet = bullet.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_raycast.global_transform.basis instance_bullet.bullet_speed = bullet_speed instance_bullet.bullet_drop = bullet_drop instance_bullet.bullet_damage = bullet_damage instance_bullet.random_spread_amt = random_spread_amt instance_bullet.bullet_force_mod = bullet_force_mod instance_bullet.player_position = player.global_position instance_bullet.player_velocity = (player.velocity * player.transform.basis) instance_bullet.instance_bullethole = bullethole.instantiate() get_tree().get_root().add_child(instance_bullet) player.recoil.add_recoil(Vector3(0,recoil_amount.y,recoil_amount.z),10,recoil_speed_change) player.recoil.add_gun_recoil(recoil_amount.x) chamber.rotate_object_local(Vector3(0,-1,0),deg_to_rad(60)) func reload(delta): if level_control.ammo_current[gun_index] < max_ammo and player.gun.anim_player.get_current_animation() != "reload" and level_control.ammo_reserve[gun_index] > 0: anim_player.play("reload") audio_reload.play() for i in bullet_array: i.visible = false if anim_player.is_playing() and anim_player.current_animation == "reload": level_control.ammo_current[gun_index] = 0 func spawn_casings(): for i in casing_array: i.visible = false if casings_chamber_last > 0: var instance_casing = spawn_casing.instantiate() instance_casing.position = i.global_position instance_casing.random_rotation = false instance_casing.transform.basis = i.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 + rng.randf_range(0,3)) get_tree().get_root().add_child(instance_casing) casings_chamber_last -= 1 func swapped_out(): queue_free()