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.

113 lines
3.0 KiB

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