Files

175 lines
5.0 KiB
GDScript

extends CharacterBody2D
enum States {
WALKING,
PANIC,
WAITING
}
@export var min_state_dur: float
@export var max_state_dur: float
@export var min_time_till_attack: float
@export var max_time_till_attack: float
@export var min_attack_duration: float
@export var max_attack_duration: float
@export var walk_speed: float
@export var panic_speed: float
@export var seagull_speed: float
@onready var is_attacked: bool = false # I shouldve made these an enum tbh
@onready var attack_approaching: bool = false
@onready var is_retreating: bool = false
@onready var walk_dir = Vector2.ZERO
@onready var is_flipped: bool = false
@onready var seagull_is_flipped: bool = false
@onready var seagull_dir = Vector2.ZERO
@onready var seagull_home_pos = Vector2.ZERO
@onready var received_biscuit: bool = false
var time_till_attacked: float
var time_till_abducted: float
var current_state: States
var state_duration: float
func _ready():
time_till_attacked = randf_range(min_time_till_attack, max_time_till_attack)
change_walk_dir()
new_state()
func _physics_process(delta: float):
if !is_attacked:
match current_state:
States.WALKING: act_walking(delta)
States.PANIC: act_walking(delta, true)
States.WAITING:
if !$PigAnimations.current_animation == "flip":
$PigAnimations.stop()
else:
if time_till_abducted > 0: act_walking(delta, true)
else: pass
attack_logic(delta)
if walk_dir.x < 0 && !is_flipped:
$PigAnimations.play("flip")
is_flipped = true
elif walk_dir.x > 0 && is_flipped:
$PigAnimations.play_backwards("flip")
is_flipped = false
state_duration -= delta
if time_till_attacked > 0: time_till_attacked -= delta
if state_duration <= 0.0: new_state()
func new_state():
state_duration = randf_range(min_state_dur, max_state_dur)
var next_state = randi_range(0, States.size() - 1)
if next_state == States.PANIC && randf() < 0.95:
next_state = States.WALKING if randi_range(0, 1) == 0 else States.WAITING
current_state = States.values()[next_state]
func act_walking(delta: float, panicked: bool = false):
var average_time_to_switch_dir: float = 2.0 if !panicked else 0.2
var should_switch_dir = randf() < delta / average_time_to_switch_dir
if should_switch_dir: change_walk_dir()
self.velocity = walk_dir * (walk_speed if !panicked else panic_speed)
self.move_and_slide()
if !$PigAnimations.current_animation == "flip":
$PigAnimations.play("walk")
func change_walk_dir():
walk_dir = Vector2(
randf_range(-1, 1),
randf_range(-1, 1)
).normalized()
func attack_logic(delta: float):
if time_till_attacked <= 0.0 && !(is_attacked || attack_approaching || is_retreating):
attack_approaching = true
seagull_home_pos = Vector2(
randf_range(-3000.0, 3000.0),
randf_range(-1920.0, -2500.0)
)
$Seagull.global_position = seagull_home_pos
$Seagull.visible = true
$Seagull.play("fly")
attack_approaching_logic(delta)
is_attacked_logic(delta)
retreating_logic(delta)
if seagull_dir.x < 0 && !seagull_is_flipped:
$SeagullAnimations.play("flip")
seagull_is_flipped = true
elif seagull_dir.x > 0 && seagull_is_flipped:
$SeagullAnimations.play_backwards("flip")
seagull_is_flipped = false
func attack_approaching_logic(delta: float):
if !attack_approaching: return
seagull_dir = ($PigSprite/SeagullAttackPos.global_position - $Seagull.global_position).normalized()
$Seagull.global_position += seagull_dir * seagull_speed * delta
var dist = $Seagull.global_position.distance_to($PigSprite/SeagullAttackPos.global_position)
if dist < 15.0:
$Seagull.global_position = $PigSprite/SeagullAttackPos.global_position
attack_approaching = false
is_attacked = true
$Seagull.play("attack")
if !$PigAnimations.current_animation == "flip": $PigAnimations.stop()
time_till_abducted = randf_range(min_attack_duration, max_attack_duration)
func is_attacked_logic(delta: float):
if !is_attacked: return
if time_till_abducted <= 0.0:
seagull_dir = (seagull_home_pos - $Seagull.global_position).normalized()
self.global_position += seagull_dir * seagull_speed * delta
$PigSprite.self_modulate.a = 0.5
$Collision.disabled = true
if self.global_position.y < -get_viewport_rect().size.y - 300.0:
get_tree().current_scene.pigs_abducted += 1
get_parent().remove_child(self)
if received_biscuit:
is_attacked = false
received_biscuit = false
is_retreating = true
get_tree().current_scene.pigs_saved += 1
time_till_abducted -= delta
func retreating_logic(delta: float):
if !is_retreating: return
seagull_dir = (seagull_home_pos - $Seagull.global_position).normalized()
$Seagull.global_position += seagull_dir * seagull_speed * delta
if $Seagull.global_position.y < -get_viewport_rect().size.y - 300.0:
is_retreating = false
$Seagull.global_position = seagull_home_pos
func _on_feed_zone_body_entered(body: Node2D):
if body is not CharacterBody2D: return
if body.name != "PlayerCharacter": return
if is_attacked && body.biscuit_count > 0 && time_till_abducted > 0.0:
received_biscuit = true
body.remove_biscuit()