91 lines
3.5 KiB
GDScript
91 lines
3.5 KiB
GDScript
class_name Rogue extends Player # Rogue class that extends Player
|
|
|
|
var attacks := ["2H_Ranged_Shoot"]
|
|
var reloadings := ["2H_Ranged_Reload"]
|
|
var aimings := ["2H_Ranged_Aiming"]
|
|
var footsteps := [
|
|
"res://resources/audio/footstep_grass_000.ogg",
|
|
"res://resources/audio/footstep_grass_001.ogg",
|
|
"res://resources/audio/footstep_grass_002.ogg",
|
|
"res://resources/audio/footstep_grass_003.ogg",
|
|
"res://resources/audio/footstep_grass_004.ogg"
|
|
]
|
|
@export var arrow_scene: PackedScene # Arrow scene to instantiate
|
|
|
|
@onready var shoot_point: Node3D = $"Rig/Skeleton3D/handslot_r/2H_Crossbow/ShootPoint" # Shoot point for the arrow
|
|
@onready var crossbow: MeshInstance3D = $"Rig/Skeleton3D/handslot_r/2H_Crossbow" # Crossbow mesh instance
|
|
@onready var ik_target: Node3D = $Rig/Skeleton3D/ik_target # IK target for the hand
|
|
@onready var hand_ik: SkeletonIK3D = $Rig/Skeleton3D/ik_hand_r # IK for the hand
|
|
|
|
@export var loaded: bool
|
|
var current_arrow: Node3D
|
|
|
|
func _ready() -> void: # Called when the node is added to the scene.
|
|
if loaded == true: # If the arrow is loaded, instantiate it
|
|
arrow_loaded() # Load the arrow if it is already loaded
|
|
|
|
func _process(delta: float) -> void: # Process function for the Rogue
|
|
var camera := get_viewport().get_camera_3d() # Get the camera from the viewport
|
|
if camera: # Check if the camera exists
|
|
camera.fov = 40 if state == States.aiming else 70 # Normal FOV
|
|
hand_ik.target = ik_target.global_transform # Set IK target position
|
|
hand_ik.start() # Start IK processing
|
|
var screen_center = get_viewport().get_visible_rect().size / 2 # Center of the screen
|
|
var target_pos = camera.project_ray_origin(screen_center) + camera.project_ray_normal(screen_center) * 100 # 100 units away from the camera
|
|
ik_target.global_transform.origin = target_pos # Set IK target position
|
|
crossbow.look_at(target_pos, Vector3.UP)
|
|
crossbow.rotate_object_local(Vector3.UP, PI) # Falls -Z nach vorne zeigt
|
|
|
|
if state == States.aiming: # Aiming state
|
|
spring_arm.transform.origin.x = 0.5 # Offset to the right
|
|
spring_arm.spring_length = 3.0 # Shorter spring length for aiming
|
|
|
|
super._process(delta)
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
# Shoot
|
|
if event.is_action_pressed("attack"):
|
|
if loaded == true:
|
|
if enough_stamina_available(attack_cost):
|
|
use_stamina(attack_cost)
|
|
anim_state.travel(attacks.pick_random())
|
|
loaded = false
|
|
else:
|
|
print("No arrow loaded!")
|
|
|
|
# Reload
|
|
if Input.is_action_pressed("reload"):
|
|
if loaded == false:
|
|
anim_state.travel(reloadings.pick_random())
|
|
loaded = true
|
|
else:
|
|
print("Already loaded!")
|
|
|
|
# Aiming
|
|
if Input.is_action_pressed("block"): state = States.aiming
|
|
if Input.is_action_just_released("block"): state = States.idle
|
|
anim_tree.set("parameters/conditions/aiming", state == States.aiming)
|
|
anim_tree.set("parameters/conditions/not_aiming", state != States.aiming)
|
|
|
|
# Calls the _input() from player.gd
|
|
super._input(event)
|
|
|
|
func shoot_arrow() -> void:
|
|
if current_arrow != null:
|
|
var camera := get_viewport().get_camera_3d()
|
|
if camera:
|
|
# Zielpunkt im Raum berechnen (Ray vom Fadenkreuz)
|
|
var from = camera.project_ray_origin(get_viewport().get_visible_rect().size / 2)
|
|
var to = from + camera.project_ray_normal(get_viewport().get_visible_rect().size / 2) * 1000
|
|
var direction = (to - shoot_point.global_transform.origin).normalized()
|
|
current_arrow.shoot(direction)
|
|
else:
|
|
current_arrow.shoot() # Fallback
|
|
|
|
|
|
func arrow_loaded() -> void:
|
|
print("Arrow loaded...")
|
|
current_arrow = arrow_scene.instantiate()
|
|
#new_arrow.global_transform = shoot_point.global_transform
|
|
shoot_point.add_child(current_arrow)
|