540 lines
14 KiB
GDScript3
540 lines
14 KiB
GDScript3
![]() |
|
||
|
extends KinematicBody
|
||
|
|
||
|
var inventory = null
|
||
|
var inventoryOpen = false
|
||
|
|
||
|
var carried_object = null
|
||
|
var throw_power = 0
|
||
|
|
||
|
var interactor = null
|
||
|
|
||
|
# this was supposedd to be for fall damage, not sure if works
|
||
|
var last_floor_height
|
||
|
var can_change_last_floor_height = true
|
||
|
|
||
|
# Movement
|
||
|
const IDLE = 0
|
||
|
|
||
|
const RUN = 1 # default movement
|
||
|
const SPRINT = 2
|
||
|
const WALK = 3
|
||
|
|
||
|
var movement_state = IDLE
|
||
|
|
||
|
const STAND = 0
|
||
|
const CROUCH = 1
|
||
|
|
||
|
var posture_state = STAND
|
||
|
|
||
|
var run_speed = 8
|
||
|
var sprint_speed = 10
|
||
|
var walk_speed = 2.7
|
||
|
|
||
|
var move_speed = run_speed
|
||
|
|
||
|
# Controls
|
||
|
var velocity = Vector3()
|
||
|
var yaw = 0
|
||
|
var pitch = 0
|
||
|
var is_moving = false
|
||
|
var view_sensitivity = 0.15
|
||
|
|
||
|
var look_vector = Vector3()
|
||
|
|
||
|
# Physics
|
||
|
var gravity = -40
|
||
|
|
||
|
const ACCEL = 0.5
|
||
|
const DEACCEL = 0.8
|
||
|
|
||
|
const JUMP_STR = 10
|
||
|
|
||
|
# Ladder
|
||
|
var on_ladder = false
|
||
|
const LADDER_SPEED = 8
|
||
|
const LADDER_ACCEL = 2
|
||
|
|
||
|
var in_vent = false
|
||
|
|
||
|
var hiding = false
|
||
|
var hideCam
|
||
|
var lightLevel : float
|
||
|
|
||
|
#slope variables
|
||
|
const MAX_SLOPE_ANGLE = 60
|
||
|
|
||
|
#stair variables
|
||
|
const MAX_STAIR_SLOPE = 20
|
||
|
const STAIR_JUMP_HEIGHT = 6
|
||
|
|
||
|
var lock = false
|
||
|
|
||
|
|
||
|
func _ready():
|
||
|
Spiel.player = self
|
||
|
#Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
||
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||
|
inventory = get_parent().get_node("Inventory")
|
||
|
|
||
|
func _process(d):
|
||
|
if hiding or inventoryOpen or lock:
|
||
|
$interaction_text.set_text("")
|
||
|
return
|
||
|
#######################################################################################################
|
||
|
# INTERACTIONS
|
||
|
|
||
|
if $Yaw/Camera/InteractionRay.is_colliding():
|
||
|
var x = $Yaw/Camera/InteractionRay.get_collider()
|
||
|
if x != null:
|
||
|
if x.has_method("pick_up"):
|
||
|
$interaction_text.set_text("[F] " + x.get_name())
|
||
|
elif x.has_method("interact"):
|
||
|
$interaction_text.set_text("[E] " + x.get_name())
|
||
|
else:
|
||
|
$interaction_text.set_text("")
|
||
|
else:
|
||
|
$interaction_text.set_text("")
|
||
|
|
||
|
|
||
|
#######################################################################################################
|
||
|
# VECTOR 3 for where the player is currently looking
|
||
|
|
||
|
var dir = (get_node("Yaw/Camera/look_at").get_global_transform().origin - get_node("Yaw/Camera").get_global_transform().origin).normalized()
|
||
|
look_vector = dir
|
||
|
|
||
|
|
||
|
func _physics_process(delta): #IS PLAYER MOVING NORMALLY OR ON LADDER? # why the fuck is this in all caps?
|
||
|
lightLevel = $LightLevel.lightLevel * 10
|
||
|
|
||
|
if inventoryOpen or lock:
|
||
|
return
|
||
|
|
||
|
if hiding:
|
||
|
_process_hiding(delta)
|
||
|
elif on_ladder:
|
||
|
_process_on_ladder(delta)
|
||
|
elif in_vent:
|
||
|
_process_in_vent(delta)
|
||
|
else:
|
||
|
_process_movements(delta)
|
||
|
|
||
|
#######################################################################################################
|
||
|
# NORMAL MOVEMENT
|
||
|
#######################################################################################################
|
||
|
|
||
|
var direction = Vector3()
|
||
|
func _process_movements(delta):
|
||
|
|
||
|
var up = Input.is_action_pressed("ui_up")
|
||
|
var down = Input.is_action_pressed("ui_down")
|
||
|
var left = Input.is_action_pressed("ui_left")
|
||
|
var right = Input.is_action_pressed("ui_right")
|
||
|
|
||
|
var jump = Input.is_action_pressed("jump")
|
||
|
|
||
|
var sprint = Input.is_action_pressed("sprint")
|
||
|
var walk = Input.is_action_pressed("walk")
|
||
|
|
||
|
var aim = $Yaw/Camera.get_camera_transform().basis
|
||
|
|
||
|
direction = Vector3()
|
||
|
|
||
|
if up:
|
||
|
direction -= aim[2]
|
||
|
if down:
|
||
|
direction += aim[2]
|
||
|
if left:
|
||
|
direction -= aim[0]
|
||
|
if right:
|
||
|
direction += aim[0]
|
||
|
|
||
|
if up or right or left or down: # IS MOVING?
|
||
|
if posture_state == STAND:
|
||
|
movement_state = RUN
|
||
|
move_speed = run_speed
|
||
|
if !on_ladder:
|
||
|
if up or right or left: # IS MOVING FORWARDS?
|
||
|
if sprint:
|
||
|
movement_state = SPRINT
|
||
|
move_speed = sprint_speed
|
||
|
elif walk:
|
||
|
movement_state = WALK
|
||
|
move_speed = walk_speed
|
||
|
else:
|
||
|
movement_state = WALK
|
||
|
move_speed = walk_speed
|
||
|
else: # IS NOT MOVING?
|
||
|
movement_state = IDLE
|
||
|
|
||
|
var normal = $floor_check.get_collision_normal()
|
||
|
|
||
|
if is_on_floor():
|
||
|
if can_change_last_floor_height == false: # FALL DAMAGE | Not sure if works properly
|
||
|
var height_difference = last_floor_height - get_translation().y
|
||
|
if height_difference > 0.4:
|
||
|
print("OUCH!")
|
||
|
can_change_last_floor_height = true
|
||
|
|
||
|
velocity = velocity - velocity.dot(normal) * normal
|
||
|
|
||
|
if jump:
|
||
|
if movement_state == SPRINT:
|
||
|
velocity.y += JUMP_STR * 1.1 # Jump higher if sprinting
|
||
|
else:
|
||
|
velocity.y += JUMP_STR
|
||
|
|
||
|
else:
|
||
|
_apply_gravity(delta)
|
||
|
if can_change_last_floor_height:
|
||
|
last_floor_height = get_translation().y
|
||
|
can_change_last_floor_height = false
|
||
|
|
||
|
if velocity.x > 0 or velocity.x < 0 and is_moving == false:
|
||
|
is_moving = true
|
||
|
else:
|
||
|
is_moving = false
|
||
|
if velocity.y > 0 or velocity.y < 0 and is_moving == false:
|
||
|
is_moving = true
|
||
|
else:
|
||
|
is_moving = false
|
||
|
if velocity.z > 0 or velocity.z < 0 and is_moving == false:
|
||
|
is_moving = true
|
||
|
else:
|
||
|
is_moving = false
|
||
|
pass
|
||
|
|
||
|
direction.y = 0
|
||
|
#Normalize direction
|
||
|
direction = direction.normalized()
|
||
|
|
||
|
if (direction.length() > 0 and $Yaw/stair_check.is_colliding()):
|
||
|
var stair_normal = $Yaw/stair_check.get_collision_normal()
|
||
|
var stair_angle = rad2deg(acos(stair_normal.dot(Vector3(0, 1, 0))))
|
||
|
if stair_angle < MAX_STAIR_SLOPE:
|
||
|
print("STAIR")
|
||
|
velocity.y = STAIR_JUMP_HEIGHT
|
||
|
|
||
|
var hvel = velocity
|
||
|
hvel.y = 0
|
||
|
var target = direction * move_speed
|
||
|
var accel
|
||
|
if(direction.dot(hvel) > 0):
|
||
|
accel = ACCEL
|
||
|
else:
|
||
|
accel = DEACCEL
|
||
|
|
||
|
hvel = hvel.linear_interpolate(target, accel * move_speed * delta)
|
||
|
velocity.x = hvel.x
|
||
|
velocity.z = hvel.z
|
||
|
|
||
|
velocity = move_and_slide(velocity, Vector3(0, 1, 0), 0.05, 4, deg2rad(MAX_SLOPE_ANGLE))
|
||
|
|
||
|
throwing(delta)
|
||
|
|
||
|
#######################################################################################################
|
||
|
# MOVEMENT ON LADDER
|
||
|
#######################################################################################################
|
||
|
|
||
|
func _process_on_ladder(delta):
|
||
|
|
||
|
var up = Input.is_action_pressed("ui_up")
|
||
|
var down = Input.is_action_pressed("ui_down")
|
||
|
var left = Input.is_action_pressed("ui_left")
|
||
|
var right = Input.is_action_pressed("ui_right")
|
||
|
|
||
|
var jump = Input.is_action_pressed("jump")
|
||
|
|
||
|
var sprint = Input.is_action_pressed("sprint")
|
||
|
var walk = Input.is_action_pressed("walk")
|
||
|
|
||
|
#read camera basis (rotation)
|
||
|
var aim = $Yaw/Camera.get_camera_transform().basis
|
||
|
|
||
|
#calculate direction where the player wants to move
|
||
|
direction = Vector3()
|
||
|
|
||
|
if up:
|
||
|
direction -= aim[2]
|
||
|
if down:
|
||
|
direction += aim[2]
|
||
|
if left:
|
||
|
direction -= aim[0]
|
||
|
if right:
|
||
|
direction += aim[0]
|
||
|
|
||
|
direction = direction.normalized()
|
||
|
|
||
|
# where would the player go at max speed
|
||
|
var target = direction * LADDER_SPEED
|
||
|
|
||
|
# calculate a portion of the distance to go
|
||
|
velocity = velocity.linear_interpolate(target, LADDER_ACCEL * delta)
|
||
|
|
||
|
if jump:
|
||
|
velocity += look_vector * Vector3(5, 5, 5)
|
||
|
|
||
|
# move
|
||
|
move_and_slide(velocity)
|
||
|
|
||
|
throwing(delta)
|
||
|
|
||
|
|
||
|
#######################################################################################################
|
||
|
# MOVEMENT IN VENT
|
||
|
#######################################################################################################
|
||
|
|
||
|
func _process_in_vent(delta):
|
||
|
var up = Input.is_action_pressed("ui_up")
|
||
|
var down = Input.is_action_pressed("ui_down")
|
||
|
var left = Input.is_action_pressed("ui_left")
|
||
|
var right = Input.is_action_pressed("ui_right")
|
||
|
|
||
|
var jump = Input.is_action_pressed("jump")
|
||
|
|
||
|
var sprint = Input.is_action_pressed("sprint")
|
||
|
var walk = Input.is_action_pressed("walk")
|
||
|
|
||
|
#read camera basis (rotation)
|
||
|
var aim = $Yaw/Camera.get_camera_transform().basis
|
||
|
|
||
|
#calculate direction where the player wants to move
|
||
|
direction = Vector3()
|
||
|
|
||
|
if up:
|
||
|
direction -= aim[2]
|
||
|
if down:
|
||
|
direction += aim[2]
|
||
|
if left:
|
||
|
direction -= aim[0]
|
||
|
if right:
|
||
|
direction += aim[0]
|
||
|
|
||
|
direction = direction.normalized()
|
||
|
|
||
|
# where would the player go at max speed
|
||
|
var target = direction * 10
|
||
|
|
||
|
# calculate a portion of the distance to go
|
||
|
velocity = target#velocity.linear_interpolate(target, 2 * delta)
|
||
|
|
||
|
if jump:
|
||
|
velocity += look_vector * Vector3(5, 5, 5)
|
||
|
|
||
|
# move
|
||
|
move_and_slide(velocity)
|
||
|
|
||
|
throwing(delta)
|
||
|
|
||
|
|
||
|
func Hide(camera):
|
||
|
$Yaw/CamPos.global_transform = $Yaw/Camera.global_transform
|
||
|
|
||
|
hiding = true
|
||
|
hideCam = camera
|
||
|
|
||
|
var t = 0.0
|
||
|
var exitHiding = false
|
||
|
func _process_hiding(delta):
|
||
|
if exitHiding:
|
||
|
t -= delta
|
||
|
$Yaw/Camera.global_transform = $Yaw/CamPos.global_transform.interpolate_with(hideCam.global_transform, t)
|
||
|
|
||
|
if t <= 0.0:
|
||
|
t = 0.0
|
||
|
$Yaw/Camera.global_transform = $Yaw/CamPos.global_transform
|
||
|
hiding = false
|
||
|
exitHiding = false
|
||
|
|
||
|
return
|
||
|
|
||
|
var jump = Input.is_action_pressed("jump")
|
||
|
|
||
|
#var sprint = Input.is_action_pressed("sprint")
|
||
|
#var walk = Input.is_action_pressed("walk")
|
||
|
|
||
|
t += delta
|
||
|
|
||
|
t = clamp(t, 0.0, 1.0)
|
||
|
|
||
|
$Yaw/Camera.global_transform = $Yaw/CamPos.global_transform.interpolate_with(hideCam.global_transform, t)
|
||
|
|
||
|
if jump:
|
||
|
exitHiding = true
|
||
|
|
||
|
|
||
|
#######################################################################################################
|
||
|
# GRAVITY
|
||
|
|
||
|
func _apply_gravity(delta):
|
||
|
velocity.y += delta * gravity
|
||
|
|
||
|
#######################################################################################################
|
||
|
# CAMERA MOVEMENTS
|
||
|
|
||
|
func _unhandled_input(event):
|
||
|
if inventoryOpen or lock:
|
||
|
return
|
||
|
|
||
|
if event is InputEventMouseMotion:
|
||
|
yaw = fmod(yaw - event.relative.x * view_sensitivity, 360)
|
||
|
pitch = max(min(pitch - event.relative.y * view_sensitivity, 89), -89)
|
||
|
$Yaw.rotation = Vector3(0, deg2rad(yaw), 0)
|
||
|
$Yaw/Camera.rotation = Vector3(deg2rad(pitch), 0, 0)
|
||
|
|
||
|
|
||
|
#######################################################################################################
|
||
|
# BUTTON PRESSING
|
||
|
#######################################################################################################
|
||
|
func _input(event):
|
||
|
if hiding:
|
||
|
return
|
||
|
|
||
|
#if Input.is_key_pressed(KEY_R):
|
||
|
# get_tree().reload_current_scene()
|
||
|
|
||
|
# If already carries an object - release it, otherwise (if ray is colliding) pick an object up
|
||
|
if Input.is_action_just_pressed("pick_up"):
|
||
|
if carried_object != null:
|
||
|
carried_object.pick_up(self)
|
||
|
else:
|
||
|
if $Yaw/Camera/InteractionRay.is_colliding():
|
||
|
var x = $Yaw/Camera/InteractionRay.get_collider()
|
||
|
if x.has_method("pick_up"):
|
||
|
x.pick_up(self)
|
||
|
|
||
|
# Hold Left Mouse Button (LMB) to throw carried object
|
||
|
if Input.is_action_just_released("LMB"):
|
||
|
if carried_object != null:
|
||
|
carried_object.throw(throw_power)
|
||
|
throw_power = 0
|
||
|
|
||
|
# Interact
|
||
|
if Input.is_action_just_pressed("interact"):
|
||
|
if $Yaw/Camera/InteractionRay.is_colliding():
|
||
|
var x = $Yaw/Camera/InteractionRay.get_collider()
|
||
|
print("COLLIDING")
|
||
|
print(x.get_name())
|
||
|
if x.has_method("interact"):
|
||
|
x.interact(self)
|
||
|
|
||
|
if Input.is_action_just_pressed("Inventory"):
|
||
|
inventoryOpen = !inventoryOpen
|
||
|
|
||
|
inventory.ShowInventory(inventoryOpen)
|
||
|
if inventoryOpen:
|
||
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||
|
else:
|
||
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||
|
|
||
|
if Input.is_action_just_pressed("Weap1"):
|
||
|
inventory.SelectSlot(1)
|
||
|
if Input.is_action_just_pressed("Weap2"):
|
||
|
inventory.SelectSlot(2)
|
||
|
if Input.is_action_just_pressed("Weap3"):
|
||
|
inventory.SelectSlot(3)
|
||
|
|
||
|
# Crouching
|
||
|
|
||
|
# Already crouching?
|
||
|
# Is there ceiling above me? If not then stand. If yes, then display a message.
|
||
|
|
||
|
if Input.is_action_pressed("crouch"):
|
||
|
if posture_state == STAND:
|
||
|
tryCrouch(true)
|
||
|
else:
|
||
|
tryCrouch(false)
|
||
|
|
||
|
|
||
|
func tryCrouch(crouch):
|
||
|
if crouch and posture_state == STAND:
|
||
|
$crouching.play("crouch")
|
||
|
move_speed = walk_speed
|
||
|
elif not crouch and posture_state == CROUCH:
|
||
|
if !($ceiling_check.is_colliding()):
|
||
|
$crouching.play_backwards("crouch")
|
||
|
move_speed = run_speed
|
||
|
#else:
|
||
|
# show_message("I cannot stand here HELP????", 2)
|
||
|
|
||
|
#######################################################################################################
|
||
|
# OTHER
|
||
|
#######################################################################################################
|
||
|
|
||
|
# LADDER
|
||
|
#func _on_Area_body_entered(body)
|
||
|
# if body.name == "Player":
|
||
|
# on_ladder = true
|
||
|
|
||
|
#func _on_Area_body_exited(body):
|
||
|
# if body.name == "Player":
|
||
|
# on_ladder = false
|
||
|
|
||
|
|
||
|
# CROUCHING ANIM
|
||
|
func _on_crouching_animation_finished(anim_name):
|
||
|
if posture_state == STAND:
|
||
|
posture_state = CROUCH
|
||
|
else:
|
||
|
posture_state = STAND
|
||
|
|
||
|
|
||
|
# IMPULSE STUFF
|
||
|
func impulse(vector_towards, power, time):
|
||
|
for x in range(time * 100):
|
||
|
velocity += vector_towards * Vector3(power, power, power)
|
||
|
|
||
|
# THROW STUFF
|
||
|
func throwing(delta):
|
||
|
if carried_object != null:
|
||
|
if Input.is_action_pressed("LMB"):
|
||
|
if throw_power <= 3000:
|
||
|
throw_power += 2
|
||
|
|
||
|
# SHOW A MESSAGE ON SCREEN
|
||
|
func show_message(text, time):
|
||
|
$message.set_text(text)
|
||
|
$message/Timer.set_wait_time(time)
|
||
|
$message/Timer.start()
|
||
|
yield($message/Timer, "timeout")
|
||
|
$message.set_text("")
|
||
|
|
||
|
#################
|
||
|
## PLAYER AS TASK
|
||
|
#################
|
||
|
var inDialog = false
|
||
|
|
||
|
func should_align():
|
||
|
return false
|
||
|
|
||
|
func done():
|
||
|
return false
|
||
|
|
||
|
func interact(_relate):
|
||
|
if inDialog:
|
||
|
return
|
||
|
pass
|
||
|
#inDialog = true
|
||
|
#var dialog = Dialogic.start("pissYourself")
|
||
|
#dialog.connect("dialogic_signal", self, "dialog_listener")
|
||
|
#add_child(dialog)
|
||
|
|
||
|
func dialog_listener(string):
|
||
|
pass
|
||
|
#inDialog = false
|
||
|
|
||
|
func get_interaction():
|
||
|
return self
|
||
|
|
||
|
func get_transform():
|
||
|
return global_transform
|
||
|
|
||
|
func waiting():
|
||
|
return inDialog
|
||
|
|
||
|
func AddToInv(ItemName, ItemIcon):
|
||
|
if not inventory.AddToHotbar(ItemName, ItemIcon):
|
||
|
if not inventory.AddToInventory(ItemName, ItemIcon):
|
||
|
return false# bruh moment. somehow not enough space in inventory
|
||
|
return true
|