Files
fps_project_1/scripts/player.gd
2024-07-17 10:53:24 -05:00

276 lines
9.1 KiB
GDScript

extends CharacterBody3D
var speed
var double_jump = true
var gravity = 9.8
var mouse_input : Vector2
var rng = RandomNumberGenerator.new()
@export_group("Game Settings")
@export var AUDIO = true
@export_group("Player Movement")
@export var WALK_SPEED = 7.0
@export var SPRINT_SPEED = 15.0
@export var JUMP_VELOCITY = 10
@export var SENSITIVITY = .01
@export var sensitivity_shift = true
var start_sensitivity
@export_subgroup("Head Bob & Gun Sway")
@export var BOB_FREQ = 2.0
@export var BOB_AMP = 0.08
@export var t_bob = 1.0
@export var weapon_holder : Node3D
@export var weapon_sway_amount : float = 5
@export var weapon_rotation_amount : float = 1
@export_subgroup("FOV")
@export var BASE_FOV : float = 80
@export var FOV_CHANGE = 1.5
@export_group("Gun")
@export var gun : Node
@onready var gun_ray = $Head/Camera3D/GunRay
@onready var level_control = $".."
@onready var bullet_ray = $Head/Camera3D/BulletRay
var instance_bullet
var instance_casing
var instance_mag
var reloading = false
var ammo
var ammo_reserve
var bullet_damage
var def_weapon_holder_pos : Vector3
var gun_folded = false
var recoiling_fade = 0
var bullet_destination
var gun_fire_pitch_starting
var current_weapon_index
# Slow Down Variables
const SLOWSPEED = .2
const MAX_STAMINA = 1800
const STAMINA_DRAIN = 100
var remaining_stamina = MAX_STAMINA
# Pickups
var picked_up = false
var picked_up_text
var pickup_announce = load("res://assets/pickup_announce.tscn")
var pickupmsg
@onready var crosshair = $Head/Camera3D/Crosshair
@onready var head = $Head
@onready var camera = $Head/Camera3D
@onready var world_environment = $"../WorldEnvironment"
@onready var pickup_sound = $Audio/PickupSound
@onready var ear_wind = $Audio/EarWind
@onready var weapon_spawner = $Head/Camera3D/WeaponHolder/WeaponSpawner
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
start_sensitivity = SENSITIVITY
#turn off audio if unchecked in player
if AUDIO == false:
AudioServer.set_bus_volume_db(0,-80)
func _unhandled_input(event):
if event is InputEventMouseMotion:
self.rotate_y(-event.relative.x * SENSITIVITY)
camera.rotate_x(-event.relative.y * SENSITIVITY)
camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-90), deg_to_rad(60))
mouse_input = event.relative
func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y -= gravity * delta
else:
double_jump = true
# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y += JUMP_VELOCITY
elif Input.is_action_just_pressed("jump") and double_jump == true:
velocity.y += JUMP_VELOCITY
double_jump = false
# Handle Sprint
if Input.is_action_pressed("sprint") and is_on_floor():
speed = SPRINT_SPEED
else:
speed = WALK_SPEED
# Get the input direction and handle the movement/deceleration.
var input_dir = Input.get_vector("move_left", "move_right", "move_up", "move_down")
var direction = (self.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if is_on_floor():
if direction:
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = lerp(velocity.x, direction.x * speed, delta * 3.0)
velocity.z = lerp(velocity.z, direction.z * speed, delta * 3.0)
else:
velocity.x = lerp(velocity.x, direction.x * speed, delta * 3.0)
velocity.z = lerp(velocity.z, direction.z * speed, delta * 3.0)
# Head bob
t_bob += delta * velocity.length() * float(is_on_floor())
camera.transform.origin = _headbob(t_bob)
# FOV
var velocity_clamped = clamp(velocity.length(), 0.5, SPRINT_SPEED * 2)
var target_fov = BASE_FOV + FOV_CHANGE * velocity_clamped
camera.fov = lerp(camera.fov, target_fov, delta * 8)
# Land sound
# Game Speed
if Input.is_action_pressed("slow_down") and remaining_stamina >0:
Engine.time_scale = lerp(0, 1, SLOWSPEED)
gun.random_spread_amt = 0
AudioServer.set_bus_effect_enabled(0,0,true)
camera.fov = lerp(camera.fov, camera.fov * gun.fov_zoom_amt, delta * 100)
if sensitivity_shift == true:
SENSITIVITY = lerp(SENSITIVITY, SENSITIVITY * .998, delta * 100)
if remaining_stamina >0:
remaining_stamina -= 1000 * delta
else:
Engine.time_scale = 1
gun.random_spread_amt = gun.random_spread_start
AudioServer.set_bus_effect_enabled(0,0,false)
if sensitivity_shift == true:
camera.fov = lerp(camera.fov, BASE_FOV, delta * .5)
SENSITIVITY = start_sensitivity
if remaining_stamina < MAX_STAMINA:
remaining_stamina += STAMINA_DRAIN * delta
elif remaining_stamina > MAX_STAMINA * 1.01:
remaining_stamina -= (STAMINA_DRAIN)/2 * delta
# Reloading
if Input.is_action_just_pressed("reload"):
gun.reload(self,delta)
if Input.is_action_pressed("inspect") and !gun.anim_player.is_playing():
gun.anim_player.play("inspect")
# Shooting & fire modes
if Input.is_action_pressed("shoot"):
gun.shoot(self,delta)
if Input.is_action_just_released("shoot"):
gun.cycle_count = gun.cycle_count_start
# Gun folding out of the way
if gun_ray.is_colliding() and !gun_ray.get_collider().is_in_group("player"):
#check distance to wall later ?
gun.rotation = lerp(gun.rotation, Vector3(1, 1, -.25), delta * 10)
gun.position = lerp(gun.position, Vector3(gun.start_position.x-.25,gun.start_position.y +.2,gun.start_position.z +.6),(delta*10))
gun_folded = true
elif !gun_ray.is_colliding():
gun.rotation = lerp(gun.rotation, gun.start_rotation,delta*7)
gun.position = lerp(gun.position, gun.start_position,delta*7)
gun_folded = false
#Weapon Swap Up
if Input.is_action_just_pressed("scroll_up") and !gun.anim_player.is_playing():
gun.anim_player.play("swap_out")
level_control.gun_spawn(level_control.current_gun_index + 1)
#Weapon Swap Down
if Input.is_action_just_pressed("scroll_down") and !gun.anim_player.is_playing():
gun.anim_player.play("swap_out")
level_control.gun_spawn(level_control.current_gun_index - 1)
#quit game and eventually go to menu
if Input.is_action_pressed("escape"):
get_tree().quit()
move_and_slide()
weapon_tilt(input_dir.x, delta)
weapon_sway(delta)
weapon_bob(velocity.length(), delta)
func _headbob(time) -> Vector3:
var pos = Vector3.ZERO
pos.y = sin(time * BOB_FREQ) * BOB_AMP
pos.x = cos(time * BOB_FREQ / 2) * BOB_AMP
return pos
func _on_pick_up_detection_body_entered(body):
if body.pickupType == "stamina":
pickupmsg = pickup_announce.instantiate()
pickupmsg.pickuptext = "stamina"
get_parent().add_child(pickupmsg)
remaining_stamina += (body.rand_amt/100) * MAX_STAMINA
pickup_sound.pitch_scale = 1 + rng.randf_range(-.3,.3)
pickup_sound.play()
body.queue_free()
elif body.pickupType == "ammo":
pickupmsg = pickup_announce.instantiate()
pickupmsg.pickuptext = "ammo"
get_parent().add_child(pickupmsg)
level_control.ammo_reserve[level_control.current_gun_index] += int((body.rand_amt/100) * gun.max_ammo)
picked_up = true
picked_up_text = "ammo"
pickup_sound.pitch_scale = 1 + rng.randf_range(-.3,.3)
pickup_sound.play()
body.queue_free()
elif body.pickupType == "jump":
pickupmsg = pickup_announce.instantiate()
pickupmsg.pickuptext = "jump"
get_parent().add_child(pickupmsg)
double_jump = true
picked_up = true
picked_up_text = "double jump"
pickup_sound.pitch_scale = 1 + rng.randf_range(-.3,.3)
pickup_sound.play()
body.queue_free()
elif body.pickupType == "weapon":
pickup_sound.pitch_scale = 1 + rng.randf_range(-.3,.3)
pickup_sound.play()
level_control.held_guns.append(body.gun_resource)
var instance_gun = body.gun_resource.instantiate()
level_control.ammo_current.append(instance_gun.max_ammo)
level_control.ammo_reserve.append(instance_gun.max_ammo * instance_gun.start_mags)
body.queue_free()
var weapon_id = level_control.held_guns.size() - 1
gun.anim_player.play("swap_out")
level_control.gun_spawn(weapon_id)
func _on_pick_up_magnet_body_entered(body):
if body.is_in_group("pickup") and body.is_in_group("magnet"):
body.player = self
func weapon_tilt(input_x, delta):
if weapon_holder:
weapon_holder.rotation.z = lerp(weapon_holder.rotation.z, -input_x * weapon_rotation_amount * 10, 10 * delta)
func weapon_sway(delta):
mouse_input = lerp(mouse_input, Vector2.ZERO, 10 * delta)
weapon_holder.rotation.x = lerp(weapon_holder.rotation.x, mouse_input.y * weapon_rotation_amount, 5 * delta)
weapon_holder.rotation.y = lerp(weapon_holder.rotation.y, mouse_input.x * weapon_rotation_amount, 5 * delta)
func weapon_bob(vel : float, delta):
if weapon_holder:
if vel > 2 and is_on_floor():
var bob_amount : float = 0.05
var bob_freq : float = 0.01
weapon_holder.position.y = lerp(weapon_holder.position.y, def_weapon_holder_pos.y + sin(Time.get_ticks_msec() * bob_freq) * bob_amount, 10 * delta)
weapon_holder.position.x = lerp(weapon_holder.position.x, def_weapon_holder_pos.x + sin(Time.get_ticks_msec() * bob_freq) * bob_amount, 10 * delta)
else:
weapon_holder.position.y = lerp(weapon_holder.position.y, def_weapon_holder_pos.y, .1 * delta)
weapon_holder.position.x = lerp(weapon_holder.position.x, def_weapon_holder_pos.x, .1 * delta)
func weapon_recoil():
var recoil_to = camera.rotation.x + gun.recoil_amount
camera.rotation.x = clamp(lerp(camera.rotation.x,recoil_to, .05), deg_to_rad(-90), deg_to_rad(60))