Files
fps_project_1/scripts/spider.gd

255 lines
7.4 KiB
GDScript

extends CharacterBody3D
signal last_enemy_dead()
var player
var last_enemy : bool = false
@export var health = 3
@export var SPEED = 3.0
@export var loot_amount = 2
const MAX_LV = 10
const MAX_AV = 10
@export_enum("Enemy", "Trap") var enemy_type: int
@export var player_path : NodePath
@export var bullet : Resource
@export var casing : Resource
@export var bullet_speed = 150
@export var bullet_drop = .1
@export var random_spread_amt = .01
@export var bullet_damage = 1
@export var turret_look_speed = 6
@export var stamina : Resource
@export var ammo : Resource
@export var money : Resource
@export var health_pickup : Resource
@export var die_particles : Resource
@export var damage_number : Resource
@export_group("Taunts")
@export var taunts : Array[String] = []
@onready var level_control = get_tree().current_scene
@onready var nav_agent = $NavigationAgent3D
@onready var movement_shape = $MovementShape
@onready var barrel_1 = $TurretLook/Turret/Barrel1
@onready var barrel_2 = $TurretLook/Turret/Barrel2
@onready var casing_ejector = $TurretLook/Turret/CasingEjector
@onready var prefire_timer = $Timers/prefire_timer
@onready var postfire_timer = $Timers/postfire_timer
@onready var knocked_timer = $Timers/knocked_timer
@onready var stunned_timer = $Timers/stunned_timer
@onready var turret_look_next = $TurretLookNext
@onready var spider_look_next = $SpiderLookNext
@onready var body = $body
@onready var audio_fire = $AUIDO/Fire
@onready var turret = $TurretLook/Turret
@onready var turret_material = turret.get_surface_override_material(2)
@onready var turret_look = $TurretLook
@onready var smoke: GPUParticles3D = $TurretLook/Turret/Smoke
@onready var smoke_2: GPUParticles3D = $TurretLook/Turret/Smoke2
@onready var stunned_stars: Node3D = $body/StunnedStars
@onready var outline_meshes = [$TurretLook/Turret/turretoutline,
$body/leg1/foot1/foot1outline,
$body/leg1/leg1outline,
$body/leg2/foot2/foot2outline,
$body/leg2/leg2outline,
$body/leg3/foot3/foot3outline,
$body/leg3/leg3outline,
$body/leg4/foot4/foot4outline,
$body/leg4/leg4outline,
$body/bodyoutline]
var gravity = 9.8
var particlespawn
var rand_select
var rand_item
var body_look_to
var distance_to_player
var hive_velocity
var hive_nav_point
var dying
var can_die : bool = false
var player_in_view = false
var player_last_seen
var knocked = false
var stunned = false
func _ready():
player = level_control.player
turret_material.emission_enabled = false
#randomly start the postfire timer so enemy turrets aren't synced
var random_time = randf_range(0,5)
await get_tree().create_timer(random_time).timeout
postfire_timer.start()
func _process(delta):
# Navigation
if !knocked:
if hive_velocity:
velocity = hive_velocity
if !stunned:
stunned_stars.visible = false
#Sightline
if turret_look_next.is_colliding() and turret_look_next.get_collider().is_in_group("player"):
player_in_view = true
player_last_seen = turret_look_next.get_collider().global_position
if player != null:
spider_look_next.look_at(Vector3(player.global_position.x, 0, player.global_position.z), Vector3.UP)
body.rotation.y = lerp(body.rotation.y, spider_look_next.rotation.y, delta * 1)
turret_look_next.look_at(player.global_position,Vector3.UP)
turret_look.rotation = lerp(turret_look.rotation,turret_look_next.rotation,delta * turret_look_speed)
else:
body.rotation.y = lerp(body.rotation.y, body.rotation.y + 10, delta * .1)
turret_look.rotation.y = lerp(turret_look.rotation.y,turret_look.rotation.y - 10,delta * .5)
stunned_stars.visible = true
#apply gravity
if !is_on_floor():
velocity.y -= gravity * delta
move_and_slide()
if dying:
turret.global_rotation.y += 200 * delta
#fire(barrel_1)
#fire(barrel_2)
if can_die:
die()
func _on_area_3d_body_part_hit(dam,bullet_damage):
if !dying:
health -= dam * bullet_damage
if health <= 0:
dying_throws()
func _on_prefire_timer_timeout():
fire(barrel_1)
smoke.emitting = true
await get_tree().create_timer(.01).timeout # makes it too hard lol
fire(barrel_2)
smoke_2.emitting = true
turret_material.emission_enabled = false
prefire_timer.stop()
postfire_timer.start()
func _on_postfire_timer_timeout():
if turret_look_next.is_colliding() and turret_look_next.get_collider().is_in_group("player") and !stunned:
prefire_timer.start()
turret_material.emission_enabled = true
else:
postfire_timer.start()
func _on_knocked_timer_timeout():
print("KNOCK TIMEOUT")
velocity = Vector3(0,0,0)
knocked = false
func _on_stunned_timer_timeout():
print("STUN TIMEOUT")
stunned = false
func fire(barrel):
var instance_bullet = bullet.instantiate()
instance_bullet.position = barrel.global_position
instance_bullet.transform.basis = barrel.global_transform.basis
instance_bullet.bullet_speed = bullet_speed
instance_bullet.bullet_drop = bullet_drop
instance_bullet.random_spread_amt = random_spread_amt
instance_bullet.bullet_damage = bullet_damage
instance_bullet.fired_by = self
instance_bullet.target_type = enemy_type
get_tree().get_root().add_child(instance_bullet)
audio_fire.play()
spawn_casing()
func spawn_casing():
var instance_casing = casing.instantiate()
instance_casing.position = casing_ejector.global_position
instance_casing.transform.basis = casing_ejector.global_transform.basis
instance_casing.player_velocity = velocity * transform.basis
get_tree().get_root().add_child(instance_casing)
func dying_throws():
dying = true
drop_loot(loot_amount)
func die():
#remove from parent array
get_parent().enemies.erase(self)
level_control.enemy_count()
particlespawn = die_particles.instantiate()
particlespawn.position = self.global_position
particlespawn.transform.basis = self.global_transform.basis
get_tree().get_root().add_child(particlespawn)
drop_loot(loot_amount)
if GameGlobals.last_hit_path == str(get_path()):
GameGlobals.last_hit_path = null
SignalBus.emit_signal("enemy_killed")
queue_free()
func drop_loot(number_of_drops):
#pickup drop
while number_of_drops > 0:
var pickup_spawn = level_control.item_pickup.instantiate()
var item_stats = level_control.pickup_spawn(false)
##SET VARIABLES
pickup_spawn.pickup_type = item_stats["pickup_type"]
pickup_spawn.ammo_type = item_stats["ammo_type"]
pickup_spawn.value = item_stats["value"]
var lv_x = randf_range(-MAX_LV,MAX_LV)
var lv_y = randf_range(0,MAX_LV)
var lv_z = randf_range(-MAX_LV,MAX_LV)
var av_x = randf_range(-MAX_AV,MAX_AV)
var av_y = randf_range(-MAX_AV,MAX_AV)
var av_z = randf_range(-MAX_AV,MAX_AV)
# Random Item Drop
pickup_spawn.position = self.global_position + Vector3(0,2,0) #added height to spawn location since origin is on the ground
pickup_spawn.transform.basis = self.global_transform.basis
pickup_spawn.linear_velocity += self.global_transform.basis * Vector3(lv_x,lv_y,lv_z)
pickup_spawn.angular_velocity += self.global_transform.basis * Vector3(av_x,av_y,av_z)
await get_tree().create_timer(.05).timeout
get_tree().get_root().add_child(pickup_spawn)
number_of_drops -= 1
if number_of_drops <= 0:
can_die = true
func save():
var save_dict = {
"filename" : get_scene_file_path(),
"parent" : get_parent().get_path(),
"pos_x" : position.x,
"pos_y" : position.y,
"pos_z" : position.z,
"rot_x" : rotation.x,
"rot_y" : rotation.y,
"rot_z" : rotation.z,
"health" : health
}
return save_dict
func _on_area_3d_body_entered(body: Node3D) -> void:
pass # Replace with function body.
func _exit_tree() -> void:
get_parent().enemies.erase(self)