Bug.gd 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. extends "res://entities/GridBasedMovable.gd"
  2. enum STATES {IDLE, MOVE}
  3. enum START_DIRS {UP, DOWN, LEFT, RIGHT}
  4. enum _DIRECTIONS {UP, DOWN, LEFT, RIGHT, NONE}
  5. var state = STATES.MOVE
  6. var turned = false
  7. var push_not_blocked #true when able to push or not pushing at all, false when push failed (blocked, unable to move)
  8. var idle_started = true
  9. @export var min_idle_time = 0.2
  10. @export var max_idle_time = 0.2
  11. @export var start_direction: START_DIRS = START_DIRS.UP
  12. @onready var current_direction = start_direction
  13. @onready var idle_timer = $IdleTimer
  14. @export var can_push = false
  15. func _ready() -> void:
  16. super._ready()
  17. requested_direction = start_direction
  18. update_rotation_point(requested_direction)
  19. push_not_blocked = true
  20. func _physics_process(delta: float) -> void:
  21. move()
  22. _handle_movement(delta)
  23. func reset_to_idle():
  24. idle_timer.wait_time = randf_range(min_idle_time, max_idle_time)
  25. state = STATES.IDLE
  26. idle_started = true
  27. idle_timer.start()
  28. push_not_blocked = true
  29. func move():
  30. var pushable_found = false
  31. if ray_front.is_colliding() and is_grid_aligned():
  32. var frontObject = ray_front.get_collider()
  33. if frontObject != null:
  34. if frontObject.is_in_group("pushable") and not frontObject.is_in_group("heavy"):
  35. pushable_found = true
  36. elif frontObject.get_parent().is_in_group("pushable") and not frontObject.get_parent().is_in_group("heavy"):
  37. pushable_found = true
  38. if state == STATES.IDLE:
  39. if idle_timer.get_time_left() < 0.1 and turned == false:
  40. update_rotation_point(get_opposite_direction(requested_direction))
  41. turned = true
  42. if state == STATES.MOVE:
  43. if ray_front.is_colliding() and is_grid_aligned():
  44. var frontObject = ray_front.get_collider()
  45. if not (pushable_found and can_push == true and push_not_blocked == true):
  46. if idle_timer.get_time_left() == 0 and idle_started == false:
  47. reset_to_idle()
  48. else:
  49. idle_started = false
  50. else:
  51. requested_direction = current_direction
  52. if ray_ground.is_colliding():
  53. var groundObject = ray_ground.get_collider()
  54. if groundObject != null and groundObject.is_in_group("player"):
  55. groundObject.hit()
  56. var frontObject = ray_front.get_collider()
  57. if frontObject != null and frontObject.is_in_group("player"):
  58. frontObject.hit()
  59. elif frontObject != null and frontObject.get_parent().is_in_group("player"):
  60. frontObject.get_parent().hit()
  61. if requested_direction != DIRECTIONS.NONE and ray_front.is_colliding() and is_grid_aligned() and can_push == true:
  62. var local_movedir = direction_to_vector(requested_direction)
  63. var next_target_pos = position + local_movedir * step_size
  64. if frontObject != null:
  65. var _distance = (next_target_pos - frontObject.position).length()
  66. if frontObject.is_in_group("pushable") and not frontObject.is_in_group("heavy"):
  67. push_not_blocked = push(frontObject, requested_direction)
  68. elif frontObject.get_parent().is_in_group("pushable") and not frontObject.get_parent().is_in_group("heavy"):
  69. push_not_blocked = push(frontObject.get_parent(), requested_direction)
  70. elif frontObject.is_in_group("heavy") or frontObject.get_parent().is_in_group("heavy"):
  71. push_not_blocked = true
  72. else:
  73. push_not_blocked = true
  74. else:
  75. print ("error: front raycast hit null object")
  76. if requested_direction == _DIRECTIONS.NONE:
  77. requested_direction = mesh_direction
  78. func change_direction():
  79. if state == STATES.IDLE:
  80. requested_direction = get_opposite_direction(requested_direction)
  81. update_rotation_point(requested_direction)
  82. current_direction = requested_direction
  83. push_not_blocked = true
  84. state = STATES.MOVE
  85. func _on_IdleTimer_timeout() -> void:
  86. current_direction = get_opposite_direction(requested_direction)
  87. change_direction()
  88. turned = false
  89. func hit():
  90. call_deferred("queue_free")