189 lines
5.7 KiB
GDScript
189 lines
5.7 KiB
GDScript
extends Spatial
|
|
class_name TPSController
|
|
|
|
# debug camera
|
|
export var reaper_path: NodePath
|
|
export var vimp_path: NodePath
|
|
|
|
export var character_path: NodePath
|
|
onready var character: Character = get_node(character_path)
|
|
var head: Spatial
|
|
var cam: Camera
|
|
var default_camera_trans: Transform
|
|
|
|
var is_in_menu: bool = false
|
|
export var FOV = 80.0
|
|
export var HUD_scene: PackedScene
|
|
onready var HUD: Control
|
|
onready var debug_label: Label = $DebugText
|
|
var mouse_axis: Vector2 = Vector2.ZERO
|
|
export var mouse_sensitivity: float = 10.0
|
|
var cursor_no_enemy: Control
|
|
var cursor_enemy: Control
|
|
|
|
func set_character(c: Character):
|
|
if cam:
|
|
cam.current = false
|
|
character = c
|
|
cam = character.back_camera
|
|
default_camera_trans = cam.transform
|
|
head = character.head
|
|
cam.fov = FOV
|
|
cam.current = true
|
|
|
|
func _ready():
|
|
set_character(character)
|
|
if not Engine.editor_hint:
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
|
HUD = HUD_scene.instance()
|
|
add_child(HUD)
|
|
character.connect("health_changed", self, "update_health")
|
|
if HUD.has_node("cursor_enemy"):
|
|
cursor_enemy = HUD.get_node("cursor_enemy")
|
|
if HUD.has_node("cursor_no_enemy"):
|
|
cursor_enemy = HUD.get_node("cursor_no_enemy")
|
|
|
|
func get_target() -> Dictionary:
|
|
var weapon = character.current_weapon
|
|
var ray_from = cam.global_transform.origin
|
|
var ray_to = cam.global_transform.basis.z * -20000
|
|
var space_state = get_world().direct_space_state
|
|
var result = space_state.intersect_ray(ray_from, ray_to, [self, weapon])
|
|
|
|
if not result:
|
|
return Globals.create_empty_collision_dictionnary(ray_to)
|
|
else:
|
|
return result
|
|
|
|
func _physics_process(delta):
|
|
if Engine.editor_hint:
|
|
return
|
|
debug_label.text = "FPS: " + str(Engine.get_frames_per_second()) + " | Objects: " + str(Performance.get_monitor(Performance.OBJECT_COUNT))
|
|
|
|
# calculate and export target
|
|
var target = get_target()
|
|
Globals.target_position = target
|
|
|
|
# cursor change
|
|
if cursor_no_enemy and cursor_enemy:
|
|
if target["collider"] and target["collider"] is Entity:
|
|
cursor_no_enemy.visible = false
|
|
cursor_enemy.visible = true
|
|
else:
|
|
cursor_enemy.visible = false
|
|
cursor_no_enemy.visible = true
|
|
|
|
# update camera
|
|
if character.sprinting:
|
|
cam.set_fov(lerp(cam.fov, FOV * 1.2, delta * 8))
|
|
else:
|
|
cam.set_fov(lerp(cam.fov, FOV, delta * 8))
|
|
# head.global_transform.origin = character.global_transform.origin
|
|
|
|
|
|
func camera_rotation() -> void:
|
|
if mouse_axis.length() > 0:
|
|
var _smoothness := 80
|
|
# Get mouse delta
|
|
var horizontal: float = -(mouse_axis.x * mouse_sensitivity) / _smoothness
|
|
var vertical: float = -(mouse_axis.y * mouse_sensitivity) / _smoothness
|
|
|
|
mouse_axis = Vector2.ZERO
|
|
|
|
character.rotate_y(deg2rad(horizontal))
|
|
|
|
var temp_rot: Vector3 = head.rotation_degrees
|
|
temp_rot += Vector3(vertical, 0, 0)
|
|
# temp_rot += Vector3(vertical, horizontal, 0)
|
|
|
|
# clamp vertical rotation
|
|
temp_rot.x = clamp(temp_rot.x, -75, 75)
|
|
head.rotation_degrees = temp_rot
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if Engine.editor_hint:
|
|
return
|
|
if not Globals.process_3d_inputs:
|
|
return
|
|
if event is InputEventMouseMotion:
|
|
mouse_axis = event.relative
|
|
|
|
if Input.is_action_pressed("camera_front"):
|
|
var camera_front_transform = default_camera_trans
|
|
camera_front_transform = default_camera_trans.translated(Vector3(5, 0, -5))
|
|
camera_front_transform = camera_front_transform.rotated(Vector3.UP, deg2rad(-180))
|
|
cam.transform = camera_front_transform
|
|
if Input.is_action_just_released("camera_front"):
|
|
cam.transform = default_camera_trans
|
|
|
|
if Input.is_action_just_pressed("inp_fire"):
|
|
character.fire_pressed()
|
|
|
|
if Input.is_action_just_released("inp_fire"):
|
|
character.fire_released()
|
|
|
|
if Input.is_action_just_pressed("weapon_forward"):
|
|
character.switch_next_weapon_slot()
|
|
|
|
if Globals.process_3d_inputs and Input.is_action_just_pressed("ui_cancel"):
|
|
var ingame_menu = preload("res://ui/menus/ingame_menu.tscn").instance()
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED)
|
|
add_child(ingame_menu)
|
|
ingame_menu.connect("tree_exited", self, "_ingamemenu_closed")
|
|
Globals.process_3d_inputs = false
|
|
|
|
if Input.is_action_just_pressed("camera_reaper"):
|
|
set_character(get_node(reaper_path))
|
|
|
|
if Input.is_action_just_pressed("camera_vimp"):
|
|
set_character(get_node(vimp_path))
|
|
|
|
if Input.is_action_just_pressed("move_jump"):
|
|
character.jump()
|
|
|
|
if Input.is_action_just_pressed("move_sprint"):
|
|
character.set_sprint(true)
|
|
if Input.is_action_just_released("move_sprint"):
|
|
character.set_sprint(false)
|
|
|
|
|
|
func _ingamemenu_closed():
|
|
Globals.process_3d_inputs = true
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
|
|
|
func _process(_delta: float) -> void:
|
|
if Engine.editor_hint:
|
|
return
|
|
if Globals.process_3d_inputs:
|
|
camera_rotation()
|
|
character.move_axis.x = Input.get_action_strength("move_forward") - Input.get_action_strength("move_backward")
|
|
character.move_axis.y = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
|
|
|
|
update_hud()
|
|
|
|
func update_hud() -> void:
|
|
# for weapon_slot in HUD.find_node("Weapon*"):
|
|
# for child in weapon_slot.get_children():
|
|
# weapon_slot.remove_child(child)
|
|
for weapon in character.weapons:
|
|
var weapon_slot = character.get_weapon_slot(weapon)
|
|
var hud_weapon_slot = HUD.find_node("Weapon%s" % weapon_slot)
|
|
var weapon_icon: Control = weapon.ui_icon
|
|
if not weapon_icon.get_parent() == hud_weapon_slot:
|
|
hud_weapon_slot.add_child(weapon_icon)
|
|
if character.current_weapon == weapon:
|
|
hud_weapon_slot.get_node("selected").visible = true
|
|
else:
|
|
hud_weapon_slot.get_node("selected").visible = false
|
|
|
|
|
|
func update_health() -> void:
|
|
var current_health = character.health
|
|
var max_health = character.max_health
|
|
var hp_percent = current_health/max_health
|
|
|
|
# UI/hp polygon: 0 means 100% hp, 250 means 0%
|
|
var val = 250 - 250*hp_percent
|
|
HUD.find_node("hp").texture_offset = Vector2(val, 0)
|
|
|