123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- extends "res://entities/GridBasedMovable.gd"
- enum STATES {IDLE, MOVE}
- enum START_DIRS {UP, DOWN, LEFT, RIGHT}
- enum _DIRECTIONS {UP, DOWN, LEFT, RIGHT, NONE}
- var state = STATES.MOVE
- var turned = false
- var push_not_blocked #true when able to push or not pushing at all, false when push failed (blocked, unable to move)
- var idle_started = true
- @export var min_idle_time = 0.2
- @export var max_idle_time = 0.2
- @export var start_direction: START_DIRS = START_DIRS.UP
- @onready var current_direction = start_direction
- @onready var idle_timer = $IdleTimer
- @export var can_push = false
- func _ready() -> void:
- super._ready()
- requested_direction = start_direction
- update_rotation_point(requested_direction)
- push_not_blocked = true
-
- func _physics_process(delta: float) -> void:
- move()
- _handle_movement(delta)
- func reset_to_idle():
- idle_timer.wait_time = randf_range(min_idle_time, max_idle_time)
- state = STATES.IDLE
- idle_started = true
- idle_timer.start()
- push_not_blocked = true
-
- func move():
- var pushable_found = false
- if ray_front.is_colliding() and is_grid_aligned():
- var frontObject = ray_front.get_collider()
- if frontObject != null:
- if frontObject.is_in_group("pushable") and not frontObject.is_in_group("heavy"):
- pushable_found = true
- elif frontObject.get_parent().is_in_group("pushable") and not frontObject.get_parent().is_in_group("heavy"):
- pushable_found = true
- if state == STATES.IDLE:
- if idle_timer.get_time_left() < 0.1 and turned == false:
- update_rotation_point(get_opposite_direction(requested_direction))
- turned = true
-
- if state == STATES.MOVE:
- if ray_front.is_colliding() and is_grid_aligned():
-
- var frontObject = ray_front.get_collider()
-
- if not (pushable_found and can_push == true and push_not_blocked == true):
-
- if idle_timer.get_time_left() == 0 and idle_started == false:
- reset_to_idle()
- else:
- idle_started = false
-
- else:
- requested_direction = current_direction
-
- if ray_ground.is_colliding():
- var groundObject = ray_ground.get_collider()
- if groundObject != null and groundObject.is_in_group("player"):
- groundObject.hit()
-
- var frontObject = ray_front.get_collider()
- if frontObject != null and frontObject.is_in_group("player"):
- frontObject.hit()
- elif frontObject != null and frontObject.get_parent().is_in_group("player"):
- frontObject.get_parent().hit()
-
- if requested_direction != DIRECTIONS.NONE and ray_front.is_colliding() and is_grid_aligned() and can_push == true:
- var local_movedir = direction_to_vector(requested_direction)
- var next_target_pos = position + local_movedir * step_size
- if frontObject != null:
- var _distance = (next_target_pos - frontObject.position).length()
-
- if frontObject.is_in_group("pushable") and not frontObject.is_in_group("heavy"):
-
- push_not_blocked = push(frontObject, requested_direction)
-
-
- elif frontObject.get_parent().is_in_group("pushable") and not frontObject.get_parent().is_in_group("heavy"):
- push_not_blocked = push(frontObject.get_parent(), requested_direction)
-
-
- elif frontObject.is_in_group("heavy") or frontObject.get_parent().is_in_group("heavy"):
- push_not_blocked = true
- else:
- push_not_blocked = true
-
- else:
- print ("error: front raycast hit null object")
-
- if requested_direction == _DIRECTIONS.NONE:
- requested_direction = mesh_direction
-
- func change_direction():
- if state == STATES.IDLE:
-
- requested_direction = get_opposite_direction(requested_direction)
- update_rotation_point(requested_direction)
-
- current_direction = requested_direction
- push_not_blocked = true
-
- state = STATES.MOVE
-
-
-
- func _on_IdleTimer_timeout() -> void:
- current_direction = get_opposite_direction(requested_direction)
- change_direction()
-
-
- turned = false
- func hit():
- call_deferred("queue_free")
|