2021-06-07 19:11:42 +02:00
extends CharacterBody3D
2021-05-19 00:56:18 +02:00
2021-10-24 16:25:04 +02:00
var impact_player = preload ( " res://Assets/Effects/ImpactBlood.tscn " )
2021-10-23 23:54:02 +02:00
var max_health = 100
var health = max_health :
set ( value ) :
2021-10-24 20:17:19 +02:00
if not dead :
if main . player_list . players . has ( self . get_multiplayer_authority ( ) ) :
main . player_list . players [ self . get_multiplayer_authority ( ) ] . health = value
main . push_local_player_info ( )
2021-10-23 23:54:02 +02:00
get :
2021-10-24 20:17:19 +02:00
if not dead :
return main . player_list . players [ self . get_multiplayer_authority ( ) ] . health
else :
return 0
2021-10-23 23:54:02 +02:00
2021-09-07 23:23:48 +02:00
@ export var mouse_sensitivity : = 0.15
2021-05-19 00:56:18 +02:00
2021-08-21 15:03:51 +02:00
@ onready var main = get_tree ( ) . root . get_node ( " Main " )
2021-09-11 15:52:09 +02:00
@ onready var gui = main . get_node ( " GUI " )
@ onready var settings = gui . settings
2021-08-21 15:03:51 +02:00
@ onready var hud = main . get_node ( " HUD " )
2021-07-16 02:52:18 +02:00
@ onready var crosshair = hud . get_node ( " Crosshair " )
@ onready var vignette = hud . get_node ( " Vignette " )
2021-09-26 02:18:51 +02:00
@ onready var banner_busy = preload ( " res://Assets/Effects/Busy.png " )
@ onready var banner_chat = preload ( " res://Assets/Effects/Typing.png " )
2021-05-19 00:56:18 +02:00
@ onready var head = $ Head
2021-05-24 21:57:19 +02:00
@ onready var camera = $ Head / Camera
2021-10-16 02:07:19 +02:00
#@onready var tween = $Head/Camera/Tween
2021-05-24 21:57:19 +02:00
2021-05-22 02:10:00 +02:00
@ onready var ground_check = $ GroundCheck
2021-10-16 02:07:19 +02:00
#@onready var climb_tween = $ClimbTween # undergoing redesign in Godot 4
#@onready var climb_check = $ClimbCheck
2021-05-24 21:57:19 +02:00
@ onready var body = $ Body
2021-05-25 01:14:37 +02:00
@ onready var mesh = $ Mesh
2021-06-18 01:43:10 +02:00
@ onready var weapon = $ Head / Camera / Hand / Weapon
2021-09-08 23:25:52 +02:00
var gibs_vfx = preload ( " res://Assets/Effects/Gibs.tscn " )
2021-09-24 04:46:39 +02:00
var blood_decal = preload ( " res://Assets/Decals/Blood/BloodSplash.tscn " )
2021-09-08 23:25:52 +02:00
2021-09-04 22:37:13 +02:00
# climb functions - temporarily disabled
#@onready var body_height = body.shape.height
#@onready var body_y = body.position.y
#@onready var mesh_height = mesh.mesh.mid_height
#@onready var mesh_y = mesh.position.y
#@onready var climb_check_y = climb_check.position.y
2021-06-07 19:11:42 +02:00
@ onready var ground_check_y = ground_check . position . y
2021-05-24 21:57:19 +02:00
2021-06-03 17:44:25 +02:00
var input_active = false
2021-05-24 21:57:19 +02:00
var base_fov = 90
2021-07-26 20:51:54 +02:00
var view_zoom_target : = 1.0
var view_zoom_direction = true
var view_zoom : = view_zoom_target :
2021-05-24 21:57:19 +02:00
set ( zoom ) :
view_zoom = zoom
camera . fov = base_fov / zoom
2021-05-24 22:18:46 +02:00
crosshair . modulate . a = clamp ( 1 - ( zoom - 1 ) , 0 , 1 )
vignette . modulate . a = ( zoom - 1 ) / 3
2021-05-24 21:57:19 +02:00
2021-09-25 17:36:15 +02:00
var revenge_pid : int #store PID of the player who killed you recently
2021-09-04 22:37:13 +02:00
# climbing code - disabled for now
#var climb_height := 0.75
#var climb_time := 0.15
#var climb_state := 0.0 :
# set(factor):
# #print("climb_state is now ", factor)
# climb_state = factor
# body.shape.height = body_height - factor * climb_height
# body.position.y = body_y + factor * climb_height / 2
#
# mesh.mesh.mid_height = mesh_height - factor * climb_height
# mesh.position.y = mesh_y + factor * climb_height / 2
#
# ground_check.position.y = ground_check_y + factor * climb_height / 2
# climb_check.position.y = climb_check_y + factor * climb_height / 2
2021-05-19 00:56:18 +02:00
2021-05-19 01:59:58 +02:00
var direction : = Vector3 . ZERO
var accel : = 0
var speed : = 0
var medium = " ground "
var accel_type : = {
" ground " : 12 ,
" air " : 1 ,
" water " : 4
}
var speed_type : = {
2021-05-24 21:57:19 +02:00
" ground " : 10 ,
" air " : 10 ,
" water " : 5
2021-05-19 01:59:58 +02:00
}
2021-05-19 00:56:18 +02:00
var gravity : = 28
2021-09-07 23:23:48 +02:00
var jump : = 14 * 1
var jetpack_active = false
var jetpack_thrust = 48 # force applied against gravity
var jetpack_tank = 0.5 # maximum fuel (jetpack use time
var jetpack_fuel = jetpack_tank # current fuel (use time) left
var jetpack_recharge = 0.25 # how long to recharge to full
2021-09-25 20:51:20 +02:00
var jetpack_min = 1.0 / 8
2021-09-08 23:54:04 +02:00
var jetpack_was_active = false
2021-05-19 00:56:18 +02:00
2021-05-19 01:59:58 +02:00
var velocity : = Vector3 . ZERO
2021-05-19 00:56:18 +02:00
var gravity_vec : = Vector3 . ZERO
2021-10-16 02:07:19 +02:00
var previously_on_floor : = false
var lagging_movement_velocity = Vector3 . ZERO
2021-10-23 23:54:02 +02:00
var dead = false #: # used to workaround Godot crash when destroying player_nodes
# set(value):
# match value:
# true:
# #input_active = false
# self.hide()
# $Body.disabled = true
# hud.pain = 3
# crosshair.hide()
# #$Head/Camera.transform.origin.y
# #set_physics_process(false)
# false:
# #input_active = true
# self.show()
# $Body.disabled = false
# $SpawnSFX.play()
# $SpawnVFX.emitting = true
# hud.pain = 0
# crosshair.show()
# #$Head/Camera.transform.origin = Vector3(0,0,0)
# #set_physics_process(true)
# dead = value
#
2021-09-26 00:46:34 +02:00
var focus_banner_alpha = 0
var focus_banner_inc = 5
var focus_banner_dec = 1
var focus_banner_show = false
var last_viewed_banner = null
func view_banner ( show : bool ) :
focus_banner_show = show
2021-10-06 23:49:16 +02:00
@ rpc ( authority , reliable ) func focus_banner ( show : bool , type : = 0 ) :
2021-09-26 00:46:34 +02:00
if show :
$ FocusBanner . show ( )
else :
$ FocusBanner . hide ( )
2021-09-26 02:18:51 +02:00
match type :
0 : $ FocusBanner . mesh . surface_get_material ( 0 ) . set ( " albedo_texture " , banner_busy )
1 : $ FocusBanner . mesh . surface_get_material ( 0 ) . set ( " albedo_texture " , banner_chat )
2021-09-22 01:51:21 +02:00
2021-10-06 23:49:16 +02:00
@ rpc ( authority , unreliable ) func update_movement ( player_transform , head_rotation , lin_velocity , jetpack ) :
2021-07-12 22:40:23 +02:00
global_transform = player_transform
head . set_rotation ( head_rotation )
2021-09-07 23:23:48 +02:00
jetpack_active = jetpack
2021-10-06 23:49:16 +02:00
motion_velocity = lin_velocity
2021-06-19 03:40:10 +02:00
2021-10-23 23:54:02 +02:00
#@rpc(any_peer, call_local, reliable) func set_dead(is_dead: bool):
2021-09-22 01:51:21 +02:00
#print("Recieved RPC call for set_dead ", is_dead)
2021-10-16 02:07:19 +02:00
2021-10-23 23:54:02 +02:00
# if not is_dead:
# spawn()
2021-10-16 02:07:19 +02:00
2021-10-23 23:54:02 +02:00
# self.dead = is_dead
2021-09-22 01:51:21 +02:00
# if is_multiplayer_authority():
# print("Rebroadcasting RPC call for set_dead ", dead)
# rpc(&'set_dead', dead)
2021-10-15 02:15:43 +02:00
@ rpc ( any_peer , reliable ) func damage_feedback ( kill = false ) :
if is_multiplayer_authority ( ) :
var victim = get_tree ( ) . multiplayer . get_remote_sender_id ( )
if kill :
crosshair . kill ( )
var pid = get_multiplayer_authority ( )
main . player_list . players [ pid ] . score += 1 # we get a point
main . rpc ( & ' player_list_update ' , main . player_list . get ( pid ) . serialize ( ) , pid ) # tell everyone
main . check_game_win_condition ( )
# check for firstblood
if main . player_list . players [ pid ] . score == 1 :
var firstblood = true
for i in main . player_list . players . keys ( ) :
if i != pid and main . player_list . players [ i ] . score > 0 :
firstblood = false
if firstblood :
main . get_node ( " Announcer " ) . speak ( main . get_node ( " Announcer " ) . firstblood ) # design a proper API
# check for revenge (payback) - don't play if this is a duel, it'd be silly
if main . player_list . players . size ( ) > 2 and victim == revenge_pid :
main . get_node ( " Announcer " ) . speak ( main . get_node ( " Announcer " ) . payback )
revenge_pid = - 1 # reset revenge
else :
crosshair . hit ( )
else :
print ( " damage feedback called on puppet, ignoring " )
return
2021-05-19 00:56:18 +02:00
func _ready ( ) - > void :
2021-06-03 17:44:25 +02:00
#Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
2021-07-26 20:51:54 +02:00
view_zoom_target = 1.0
2021-09-26 00:46:34 +02:00
var banner_material = $ FocusBanner . mesh . surface_get_material ( 0 ) . duplicate ( )
$ FocusBanner . mesh . surface_set_material ( 0 , banner_material )
focus_banner ( false )
2021-09-10 02:04:27 +02:00
2021-09-17 01:32:00 +02:00
if is_multiplayer_authority ( ) : # prevent puppets from attempting to steer the authority - this just causes RPC errors
2021-09-10 02:04:27 +02:00
input_active = true
2021-09-11 23:00:53 +02:00
$ Head / Camera . current = true
2021-09-10 02:04:27 +02:00
else :
input_active = false
2021-09-11 23:00:53 +02:00
$ Head / Camera . current = false
2021-06-09 19:41:52 +02:00
2021-09-12 04:44:02 +02:00
$ Jetpack / JetpackSound . playing = true
$ Jetpack / JetpackSound . stream_paused = true
2021-09-25 19:24:29 +02:00
$ SpawnVFX . emitting = true
2021-09-12 04:44:02 +02:00
2021-05-19 00:56:18 +02:00
func aim ( event ) - > void :
var mouse_motion = event as InputEventMouseMotion
if mouse_motion :
2021-09-11 15:52:09 +02:00
var adjusted_mouse_sensitivity = 1.0
if " Sensitivity " in settings . keys ( ) :
adjusted_mouse_sensitivity = mouse_sensitivity * settings [ " Sensitivity " ]
rotation . y -= deg2rad ( mouse_motion . relative . x * adjusted_mouse_sensitivity / view_zoom )
2021-05-19 00:56:18 +02:00
2021-07-04 00:42:42 +02:00
var current_tilt : float = head . rotation . x
2021-09-11 15:52:09 +02:00
current_tilt -= deg2rad ( mouse_motion . relative . y * adjusted_mouse_sensitivity / view_zoom )
2021-07-04 00:42:42 +02:00
head . rotation . x = clamp ( current_tilt , deg2rad ( - 90 ) , deg2rad ( 90 ) )
2021-05-19 00:56:18 +02:00
func _input ( event ) - > void :
2021-09-22 01:51:21 +02:00
if dead :
return
2021-06-03 17:44:25 +02:00
if not input_active :
return
2021-05-19 00:56:18 +02:00
2021-09-19 20:51:47 +02:00
#assert(is_multiplayer_authority() == true, "input_active is true, even though the node is not multiplayer_authority")
if is_multiplayer_authority ( ) == false :
print ( " Input is active, but we ' re not the authority. WTF?! " )
input_active = false
return
2021-09-11 14:35:07 +02:00
2021-05-24 21:57:19 +02:00
if Input . is_action_just_pressed ( " view_zoom " ) :
2021-07-16 02:52:18 +02:00
# tween.remove_all()
# tween.interpolate_property(self, "view_zoom", view_zoom, 4.0, 0.5, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
# tween.start()
2021-07-26 20:51:54 +02:00
view_zoom_direction = true
view_zoom_target = 4.0
2021-05-24 21:57:19 +02:00
if Input . is_action_just_released ( " view_zoom " ) :
2021-07-16 02:52:18 +02:00
# tween.remove_all()
# tween.interpolate_property(self, "view_zoom", view_zoom, 1.0, 0.25, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
# tween.start()
2021-07-26 20:51:54 +02:00
view_zoom_direction = false
view_zoom_target = 1.0
2021-07-16 02:52:18 +02:00
2021-07-12 22:40:23 +02:00
aim ( event )
2021-09-12 04:05:32 +02:00
var can_shoot = true if view_zoom < = 1.05 else false
if can_shoot and Input . is_action_just_pressed ( " trigger_primary " ) :
2021-08-25 12:03:35 +02:00
weapon . trigger ( 0 , true )
2021-06-18 01:43:10 +02:00
elif Input . is_action_just_released ( " trigger_primary " ) :
2021-08-25 12:03:35 +02:00
weapon . trigger ( 0 , false )
2021-09-12 04:05:32 +02:00
if can_shoot and Input . is_action_just_pressed ( " trigger_secondary " ) :
2021-08-25 12:03:35 +02:00
weapon . trigger ( 1 , true )
2021-06-18 01:43:10 +02:00
elif Input . is_action_just_released ( " trigger_secondary " ) :
2021-08-25 12:03:35 +02:00
weapon . trigger ( 1 , false )
2021-07-26 20:51:54 +02:00
func _process ( delta ) :
2021-09-11 14:35:07 +02:00
$ Jetpack / GPUParticles3D . emitting = jetpack_active
2021-09-12 04:44:02 +02:00
if jetpack_active :
$ Jetpack / JetpackSound . stream_paused = false
2021-09-21 23:07:31 +02:00
$ Jetpack / OmniLight3D . show ( )
2021-09-25 00:29:54 +02:00
$ Jetpack / OmniLight3D . light_energy = randf_range ( 2 , 5 )
2021-09-12 04:44:02 +02:00
else :
$ Jetpack / JetpackSound . stream_paused = true
2021-09-21 23:07:31 +02:00
$ Jetpack / OmniLight3D . hide ( )
2021-09-12 04:44:02 +02:00
2021-09-26 00:46:34 +02:00
# show focus banner on demand
if focus_banner_show :
focus_banner_alpha = min ( focus_banner_alpha + focus_banner_inc * delta , 1.0 )
else :
focus_banner_alpha = max ( focus_banner_alpha - focus_banner_dec * delta , 0.0 )
$ FocusBanner . mesh . surface_get_material ( 0 ) . set ( " albedo_color " , Color ( 1 , 1 , 1 , focus_banner_alpha ) )
2021-09-26 01:12:12 +02:00
#print("PLayer: ", name, "; Focus banner alpha: ", focus_banner_alpha, "; Focus banner show: ", focus_banner_show)
2021-09-26 00:46:34 +02:00
2021-09-11 14:35:07 +02:00
if not input_active :
return
2021-09-26 00:46:34 +02:00
# demand seeing other player's banner:
2021-09-26 01:12:12 +02:00
#print("Last viewed banner is ", last_viewed_banner)
2021-09-26 00:46:34 +02:00
if $ " Head/Camera/RayCast3D " . is_colliding ( ) :
2021-09-26 01:12:12 +02:00
#print("Probe got ", $"Head/Camera/RayCast3D".get_collider().name)
2021-09-26 00:46:34 +02:00
if $ " Head/Camera/RayCast3D " . get_collider ( ) . has_method ( & " view_banner " ) :
$ " Head/Camera/RayCast3D " . get_collider ( ) . view_banner ( true )
last_viewed_banner = $ " Head/Camera/RayCast3D " . get_collider ( )
elif last_viewed_banner :
last_viewed_banner . view_banner ( false )
2021-09-11 14:35:07 +02:00
2021-09-19 20:51:47 +02:00
#assert(is_multiplayer_authority() == true, "input_active is true, even though the node is not multiplayer_authority")
if is_multiplayer_authority ( ) == false :
print ( " input_active is true, while we ' re not the authority. WTF? " )
input_active = false
return
2021-09-11 14:35:07 +02:00
2021-07-26 20:51:54 +02:00
if view_zoom_direction and view_zoom < view_zoom_target :
view_zoom = min ( view_zoom_target , view_zoom + delta * 4 )
elif not view_zoom_direction and view_zoom > view_zoom_target :
view_zoom = max ( view_zoom_target , view_zoom - delta * 4 )
2021-09-07 23:23:48 +02:00
2021-09-22 01:51:21 +02:00
hud . get_node ( " Stats " ) . get_node ( " JetpackBar " ) . value = ( jetpack_fuel / jetpack_tank ) * 100
2021-09-25 20:51:20 +02:00
# weapon spread
weapon . spread = max ( lerp ( weapon . spread , weapon . spread_min , weapon . spread_lerp ) , weapon . spread_min )
2021-07-26 20:51:54 +02:00
2021-10-06 23:49:16 +02:00
@ rpc ( call_local , any_peer , reliable ) func moan ( ) :
2021-09-29 14:08:46 +02:00
var anims = [ " 01 " , " 02 " , " 03 " , " 04 " ]
$ Pain . play ( anims [ randi ( ) % 4 ] )
2021-10-14 23:59:39 +02:00
2021-10-15 02:15:43 +02:00
@ rpc ( call_local , any_peer , reliable ) func take_damage ( attacker : int , hit_position : Vector3 , hit_normal : Vector3 , damage : int , source_position : Vector3 , damage_type , push : float ) :
var attacker_node = main . get_node ( " Players " ) . get_node ( str ( attacker ) )
2021-10-14 23:59:39 +02:00
if is_multiplayer_authority ( ) :
print ( " Taken damage: " , damage , " by: " , attacker , " from: " , source_position )
hud . damage ( damage )
2021-10-23 23:54:02 +02:00
health -= damage # reduce health
2021-10-14 23:59:39 +02:00
2021-10-23 23:54:02 +02:00
if health < = 0 : # are we dead?
2021-10-15 02:15:43 +02:00
print ( " Died " )
rpc ( & ' die ' , attacker )
attacker_node . rpc ( & ' damage_feedback ' , true ) # let the attacker know he's got a kill
else :
attacker_node . rpc ( & ' damage_feedback ' , false ) # let the attackr know he's got a hit
main . update_hud ( )
if not dead :
rpc ( & ' moan ' ) # all puppets must scream!
2021-10-24 16:25:04 +02:00
# spawn the bullet hit effect
var impact_vfx = impact_player . instantiate ( )
impact_vfx . global_transform = impact_vfx . global_transform . looking_at ( hit_normal )
impact_vfx . global_transform . origin = hit_position
get_tree ( ) . root . add_child ( impact_vfx )
2021-10-23 23:54:02 +02:00
@ rpc ( any_peer , call_local , reliable ) func spawn ( spawn_transform : Transform3D ) :
dead = false
self . global_transform = spawn_transform
health = max_health
2021-10-16 02:07:19 +02:00
$ Head / Camera . position . y = 0
$ Head / Camera . rotation . z = 0
jetpack_fuel = jetpack_tank
2021-10-23 22:34:51 +02:00
2021-10-23 23:54:02 +02:00
self . show ( )
$ Body . disabled = false
$ SpawnSFX . play ( )
$ SpawnVFX . emitting = true
if is_multiplayer_authority ( ) : # don't touch these on puppets
hud . pain = 0
crosshair . show ( )
2021-10-16 02:07:19 +02:00
2021-10-06 23:49:16 +02:00
@ rpc ( any_peer , call_local , reliable ) func die ( killer_pid : int ) :
2021-10-24 20:17:19 +02:00
if killer_pid == - 1 : # we're disconnecting from the game
#main.chat.chat_notification("Player [/i][b][color=" + main.player_list.players[self.get_multiplayer_authority()].color.to_html() + "]" + main.player_list.players[self.get_multiplayer_authority()].name + "[/color][/b][i] left the game.")
pass
else :
var gibs = gibs_vfx . instantiate ( )
get_tree ( ) . root . add_child ( gibs )
gibs . global_transform = self . global_transform
var decal = blood_decal . instantiate ( )
get_tree ( ) . root . add_child ( decal )
decal . global_transform = self . global_transform
if is_multiplayer_authority ( ) : # don't touch these on puppets
hud . pain = 3
crosshair . hide ( )
#main.chat.rpc(&'chat_notification', "Player [/i][b][color=" + main.player_list.players[self.get_multiplayer_authority()].color.to_html() + "]" + main.player_list.players[self.get_multiplayer_authority()].name + "[/color][/b][i] was killed by " + main.player_list.players[killer_pid].name )
main . chat . chat_notification ( " Player [/i][b][color= " + main . player_list . players [ self . get_multiplayer_authority ( ) ] . color . to_html ( ) + " ] " + main . player_list . players [ self . get_multiplayer_authority ( ) ] . name + " [/color][/b][i] was killed by " + main . player_list . players [ killer_pid ] . name )
revenge_pid = killer_pid
$ Head / Camera . position . y = - 1 # lower the head to the ground, let the player see their gibs
$ Head / Camera . rotation . x = 0 # reset the tilt so the camera looks forward
$ Head / Camera . rotation . z = - 20
jetpack_active = false
view_zoom_target = 1.0
view_zoom = 1
2021-10-23 23:54:02 +02:00
dead = true
2021-10-24 20:17:19 +02:00
main . destroy_player ( self . get_multiplayer_authority ( ) )
self . hide ( )
$ Body . disabled = true
2021-09-08 23:25:52 +02:00
2021-09-17 01:32:00 +02:00
#if get_tree().get_rpc_sender_id() != get_multiplayer_authority():
2021-08-29 20:32:46 +02:00
# print ("Death requested by a non-master. Ignoring")
# return
2021-09-19 20:51:47 +02:00
#main.rpc(&'destroy_player', self.get_multiplayer_authority())
2021-10-24 20:17:19 +02:00
2021-10-16 02:07:19 +02:00
2021-08-29 20:32:46 +02:00
#queue_free()
2021-09-11 22:23:41 +02:00
func update_player ( info ) - > void :
update_color ( info . color )
2021-09-17 01:32:00 +02:00
func update_color ( color ) - > void : #change player's wolrldmodel color
2021-08-29 21:41:20 +02:00
var player_material = mesh . mesh . surface_get_material ( 0 ) . duplicate ( )
2021-09-11 22:23:41 +02:00
player_material . albedo_color = color
mesh . set_surface_override_material ( 0 , player_material )
2021-07-26 20:51:54 +02:00
2021-05-19 00:56:18 +02:00
func _physics_process ( delta ) :
2021-09-22 01:51:21 +02:00
if dead : # workaround for Godot player destruction crash
2021-10-06 23:49:16 +02:00
motion_velocity = Vector3 . ZERO
2021-09-22 01:51:21 +02:00
return
2021-09-17 01:32:00 +02:00
if not is_multiplayer_authority ( ) :
2021-09-08 21:36:43 +02:00
move_and_slide ( )
return
2021-05-19 01:59:58 +02:00
direction = Vector3 . ZERO
2021-05-19 00:56:18 +02:00
2021-09-07 23:23:48 +02:00
if is_on_floor ( ) and ground_check . is_colliding ( ) and not jetpack_active :
2021-09-26 03:07:41 +02:00
#snap = -get_floor_normal()
2021-05-19 01:59:58 +02:00
medium = " ground "
gravity_vec = Vector3 . ZERO
2021-05-19 00:56:18 +02:00
else :
2021-09-26 03:07:41 +02:00
#snap = Vector3.DOWN
2021-05-19 01:59:58 +02:00
medium = " air "
2021-05-19 00:56:18 +02:00
gravity_vec += Vector3 . DOWN * gravity * delta
2021-06-06 01:58:04 +02:00
if input_active :
if Input . is_action_just_pressed ( " move_jump " ) and is_on_floor ( ) :
2021-09-26 03:07:41 +02:00
#snap = Vector3.ZERO
2021-06-06 01:58:04 +02:00
gravity_vec = Vector3 . UP * jump
2021-09-25 18:34:02 +02:00
$ JumpSFX . rpc ( & " play " )
2021-06-06 01:58:04 +02:00
if Input . is_action_pressed ( " move_forward " ) :
direction -= transform . basis . z
if Input . is_action_pressed ( " move_backward " ) :
direction += transform . basis . z
if Input . is_action_pressed ( " move_left " ) :
direction -= transform . basis . x
if Input . is_action_pressed ( " move_right " ) :
direction += transform . basis . x
2021-09-07 23:23:48 +02:00
2021-09-08 23:54:04 +02:00
jetpack_was_active = jetpack_active
if jetpack_was_active :
jetpack_active = Input . is_action_pressed ( " move_special " ) if jetpack_fuel > 0 else false
else :
jetpack_active = Input . is_action_just_pressed ( " move_special " ) if jetpack_fuel > jetpack_min else false
2021-09-07 23:23:48 +02:00
if jetpack_active :
gravity_vec [ 1 ] += jetpack_thrust * delta
jetpack_fuel -= delta
elif jetpack_fuel < jetpack_tank :
jetpack_fuel = min ( jetpack_tank , jetpack_fuel + jetpack_recharge * delta )
2021-05-19 01:59:58 +02:00
2021-09-11 15:49:59 +02:00
#print("Jetpack fuel: ", jetpack_fuel, " active: ", jetpack_active, " delta: ", delta, " gravity vec: ", gravity_vec)
2021-09-17 01:32:00 +02:00
2021-05-19 01:59:58 +02:00
if direction . length ( ) > 0 : # normalized() will return a null
direction = direction . normalized ( )
2021-05-19 00:56:18 +02:00
2021-10-16 02:07:19 +02:00
# weapon bob
if direction . length ( ) > 0 :
if is_on_floor ( ) :
$ Head / Camera / Hand / Weapon . transform . origin . y = lerp ( $ Head / Camera / Hand / Weapon . transform . origin . y , sin ( main . uptime * 10 ) / 15 , 4 * delta )
else :
$ Head / Camera / Hand / Weapon . transform . origin . y *= 1 - delta * 8
$ Head / Camera / Hand / Weapon . transform . origin . y += sin ( main . uptime * 2 ) / 1000 * delta
$ Head / Camera / Hand / Weapon . transform . origin . y -= motion_velocity . y * delta / 60
if Input . is_action_just_pressed ( " move_jump " ) and is_on_floor ( ) :
2021-10-23 22:34:51 +02:00
# var tween = create_tween()
2021-10-16 02:07:19 +02:00
$ Head / Camera / Hand / Weapon . transform . origin . y -= 0.025
#$Head/Camera/Hand/Weapon.transform.origin.y -= 0.05
if is_on_floor ( ) and not previously_on_floor :
$ Head / Camera / Hand / Weapon . transform . origin . y -= 1
# if
# $Head/Camera/Hand/Weapon.transform.origin.y -= 0.25
2021-05-19 01:59:58 +02:00
speed = speed_type [ medium ]
accel = accel_type [ medium ]
2021-05-19 00:56:18 +02:00
2021-05-19 01:59:58 +02:00
velocity = velocity . lerp ( direction * speed , accel * delta )
2021-05-19 00:56:18 +02:00
2021-10-06 23:49:16 +02:00
motion_velocity = velocity + gravity_vec
2021-07-12 22:40:23 +02:00
move_and_slide ( )
2021-05-19 00:56:18 +02:00
2021-05-22 18:08:26 +02:00
if not is_on_floor ( ) and not ground_check . is_colliding ( ) : # while in mid-air collisions affect momentum
2021-10-06 23:49:16 +02:00
velocity . x = motion_velocity . x
velocity . z = motion_velocity . z
gravity_vec . y = motion_velocity . y
2021-07-12 22:40:23 +02:00
2021-10-16 02:07:19 +02:00
previously_on_floor = is_on_floor ( )
2021-10-23 22:34:51 +02:00
#lagging_movement_velocity.lerp(motion_velocity, delta)
2021-10-16 02:07:19 +02:00
2021-10-06 23:49:16 +02:00
rpc ( & ' update_movement ' , global_transform , head . get_rotation ( ) , motion_velocity , jetpack_active )
2021-07-12 22:40:23 +02:00
2021-05-25 01:14:37 +02:00
# (stair) climbing
2021-09-04 22:37:13 +02:00
# ↓ disabled - Tween is undergoing redesign in Godot 4
# if get_slide_count() > 1 and climb_check.is_colliding() and false:
# #print("climb started at climb state: ", climb_state)
# var test_y = climb_height * (1 - climb_state)
# #print("test_y: ", test_y)
# var climb_test_start = global_transform.translated(Vector3(0, test_y, 0))
# var climb_test_step = Vector3(0,0,-0.1).rotated(Vector3.UP, rotation.y)
# if not test_move(climb_test_start, climb_test_step): # no collision
# var step = climb_check.get_collision_point().y
# var start = global_transform.origin.y
## print("step: ", step, " start: ", start)
# climb_state = clamp((step - start) / climb_height, 0, 1)
# global_transform.origin.y += climb_height * climb_state
# #print("climb state to start: ", climb_state)
## print("Climb height: ", step - start, " Climb state: ", climb_state)
# climb_tween.remove_all()
# climb_tween.interpolate_property(self, "climb_state", climb_state, 0.0, climb_time, Tween.TRANS_CUBIC, Tween.EASE_IN)
# climb_tween.start()