A team game with an emphasis on movement (with no shooting), inspired by Overwatch and Zineth
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
4.1 KiB

  1. # Copyright (c) 2015 Calinou
  2. # This source code form is governed by the MIT license.
  3. # Original: https://raw.githubusercontent.com/Calinou/fps-test/master/scripts/player.gd
  4. extends RigidBody
  5. var view_sensitivity = 0.25
  6. var yaw = 0
  7. var pitch = 0
  8. var timer = 0
  9. # Walking speed and jumping height are defined later.
  10. var walk_speed = 2
  11. var jump_speed = 3
  12. const air_accel = .6
  13. var floor_friction = 0.92
  14. var air_friction = 0.98
  15. var health = 100
  16. var stamina = 10000
  17. var debug_node
  18. slave var slave_transform = Basis()
  19. slave var slave_lin_v = Vector3()
  20. slave var slave_ang_v = Vector3()
  21. func _ready():
  22. set_process_input(true)
  23. # Capture mouse once game is started:
  24. Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
  25. debug_node = get_node("/root/world/Debug")
  26. if is_network_master():
  27. get_node("Yaw/Camera").make_current()
  28. func _input(event):
  29. if is_network_master():
  30. if event is InputEventMouseMotion:
  31. yaw = fmod(yaw - event.relative.x * view_sensitivity, 360)
  32. pitch = max(min(pitch - event.relative.y * view_sensitivity, 85), -85)
  33. get_node("Yaw").set_rotation(Vector3(0, deg2rad(yaw), 0))
  34. get_node("Yaw/Camera").set_rotation(Vector3(deg2rad(pitch), 0, 0))
  35. # Toggle mouse capture:
  36. if Input.is_action_pressed("toggle_mouse_capture"):
  37. if (Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED):
  38. Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
  39. view_sensitivity = 0
  40. else:
  41. Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
  42. view_sensitivity = 0.25
  43. # Quit the game:
  44. if Input.is_action_pressed("quit"):
  45. quit()
  46. master func _integrate_forces(state):
  47. control_player(state)
  48. rpc_unreliable("set_status", get_transform(), get_linear_velocity(), get_angular_velocity())
  49. slave func set_status(tf, lv, av):
  50. set_transform(tf)
  51. set_linear_velocity(lv)
  52. set_angular_velocity(av)
  53. func control_player(state):
  54. var aim = get_node("Yaw").get_global_transform().basis
  55. var direction = Vector3()
  56. if Input.is_action_pressed("move_forwards"):
  57. direction -= aim[2]
  58. if Input.is_action_pressed("move_backwards"):
  59. direction += aim[2]
  60. if Input.is_action_pressed("move_left"):
  61. direction -= aim[0]
  62. if Input.is_action_pressed("move_right"):
  63. direction += aim[0]
  64. direction = direction.normalized()
  65. var ray = get_node("Ray")
  66. if ray.is_colliding():
  67. var up = state.get_total_gravity().normalized()
  68. var normal = ray.get_collision_normal()
  69. var floor_velocity = Vector3()
  70. var object = ray.get_collider()
  71. if object is RigidBody or object is StaticBody:
  72. var point = ray.get_collision_point() - object.get_translation()
  73. var floor_angular_vel = Vector3()
  74. if object is RigidBody:
  75. floor_velocity = object.get_linear_velocity()
  76. floor_angular_vel = object.get_angular_velocity()
  77. elif object is StaticBody:
  78. floor_velocity = object.get_constant_linear_velocity()
  79. floor_angular_vel = object.get_constant_angular_velocity()
  80. # Surely there should be a function to convert Euler angles to a 3x3 matrix
  81. var tf = Basis(Vector3(1, 0, 0), floor_angular_vel.x)
  82. tf = tf.rotated(Vector3(0, 1, 0), floor_angular_vel.y)
  83. tf = tf.rotated(Vector3(0, 0, 1), floor_angular_vel.z)
  84. floor_velocity += tf.xform_inv(point) - point
  85. yaw = fmod(yaw + rad2deg(floor_angular_vel.y) * state.get_step(), 360)
  86. get_node("Yaw").set_rotation(Vector3(0, deg2rad(yaw), 0))
  87. var diff = floor_velocity + direction * walk_speed
  88. state.apply_impulse(Vector3(), diff * get_mass())
  89. var lin_v = state.get_linear_velocity()
  90. lin_v.x *= floor_friction
  91. lin_v.z *= floor_friction
  92. state.set_linear_velocity(lin_v)
  93. if Input.is_action_pressed("jump"):
  94. state.apply_impulse(Vector3(), normal * jump_speed * get_mass())
  95. else:
  96. state.apply_impulse(Vector3(), direction * air_accel * get_mass())
  97. var lin_v = state.get_linear_velocity()
  98. lin_v.x *= air_friction
  99. lin_v.z *= air_friction
  100. state.set_linear_velocity(lin_v)
  101. # print(state.get_linear_velocity())
  102. var vel = get_linear_velocity()
  103. debug_node.set_text("%8.f,%8.f,%8.f" % [vel.x, vel.y, vel.z])
  104. state.integrate_forces()
  105. func _exit_scene():
  106. Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
  107. # Functions
  108. # =========
  109. # Quits the game:
  110. func quit():
  111. get_tree().quit()