2021-06-07 19:11:42 +02:00
extends CharacterBody3D
2021-05-19 00:56:18 +02:00
@ export var mouse_sensitivity : = 0.35
2021-08-21 15:03:51 +02:00
@ onready var main = get_tree ( ) . root . get_node ( " Main " )
@ 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-05-19 00:56:18 +02:00
@ onready var head = $ Head
2021-05-24 21:57:19 +02:00
@ onready var camera = $ Head / Camera
@ onready var tween = $ Head / Camera / Tween
2021-05-22 02:10:00 +02:00
@ onready var ground_check = $ GroundCheck
2021-07-12 22:40:23 +02:00
@ onready var climb_tween = $ ClimbTween # undergoing redesign in Godot 4
2021-05-24 21:57:19 +02:00
@ onready var climb_check = $ ClimbCheck
@ 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-05-25 01:14:37 +02:00
@ onready var body_height = body . shape . height
2021-06-07 19:11:42 +02:00
@ onready var body_y = body . position . y
2021-05-25 01:14:37 +02:00
@ onready var mesh_height = mesh . mesh . mid_height
2021-06-07 19:11:42 +02:00
@ onready var mesh_y = mesh . position . y
@ onready var climb_check_y = climb_check . position . y
@ 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-05-25 01:14:37 +02:00
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
2021-06-07 19:11:42 +02:00
body . position . y = body_y + factor * climb_height / 2
2021-05-25 01:14:37 +02:00
mesh . mesh . mid_height = mesh_height - factor * climb_height
2021-06-07 19:11:42 +02:00
mesh . position . y = mesh_y + factor * climb_height / 2
2021-05-25 01:14:37 +02:00
2021-06-07 19:11:42 +02:00
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
var jump : = 14
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-07-12 22:40:23 +02:00
@ puppet func update_movement ( player_transform , head_rotation ) :
global_transform = player_transform
head . set_rotation ( head_rotation )
2021-06-19 03:40:10 +02:00
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-06-19 00:31:22 +02:00
2021-08-21 15:03:51 +02:00
# generate_info()
2021-07-12 22:40:23 +02:00
rpc_config ( & ' move_and_slide ' , MultiplayerAPI . RPC_MODE_REMOTE )
rpc_config ( & " aim " , MultiplayerAPI . RPC_MODE_REMOTE )
rpc_config ( & " set_global_transform " , MultiplayerAPI . RPC_MODE_REMOTE )
rpc_config ( & " set_linear_velocity " , MultiplayerAPI . RPC_MODE_REMOTE )
head . rpc_config ( & " set_rotation " , MultiplayerAPI . RPC_MODE_REMOTE )
rpc_config ( & " set_info " , MultiplayerAPI . RPC_MODE_REMOTE )
# rpc_config(&'move_and_slide', MultiplayerAPI.RPC_MODE_PUPPETSYNC)
# rpc_config(&"aim", MultiplayerAPI.RPC_MODE_PUPPETSYNC)
# rpc_config(&"set_global_transform", MultiplayerAPI.RPC_MODE_PUPPET)
# rpc_config(&"set_linear_velocity", MultiplayerAPI.RPC_MODE_PUPPET)
# head.rpc_config(&"set_rotation", MultiplayerAPI.RPC_MODE_PUPPETSYNC)
# rpc_config(&"set_info", MultiplayerAPI.RPC_MODE_PUPPETSYNC)
2021-06-09 19:41:52 +02:00
2021-05-19 00:56:18 +02:00
func aim ( event ) - > void :
var mouse_motion = event as InputEventMouseMotion
if mouse_motion :
2021-07-04 00:42:42 +02:00
rotation . y -= deg2rad ( mouse_motion . relative . x * 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
current_tilt -= deg2rad ( mouse_motion . relative . y * mouse_sensitivity / view_zoom )
head . rotation . x = clamp ( current_tilt , deg2rad ( - 90 ) , deg2rad ( 90 ) )
2021-05-19 00:56:18 +02:00
func _input ( event ) - > void :
2021-06-03 17:44:25 +02:00
if not input_active :
return
2021-05-19 00:56:18 +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-07-26 20:51:54 +02:00
2021-06-18 01:43:10 +02:00
if 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-06-18 01:43:10 +02:00
if 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 ) :
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-08-23 01:57:47 +02:00
func damage ( hp : int ) :
2021-08-25 12:03:35 +02:00
var target = main . player_list . players [ self . get_network_master ( ) ]
target . health -= hp
2021-08-29 20:32:46 +02:00
#if target.health <= 0: # int(name) is the player instance node name signifying owner's PID
# die()
2021-08-29 22:47:40 +02:00
func die ( killer_pid : int ) :
2021-08-29 20:32:46 +02:00
# if get_tree().get_rpc_sender_id() != get_network_master():
# print ("Death requested by a non-master. Ignoring")
# return
main . rpc ( & ' destroy_player ' , self . get_network_master ( ) )
2021-08-29 22:47:40 +02:00
main . chat . rpc ( & ' chat_notification ' , " Player [/i][b][color= " + main . player_list . players [ self . get_network_master ( ) ] . color . to_html ( ) + " ] " + main . player_list . players [ self . get_network_master ( ) ] . name + " [/color][/b][i] was killed by " + main . player_list . players [ killer_pid ] . name )
2021-08-29 20:32:46 +02:00
#queue_free()
2021-08-29 22:47:40 +02:00
func update_color ( pid ) - > void : #change player's wolrdmodel color
2021-08-29 21:41:20 +02:00
## @onready var player_material =
## var material = player_material
2021-08-29 22:47:40 +02:00
if pid != get_network_master ( ) :
print ( " Requesting color change for a different PID " )
return
2021-08-29 21:41:20 +02:00
var player_material = mesh . mesh . surface_get_material ( 0 ) . duplicate ( )
player_material . albedo_color = main . player_list . get ( self . get_network_master ( ) ) . color
print ( " Updating color of player pid " , self . get_network_master ( ) , " to " , player_material . albedo_color )
mesh . mesh . surface_set_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-07-01 13:53:05 +02:00
# rpc_unreliable(&'set_global_transform', global_transform)
# head.rpc_unreliable(&'set_rotation', head.get_rotation())
2021-07-12 22:40:23 +02:00
#rpc(&'set_global_transform', global_transform)
#head.rpc(&'set_rotation', head.get_rotation())
2021-05-19 01:59:58 +02:00
direction = Vector3 . ZERO
2021-05-19 00:56:18 +02:00
2021-05-22 02:10:00 +02:00
if is_on_floor ( ) and ground_check . is_colliding ( ) :
2021-05-19 01:59:58 +02:00
snap = - get_floor_normal ( )
medium = " ground "
gravity_vec = Vector3 . ZERO
2021-05-19 00:56:18 +02:00
else :
2021-05-19 01:59:58 +02:00
snap = Vector3 . DOWN
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 ( ) :
snap = Vector3 . ZERO
gravity_vec = Vector3 . UP * jump
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-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-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-06-07 19:11:42 +02:00
linear_velocity = velocity + gravity_vec
#slide = move_and_slide_with_snap(movement, snap, Vector3.UP)
2021-07-01 13:53:05 +02:00
# rpc_unreliable(&'set_linear_velocity', linear_velocity)
# rpc_unreliable(&"move_and_slide")
2021-07-04 21:50:13 +02:00
# rpc(&'set_linear_velocity', linear_velocity)
2021-07-12 22:40:23 +02:00
# rpc(&'move_and_slide')
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-06-07 19:11:42 +02:00
velocity . x = linear_velocity . x
velocity . z = linear_velocity . z
gravity_vec . y = linear_velocity . y
2021-07-12 22:40:23 +02:00
# update puppets
2021-08-23 01:57:47 +02:00
# if get_tree().network_peer.get_unique_id() == 1:
# rpc(&'update_movement', global_transform, head.get_rotation())
# else:
# rpc_id(1, &'update_movement', global_transform, head.get_rotation())
#
2021-07-12 22:40:23 +02:00
rpc ( & ' update_movement ' , global_transform , head . get_rotation ( ) )
2021-05-25 01:14:37 +02:00
# (stair) climbing
2021-07-12 22:40:23 +02:00
if get_slide_count ( ) > 1 and climb_check . is_colliding ( ) and false : # disabled - Tween is undergoing redesign in Godot 4
2021-05-25 01:14:37 +02:00
#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 )
2021-05-31 23:34:26 +02:00
global_transform . origin . y += climb_height * climb_state
2021-05-25 01:14:37 +02:00
#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 ( )