PipeArea.gd 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. @tool
  2. @icon("res://Assets/Sprites/Editor/Pipe.png")
  3. class_name PipeArea
  4. extends Node2D
  5. signal pipe_entered
  6. signal pipe_exited
  7. @onready var arrow_joint: Node2D = $ArrowJoint
  8. @onready var arrow: Sprite2D = $ArrowJoint/Arrow
  9. @onready var hitbox: Area2D = $Hitbox
  10. @export_enum("Down", "Up", "Left", "Right") var enter_direction := 0:
  11. set(value):
  12. enter_direction = value
  13. update_visuals()
  14. @export_range(0, 99) var pipe_id := 0:
  15. set(value):
  16. pipe_id = value
  17. update_visuals()
  18. @export_enum("0", "1", "2", "3", "4") var target_sub_level := 0
  19. @export_file("*.tscn") var target_level := ""
  20. @export var exit_only := false:
  21. set(value):
  22. exit_only = value
  23. update_visuals()
  24. var can_enter := true
  25. static var exiting_pipe_id := -1
  26. func _ready() -> void:
  27. update_visuals()
  28. if Engine.is_editor_hint() == false and Global.current_game_mode != Global.GameMode.LEVEL_EDITOR:
  29. run_pipe_check()
  30. func run_pipe_check() -> void:
  31. if exiting_pipe_id == pipe_id and exit_only:
  32. exit_pipe()
  33. func _physics_process(_delta: float) -> void:
  34. if Engine.is_editor_hint() == false:
  35. in_game()
  36. update_visuals()
  37. func update_visuals() -> void:
  38. if Engine.is_editor_hint() or (Global.current_game_mode == Global.GameMode.LEVEL_EDITOR and LevelEditor.playing_level == false):
  39. show()
  40. $ArrowJoint.show()
  41. $ArrowJoint.rotation = get_vector(enter_direction).angle() - deg_to_rad(90)
  42. $ArrowJoint/Arrow.flip_v = exit_only
  43. var id := pipe_id
  44. $Node2D/CenterContainer/Label.text = str(id)
  45. else:
  46. hide()
  47. func exit_pipe() -> void:
  48. pipe_exited.emit()
  49. await get_tree().physics_frame
  50. for i in get_tree().get_nodes_in_group("Players"):
  51. i.go_to_exit_pipe(self)
  52. for i in get_tree().get_nodes_in_group("Players"):
  53. await get_tree().create_timer(0.5, false).timeout
  54. await i.exit_pipe(self)
  55. exiting_pipe_id = -1
  56. func get_vector(direction := 0) -> Vector2:
  57. match direction:
  58. 0:
  59. return Vector2.DOWN
  60. 1:
  61. return Vector2.UP
  62. 2:
  63. return Vector2.LEFT
  64. 3:
  65. return Vector2.RIGHT
  66. _:
  67. return Vector2.ZERO
  68. func get_input_direction(direction := 0) -> String:
  69. match direction:
  70. 0:
  71. return "move_down"
  72. 1:
  73. return "move_up"
  74. 2:
  75. return "move_left"
  76. 3:
  77. return "move_right"
  78. _:
  79. return ""
  80. func in_game() -> void:
  81. if exit_only:
  82. return
  83. for i in hitbox.get_overlapping_areas():
  84. if i.owner is Player:
  85. run_player_check(i.owner)
  86. func run_player_check(player: Player) -> void:
  87. if Global.player_action_pressed(get_input_direction(enter_direction), player.player_id) and can_enter and (player.is_on_floor() or enter_direction == 1 or player.gravity_vector != Vector2.DOWN) and player.state_machine.state.name == "Normal":
  88. can_enter = false
  89. pipe_entered.emit()
  90. DiscoLevel.can_meter_tick = false
  91. Level.in_vine_level = false
  92. player.enter_pipe(self)