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.

123 lines
3.3 KiB

  1. extends Node # Networking functionality
  2. var player
  3. var is_placing = false
  4. var placing_node
  5. var placed = []
  6. var max_placed = 5
  7. var start_action
  8. var confirm_action
  9. var delete_action
  10. var scene
  11. signal start_placement
  12. signal confirm_placement
  13. func _init(parent, scene_path):
  14. player = parent
  15. player.add_child(self)
  16. # Set the network master to the player's network master, which happens to be its name
  17. # This allows it to use master, slave keywords appropriately
  18. set_network_master(int(player.get_name()))
  19. scene = load(scene_path)
  20. func place_input():
  21. # We allow you to just click to place, without needing to press E
  22. var confirm = Input.is_action_just_pressed(confirm_action)
  23. if Input.is_action_just_pressed(start_action) or (confirm and not is_placing):
  24. # Press button twice to cancel
  25. if is_placing:
  26. # We changed our mind, delete the placing wall
  27. placing_node.queue_free()
  28. is_placing = false
  29. else:
  30. # Make a floating placement wall
  31. placing_node = create()
  32. is_placing = true
  33. if Input.is_action_just_pressed(delete_action):
  34. var pick = player.pick_from(placed)
  35. if pick != -1:
  36. rpc("remove_placed", pick)
  37. if is_placing or confirm:
  38. position_placement(placing_node)
  39. if confirm:
  40. # Order matters here: confirm_placement resets placing_node so we have to do anything with it first
  41. rpc("slave_place", placing_node.transform)
  42. confirm_placement(placing_node)
  43. func confirm_placement(node, tf=null):
  44. if tf:
  45. node.set_transform(tf)
  46. node.place()
  47. placed.append(node)
  48. check_count()
  49. placing_node = null
  50. is_placing = false
  51. func check_count():
  52. # If we've made max_walls, remove the first we made
  53. if placed.size() > max_placed:
  54. placed[0].queue_free()
  55. placed.pop_front()
  56. # When placing, make the about-to-disappear wall translucent
  57. if placed.size() >= max_placed:
  58. placed[0].make_last()
  59. # Find the point we're looking at, and put the wall there
  60. func position_placement(node):
  61. var aim = player.get_node("Yaw/Pitch").get_global_transform().basis
  62. var look_ray = player.get_node("TPCamera/Camera/Ray")
  63. var pos = look_ray.get_collision_point()
  64. node.set_translation(pos)
  65. var normal = look_ray.get_collision_normal()
  66. var towards = normal + pos
  67. var up = aim[2] # Wall should be horizontal to my view
  68. # This helps nearly horizontal walls be easier to make flat
  69. # We have two methods I'm deciding between
  70. var use_method_two = true
  71. if not use_method_two:
  72. # Method one: only allow horizontal or vertical, based on whether the surface faces you
  73. var on_wall_margin = 0.75
  74. if normal.dot(Vector3(0,1,0)) < on_wall_margin:
  75. var margin = 0.8
  76. if up.dot(normal) > margin: # The wall is facing us
  77. # We want flat
  78. up = Vector3(0,1,0)
  79. else:
  80. # We want straight
  81. up.y = 0
  82. else:
  83. # Method two: Make y more aggressive than other dimensions
  84. up.y = 3 * tanh(up.y)
  85. up = up.normalized()
  86. node.look_at(towards, up)
  87. func clear():
  88. for node in placed:
  89. node.queue_free()
  90. placed = []
  91. slave func slave_place(tf):
  92. var node = create()
  93. confirm_placement(node, tf)
  94. sync func remove_placed(index):
  95. placed[index].queue_free()
  96. placed.remove(index)
  97. func create():
  98. var node = scene.instance()
  99. print(node)
  100. player.get_node("/root/Level").add_child(node)
  101. # We have to call_deferred because we're `load`ing instead of `preload`ing. TODO: preload?
  102. node.init(player)
  103. return node