123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- extends CharacterBody2D
- class_name UFO
- @export var movement_speed: float = 800.0
- @export var radius: float = 150.0
- var max_velocity: float = movement_speed
- @onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D
- @onready var plants: Node = $"../../Plants"
- var target: Plant = null
- var target2: Plant = null
- var announce_self: bool = false
- var dead = false
- @export_range(1.0, 1000.0) var dps: float = 10.0
- @export var max_hp = 100.0
- var hp: float
- var dead_timer: Timer = Timer.new()
- @export var wheat_out: int = 3
- var Wheat = preload("res://scene/entity/wheat.tscn")
- @export var should_rotate: bool = true
- @onready var ray = $Plx/Ray
- @onready var ray2 = find_child("Ray2")
- var attack_range = 1000.0
- var second_player = find_child("AudioStreamPlayer2D2")
- @onready var power_level: float = $"../../Waves".power_level
- func fuck():
- return false
- func _ready():
- # Workaround bug body->get_space()
- call_deferred("actor_setup")
- navigation_agent.connect("velocity_computed", move)
-
- max_hp *= power_level
- dps *= power_level * pow(power_level, 0.7)
-
- $RerollTimer.connect("timeout", roll_movement_target)
- $DamageTimer.connect("timeout", damage_target)
-
- navigation_agent.set_path_desired_distance(10.0)
- navigation_agent.set_target_desired_distance(attack_range)
- navigation_agent.set_path_max_distance(40.0)
- navigation_agent.set_avoidance_enabled(true)
- navigation_agent.set_radius(radius)
- navigation_agent.set_neighbor_distance(movement_speed * 2)
- navigation_agent.set_max_speed(movement_speed)
-
- $AudioStreamPlayer2D.set_bus("Music" + str(randi_range(0, 3)))
- $AudioStreamPlayer2D.play($"../../HomeSound".get_playback_position())
-
- if second_player != null:
- second_player.set_bus("Music" + str(randi_range(0, 3)))
- second_player.play($"../../HomeSound".get_playback_position())
-
- hp = max_hp
- $Plx/HP.set_max(max_hp)
- $Plx/HP.set_value(max_hp)
-
- func _process(delta):
- if dead:
- _process_dead(delta)
- if navigation_agent.is_target_reached() and target != null:
- enable_ray(ray, target)
- if ray2 != null:
- if target2 == null or target2.dead:
- target2 = roll_aux_target()
- if target2 != null:
- enable_ray(ray2, target2)
- else:
- hide_ray(ray2)
- if $DamageTimer.is_stopped():
- $DamageTimer.start()
- if target.dead:
- if target2 != null:
- target = target2
- target2 = null
- else:
- target = roll_movement_target()
- hide_ray(ray)
- else:
- hide_ray(ray)
- hide_ray(ray2)
- $DamageTimer.stop()
- func _process_dead(delta: float):
- var time_left = dead_timer.get_time_left() * 3.0
- var scale = ease(time_left, 5)
- set_scale(Vector2(scale, scale))
- $AudioStreamPlayer2D.set_volume_db($AudioStreamPlayer2D.get_volume_db() - delta * 30.0)
- if second_player != null:
- second_player.set_volume_db(second_player.get_volume_db() - delta * 30.0)
- if time_left == 0.0:
- get_parent().remove_child(self)
- queue_free()
- func _physics_process(delta):
- if fuck():
- return
- if navigation_agent.is_target_reached():
- var new_speed = velocity.length() - delta * movement_speed * 2.0
- velocity = velocity.normalized() * new_speed
- move_and_slide()
- else:
- var current_agent_position: Vector2 = global_transform.origin
- var next_path_position: Vector2 = navigation_agent.get_next_location()
- var new_velocity: Vector2 = next_path_position - current_agent_position
- new_velocity = new_velocity.normalized()
- new_velocity = new_velocity * movement_speed
- navigation_agent.set_velocity(new_velocity)
- func actor_setup():
- await get_tree().physics_frame
- target = roll_movement_target()
- func roll_movement_target():
- var all_plants = plants.get_children()
- var count = all_plants.size()
- announce_self = true
- var res: UFO = null
- if count == 0:
- $RerollTimer.start()
- else:
- var i = 0
- while (res == null or res.dead) and i < 10:
- res = all_plants[randi_range(0, count - 1)]
- i += 1
- if i == 10:
- res = null
- $RerollTimer.start()
- else:
- navigation_agent.set_target_location(res.get_global_position())
- return res
-
- func roll_aux_target():
- var all_plants = plants.get_children()
- for plant in all_plants:
- if plant != target and plant.get_global_position().distance_to(get_global_position()) <= attack_range:
- return plant
- return null
- func damage_target():
- if target != null:
- target.deal_damage(dps / 20.0, self if announce_self else null)
- if target2 != null:
- target2.deal_damage(dps / 20.0, self if announce_self else null)
- func move(velocity_: Vector2):
- velocity = velocity_
- move_and_slide()
- if should_rotate:
- var top = find_child("Top")
- top.set_rotation(lerp_angle(top.get_rotation(), velocity.angle(), 10.0 * get_physics_process_delta_time()))
- func _on_area_2d_body_entered(body):
- if body.get_class() == "Bullet":
- deal_damage(body.damage)
- body.get_parent().remove_child(body)
- body.queue_free()
-
- func deal_damage(damage):
- hp -= damage
- $Plx/HP.set_value(hp)
- if hp <= 0 and not dead:
- dead = true
- $Coin.play()
- set_collision_layer_value(1, false)
- set_collision_mask_value(1, false)
- $Plx/HP.hide()
- dead_timer.set_wait_time(0.333)
- dead_timer.set_one_shot(true)
- add_child(dead_timer)
- dead_timer.start()
- $DamageTimer.stop()
- hide_ray(ray)
- hide_ray(ray2)
- call_deferred("spawn_wheat")
- func spawn_wheat():
- for i in range(0, ceil(wheat_out * sqrt(power_level))):
- var wheat = Wheat.instantiate()
- wheat.rotate(randf_range(-PI, PI))
- wheat.set_position(get_global_position())
- $"../../Wheat".add_child(wheat)
- func enable_ray(ray, target: Node2D):
- if ray != null:
- var diff = target.get_global_position() - get_global_position()
- var poly = ray.get_polygon()
- poly[1] = diff + Vector2(-80.0, target.body.texture.get_size().y / 2 + 30.0)
- poly[2] = diff + Vector2(80.0, target.body.texture.get_size().y / 2 + 30.0)
- ray.set_polygon(poly)
- ray.show()
- func hide_ray(r):
- if r != null:
- r.hide()
-
-
|