npcs and enemies now inherit from character state
This commit is contained in:
@@ -867,32 +867,38 @@ taunts = Array[String](["did i do that?", "you've been on my shitlist", "you lik
|
||||
script = ExtResource("6_87l3v")
|
||||
initial_state = NodePath("Idle")
|
||||
|
||||
[node name="Idle" type="Node" parent="StateMachine"]
|
||||
[node name="Idle" type="Node" parent="StateMachine" node_paths=PackedStringArray("character")]
|
||||
script = ExtResource("7_cwyr0")
|
||||
move_speed = 1.5
|
||||
turret_speed = 0.5
|
||||
character = NodePath("../..")
|
||||
move_speed = 1.5
|
||||
poi_investigate = true
|
||||
poi_change_to_search = true
|
||||
|
||||
[node name="Stunned" type="Node" parent="StateMachine"]
|
||||
[node name="Stunned" type="Node" parent="StateMachine" node_paths=PackedStringArray("character")]
|
||||
script = ExtResource("8_wpql0")
|
||||
character = NodePath("../..")
|
||||
|
||||
[node name="Die" type="Node" parent="StateMachine"]
|
||||
[node name="Die" type="Node" parent="StateMachine" node_paths=PackedStringArray("character")]
|
||||
script = ExtResource("9_6mvds")
|
||||
character = NodePath("../..")
|
||||
metadata/_custom_type_script = "uid://dhxolagi0b5s1"
|
||||
|
||||
[node name="Attack" type="Node" parent="StateMachine" node_paths=PackedStringArray("alert_sound")]
|
||||
[node name="Attack" type="Node" parent="StateMachine" node_paths=PackedStringArray("alert_sound", "character")]
|
||||
script = ExtResource("10_gicen")
|
||||
alert_sound = NodePath("../../AUIDO/Alarm")
|
||||
character = NodePath("../..")
|
||||
body_turn_speed = 1.0
|
||||
|
||||
[node name="Reload" type="Node" parent="StateMachine" node_paths=PackedStringArray("reload_sound", "servo_sound")]
|
||||
[node name="Reload" type="Node" parent="StateMachine" node_paths=PackedStringArray("reload_sound", "servo_sound", "character")]
|
||||
script = ExtResource("11_ekglj")
|
||||
reload_sound = NodePath("../../AUIDO/Reload")
|
||||
servo_sound = NodePath("../../AUIDO/ServoSingle")
|
||||
character = NodePath("../..")
|
||||
|
||||
[node name="Search" type="Node" parent="StateMachine"]
|
||||
[node name="Search" type="Node" parent="StateMachine" node_paths=PackedStringArray("character")]
|
||||
script = ExtResource("12_aasxo")
|
||||
character = NodePath("../..")
|
||||
poi_investigate = true
|
||||
poi_update_waypoint_immediately = true
|
||||
|
||||
|
||||
1171
assets/spider2.tscn2375300484.tmp
Normal file
1171
assets/spider2.tscn2375300484.tmp
Normal file
File diff suppressed because one or more lines are too long
1162
assets/spider2.tscn2400692018.tmp
Normal file
1162
assets/spider2.tscn2400692018.tmp
Normal file
File diff suppressed because one or more lines are too long
@@ -19,11 +19,11 @@ func Enter():
|
||||
|
||||
func Physics_Update(delta):
|
||||
update_minimap(0,2.0,ColorSwatch.RED_COLOR)
|
||||
if enemy.is_player_visible():
|
||||
if character.is_player_visible():
|
||||
#reset lost target timer
|
||||
lost_target_timer = time_to_lose_target
|
||||
#get player location
|
||||
enemy.cache_player_pos()
|
||||
character.cache_player_pos()
|
||||
#set player location as target
|
||||
update_player_target()
|
||||
#move and look at location
|
||||
@@ -34,7 +34,7 @@ func Physics_Update(delta):
|
||||
initial_timer -= delta
|
||||
else:
|
||||
#fire if player in view
|
||||
if enemy.ammo > 0:
|
||||
if character.ammo > 0:
|
||||
attack_sequence(delta)
|
||||
else:
|
||||
await get_tree().create_timer(.5).timeout
|
||||
@@ -54,42 +54,42 @@ func attack_sequence(delta):
|
||||
shot_timer -= delta
|
||||
else:
|
||||
shot_timer = randf_range(between_shot_time.x,between_shot_time.y)
|
||||
enemy.turret_material.emission_enabled = true
|
||||
character.turret_material.emission_enabled = true
|
||||
await get_tree().create_timer(.1).timeout
|
||||
attack()
|
||||
|
||||
func update_player_target():
|
||||
move_target = enemy.player_last_seen
|
||||
look_target = enemy.player_last_seen + Vector3(0,.75,0)
|
||||
enemy.nav_agent.set_target_position(move_target)
|
||||
move_target = character.player_last_seen
|
||||
look_target = character.player_last_seen + Vector3(0,.75,0)
|
||||
character.nav_agent.set_target_position(move_target)
|
||||
|
||||
func attack():
|
||||
fire(enemy.barrel_1)
|
||||
enemy.smoke.emitting = true
|
||||
fire(character.barrel_1)
|
||||
character.smoke.emitting = true
|
||||
await get_tree().create_timer(.1).timeout
|
||||
fire(enemy.barrel_2)
|
||||
enemy.smoke_2.emitting = true
|
||||
enemy.turret_material.emission_enabled = false
|
||||
fire(character.barrel_2)
|
||||
character.smoke_2.emitting = true
|
||||
character.turret_material.emission_enabled = false
|
||||
|
||||
func fire(barrel):
|
||||
enemy.ammo -= 1
|
||||
SignalBus.emit_signal("engaging_target",enemy,enemy.player_last_seen)
|
||||
var instance_bullet = enemy.bullet.instantiate()
|
||||
character.ammo -= 1
|
||||
SignalBus.emit_signal("engaging_target",character,character.player_last_seen)
|
||||
var instance_bullet = character.bullet.instantiate()
|
||||
instance_bullet.position = barrel.global_position
|
||||
instance_bullet.transform.basis = barrel.global_transform.basis
|
||||
instance_bullet.bullet_speed = enemy.bullet_speed
|
||||
instance_bullet.bullet_drop = enemy.bullet_drop
|
||||
instance_bullet.random_spread_amt = enemy.random_spread_amt
|
||||
instance_bullet.bullet_damage = enemy.bullet_damage
|
||||
instance_bullet.fired_by = enemy
|
||||
instance_bullet.target_type = enemy.enemy_type
|
||||
instance_bullet.bullet_speed = character.bullet_speed
|
||||
instance_bullet.bullet_drop = character.bullet_drop
|
||||
instance_bullet.random_spread_amt = character.random_spread_amt
|
||||
instance_bullet.bullet_damage = character.bullet_damage
|
||||
instance_bullet.fired_by = character
|
||||
instance_bullet.target_type = character.enemy_type
|
||||
get_tree().get_root().add_child(instance_bullet)
|
||||
enemy.audio_fire.play()
|
||||
character.audio_fire.play()
|
||||
spawn_casing()
|
||||
|
||||
func spawn_casing():
|
||||
var instance_casing = enemy.casing.instantiate()
|
||||
instance_casing.position = enemy.casing_ejector.global_position
|
||||
instance_casing.transform.basis = enemy.casing_ejector.global_transform.basis
|
||||
instance_casing.player_velocity = enemy.velocity * enemy.transform.basis
|
||||
var instance_casing = character.casing.instantiate()
|
||||
instance_casing.position = character.casing_ejector.global_position
|
||||
instance_casing.transform.basis = character.casing_ejector.global_transform.basis
|
||||
instance_casing.player_velocity = character.velocity * character.transform.basis
|
||||
get_tree().get_root().add_child(instance_casing)
|
||||
|
||||
@@ -10,7 +10,6 @@ var scan_direction = scan_cone_angle/2
|
||||
|
||||
func Enter():
|
||||
scan_timer = scan_time
|
||||
get_new_wander_point()
|
||||
clear_points_of_interest()
|
||||
|
||||
func Update(delta):
|
||||
@@ -22,11 +21,8 @@ func Update(delta):
|
||||
change_scan_direction()
|
||||
|
||||
func Physics_Update(delta):
|
||||
#draw target for debug purposes
|
||||
debug_marker(move_target)
|
||||
|
||||
#if navigation is finished get new point, otherwise continue on path
|
||||
if enemy.nav_agent.is_navigation_finished():
|
||||
if character.nav_agent.is_navigation_finished():
|
||||
get_new_wander_point()
|
||||
else:
|
||||
move_to_nav_point(delta)
|
||||
@@ -37,8 +33,8 @@ func Physics_Update(delta):
|
||||
func get_new_wander_point():
|
||||
var x = randf_range(-wander_distance_max,wander_distance_max)
|
||||
var z = randf_range(-wander_distance_max,wander_distance_max)
|
||||
move_target = enemy.global_position + Vector3(x,0,z)
|
||||
enemy.nav_agent.set_target_position(move_target)
|
||||
move_target = character.global_position + Vector3(x,0,z)
|
||||
character.nav_agent.set_target_position(move_target)
|
||||
|
||||
func change_scan_direction():
|
||||
scan_timer = scan_time
|
||||
|
||||
@@ -12,36 +12,36 @@ func Enter():
|
||||
servo_sound.play()
|
||||
|
||||
func Update(delta):
|
||||
if enemy.ammo < enemy.max_ammo:
|
||||
if character.ammo < character.max_ammo:
|
||||
reload()
|
||||
else:
|
||||
finished_reload()
|
||||
|
||||
func Physics_Update(delta):
|
||||
if enemy.is_player_visible():
|
||||
if character.is_player_visible():
|
||||
#get player location
|
||||
enemy.cache_player_pos()
|
||||
character.cache_player_pos()
|
||||
update_reload_look_target()
|
||||
move_to_nav_point(delta)
|
||||
turret_look3D(delta)
|
||||
|
||||
|
||||
func update_reload_look_target():
|
||||
look_target = enemy.global_position + Vector3(0,10,0)
|
||||
look_target = character.global_position + Vector3(0,10,0)
|
||||
|
||||
func update_reload_move_target():
|
||||
var direction = (enemy.player_last_seen - enemy.global_position).normalized()
|
||||
var direction = (character.player_last_seen - character.global_position).normalized()
|
||||
move_target = direction * retreat_distance
|
||||
enemy.nav_agent.set_target_position(move_target)
|
||||
character.nav_agent.set_target_position(move_target)
|
||||
|
||||
func reload():
|
||||
if !reload_sound.is_playing():
|
||||
enemy.ammo += 1
|
||||
character.ammo += 1
|
||||
reload_sound.play()
|
||||
|
||||
func finished_reload():
|
||||
servo_sound.play()
|
||||
if enemy.is_player_visible():
|
||||
if character.is_player_visible():
|
||||
Transitioned.emit(self,"attack")
|
||||
else:
|
||||
Transitioned.emit(self,"search") #fix to search when it works
|
||||
|
||||
@@ -27,11 +27,8 @@ func Update(delta):
|
||||
Transitioned.emit(self,"idle")
|
||||
|
||||
func Physics_Update(delta):
|
||||
#draw target for debug purposes
|
||||
debug_marker(move_target)
|
||||
|
||||
#if navigation is finished get new point, otherwise continue on path
|
||||
if enemy.nav_agent.is_navigation_finished():
|
||||
if character.nav_agent.is_navigation_finished():
|
||||
if has_points_to_investigate():
|
||||
get_new_point_of_interest()
|
||||
else:
|
||||
|
||||
@@ -1,127 +1,44 @@
|
||||
extends State
|
||||
extends CharacterState
|
||||
class_name EnemyState
|
||||
|
||||
@export var enemy : CharacterBody3D
|
||||
@export var move_speed : float = 3
|
||||
@export var body_turn_speed : float = 3
|
||||
@export var turret_speed : float = 6.0
|
||||
@export var can_see : bool = true # indicates whether the enemy is able to see things in the state
|
||||
@export var poi_investigate : bool = false
|
||||
@export var poi_change_to_search : bool = false
|
||||
@export var poi_update_waypoint_immediately : bool = false
|
||||
|
||||
var move_target
|
||||
var look_target
|
||||
|
||||
func enemy_has_target():
|
||||
if enemy.player_last_seen != null:
|
||||
if character.player_last_seen != null:
|
||||
return true
|
||||
if enemy.point_of_interest != null:
|
||||
if character.point_of_interest != null:
|
||||
return true
|
||||
return false
|
||||
|
||||
func update_move_target():
|
||||
if enemy.player_last_seen != null:
|
||||
return enemy.player_last_seen
|
||||
elif enemy.point_of_interest != null:
|
||||
return enemy.point_of_interest["point"]
|
||||
else:
|
||||
return enemy.global_position
|
||||
|
||||
func attack_on_sight():
|
||||
if can_see:
|
||||
if enemy.is_player_in_area() and enemy.is_player_visible():
|
||||
enemy.cache_player_pos()
|
||||
if character.is_player_in_area() and character.is_player_visible():
|
||||
character.cache_player_pos()
|
||||
Transitioned.emit(self,"attack")
|
||||
if enemy.turret_look.is_colliding():
|
||||
if enemy.turret_look.get_collider() is Player:
|
||||
enemy.cache_player_pos()
|
||||
if character.turret_look.is_colliding():
|
||||
if character.turret_look.get_collider() is Player:
|
||||
character.cache_player_pos()
|
||||
Transitioned.emit(self,"attack")
|
||||
|
||||
func search_on_lost_target():
|
||||
if !enemy.is_player_visible():
|
||||
Transitioned.emit(self,"attack")
|
||||
|
||||
func move_target_adj(position):
|
||||
return Vector3(position.x,enemy.global_position.y,position.z)
|
||||
|
||||
func search_for_suspicious_sounds():
|
||||
if enemy.point_of_interest != null:
|
||||
enemy.player_last_seen = null
|
||||
Transitioned.emit(self,"search")
|
||||
|
||||
func rotate_to_face2D(object,target,target_offset_angle,delta,turn_speed):
|
||||
#to allow both nodes and positions to be passed to this function, test the target and use Vector3 coords
|
||||
var target_transformed
|
||||
if target == null:
|
||||
target_transformed = object.global_position
|
||||
elif target is Vector3:
|
||||
target_transformed = target
|
||||
elif target is Node3D:
|
||||
target_transformed = target.global_position
|
||||
|
||||
var pos2d = Vector2(object.global_position.x,object.global_position.z)
|
||||
var target_pos2d = Vector2(target_transformed.x,target_transformed.z)
|
||||
var direction = (pos2d - target_pos2d)
|
||||
return lerp_angle(object.global_rotation.y,atan2(direction.x,direction.y) + deg_to_rad(target_offset_angle),delta * turn_speed)
|
||||
|
||||
func rotate_to_face3D(object : Node3D,target,target_offset_angle : Vector3,delta : float,turn_speed : float):
|
||||
if target == null:
|
||||
return
|
||||
|
||||
var target_positon
|
||||
|
||||
if target is Vector3:
|
||||
target_positon = target
|
||||
else:
|
||||
target_positon = target.global_position
|
||||
|
||||
var desired_rotation = object.global_transform.looking_at(target_positon,Vector3.UP).basis.get_euler()
|
||||
var current_rotation = object.global_rotation
|
||||
|
||||
#Interpolate each axis
|
||||
current_rotation.x = lerp_angle(current_rotation.x,desired_rotation.x + target_offset_angle.x,delta * turn_speed)
|
||||
current_rotation.y = lerp_angle(current_rotation.y,desired_rotation.y + target_offset_angle.y,delta * turn_speed)
|
||||
current_rotation.z = lerp_angle(current_rotation.z,desired_rotation.z + target_offset_angle.z,delta * turn_speed)
|
||||
|
||||
#clamp pitch
|
||||
var max_downward_pitch = deg_to_rad(85)
|
||||
var min_upward_pitch = deg_to_rad(-45)
|
||||
current_rotation.x = clamp(current_rotation.x,min_upward_pitch, max_downward_pitch)
|
||||
|
||||
object.global_rotation = current_rotation
|
||||
|
||||
func move_to_nav_point(delta):
|
||||
var destination = enemy.nav_agent.get_next_path_position()
|
||||
var local_destination = destination - enemy.global_position
|
||||
var new_velocity = local_destination.normalized() * move_speed
|
||||
|
||||
enemy.nav_agent.set_velocity(new_velocity)
|
||||
enemy.global_rotation.y = rotate_to_face2D(enemy,destination,0,delta,body_turn_speed)
|
||||
|
||||
func velocity_computed(safe_velocity):
|
||||
enemy.velocity = enemy.velocity.move_toward(safe_velocity,.25)
|
||||
|
||||
|
||||
func turret_look2D(delta):
|
||||
enemy.turret_look.global_rotation.y = rotate_to_face2D(enemy.turret_look,look_target,0,delta,turret_speed)
|
||||
character.turret_look.global_rotation.y = rotate_to_face2D(character.turret_look,look_target,0,delta,turret_speed)
|
||||
|
||||
func turret_scan(target_offset : Vector3,delta):
|
||||
rotate_to_face3D(enemy.turret_look,look_target,target_offset,delta,turret_speed)
|
||||
rotate_to_face3D(character.turret_look,look_target,target_offset,delta,turret_speed)
|
||||
|
||||
func turret_look3D(delta):
|
||||
rotate_to_face3D(enemy.turret_look,look_target,Vector3.ZERO,delta,turret_speed)
|
||||
rotate_to_face3D(character.turret_look,look_target,Vector3.ZERO,delta,turret_speed)
|
||||
|
||||
func turret_scan_look(target,scan_direction,delta):
|
||||
enemy.turret_look.global_rotation.y = rotate_to_face2D(enemy.turret_look,target,scan_direction,delta,turret_speed)
|
||||
character.turret_look.global_rotation.y = rotate_to_face2D(character.turret_look,target,scan_direction,delta,turret_speed)
|
||||
|
||||
func investigate_points_of_interest(point,loudness,max_distance):
|
||||
if poi_investigate:
|
||||
var distance_to_point = enemy.global_position.distance_to(point)
|
||||
var distance_to_point = character.global_position.distance_to(point)
|
||||
if distance_to_point <= max_distance:
|
||||
var perceived_loudness = 1/distance_to_point * loudness
|
||||
var add_point = {"point" : point, "loudness" : perceived_loudness}
|
||||
enemy.points_of_interest.append(add_point)
|
||||
character.points_of_interest.append(add_point)
|
||||
|
||||
if poi_change_to_search:
|
||||
Transitioned.emit(self,"search")
|
||||
@@ -130,32 +47,22 @@ func investigate_points_of_interest(point,loudness,max_distance):
|
||||
get_new_point_of_interest()
|
||||
|
||||
func has_points_to_investigate():
|
||||
if enemy.player_last_seen != null:
|
||||
if character.player_last_seen != null:
|
||||
return true
|
||||
elif enemy.points_of_interest.size() > 0:
|
||||
elif character.points_of_interest.size() > 0:
|
||||
return true
|
||||
else:
|
||||
return false
|
||||
|
||||
func get_new_point_of_interest():
|
||||
if enemy.player_last_seen != null:
|
||||
move_target = enemy.player_last_seen
|
||||
enemy.player_last_seen = null
|
||||
enemy.nav_agent.set_target_position(move_target)
|
||||
elif enemy.points_of_interest.size() > 0:
|
||||
var point_of_interest = enemy.points_of_interest.pop_back()
|
||||
if character.player_last_seen != null:
|
||||
move_target = character.player_last_seen
|
||||
character.player_last_seen = null
|
||||
character.nav_agent.set_target_position(move_target)
|
||||
elif character.points_of_interest.size() > 0:
|
||||
var point_of_interest = character.points_of_interest.pop_back()
|
||||
move_target = point_of_interest["point"]
|
||||
enemy.nav_agent.set_target_position(move_target)
|
||||
character.nav_agent.set_target_position(move_target)
|
||||
|
||||
func clear_points_of_interest():
|
||||
enemy.points_of_interest = []
|
||||
|
||||
func debug_marker(target_pos):
|
||||
if enemy.debug_tools:
|
||||
enemy.debug_tracker.visible = true
|
||||
enemy.debug_tracker.global_position = target_pos
|
||||
else:
|
||||
enemy.debug_tracker.visible = false
|
||||
|
||||
func update_minimap(priority,duration,color):
|
||||
SignalBus.emit_signal("ui_minimap_point",enemy,enemy.global_position,1,duration,color)
|
||||
character.points_of_interest = []
|
||||
|
||||
@@ -8,11 +8,11 @@ func Enter():
|
||||
|
||||
func die():
|
||||
drop_loot()
|
||||
enemy.visible = false
|
||||
character.visible = false
|
||||
#remove from parent array
|
||||
var particlespawn = enemy.die_particles.instantiate()
|
||||
particlespawn.position = enemy.global_position
|
||||
particlespawn.transform.basis = enemy.global_transform.basis
|
||||
var particlespawn = character.die_particles.instantiate()
|
||||
particlespawn.position = character.global_position
|
||||
particlespawn.transform.basis = character.global_transform.basis
|
||||
for particle in particlespawn.get_children():
|
||||
if particle is RigidBody3D:
|
||||
particle.linear_velocity += random_av_lv()["linear_velocity"]
|
||||
@@ -22,15 +22,15 @@ func die():
|
||||
if GameGlobals.last_hit_path == str(get_path()):
|
||||
GameGlobals.last_hit_path = null
|
||||
|
||||
SignalBus.emit_signal("enemy_killed",enemy)
|
||||
SignalBus.emit_signal("enemy_killed",character)
|
||||
|
||||
func drop_loot():
|
||||
var number_of_drops = enemy.loot_amount
|
||||
var number_of_drops = character.loot_amount
|
||||
#pickup drop
|
||||
while number_of_drops > 0:
|
||||
|
||||
var pickup_spawn = enemy.level_control.ITEM_PICKUP.instantiate()
|
||||
var item_stats = enemy.level_control.pickup_spawn(false)
|
||||
var pickup_spawn = character.level_control.ITEM_PICKUP.instantiate()
|
||||
var item_stats = character.level_control.pickup_spawn(false)
|
||||
|
||||
##SET VARIABLES
|
||||
pickup_spawn.pickup_type = item_stats["pickup_type"]
|
||||
@@ -39,16 +39,16 @@ func drop_loot():
|
||||
|
||||
|
||||
# Random Item Drop
|
||||
pickup_spawn.position = enemy.global_position + Vector3(0,2,0) #added height to spawn location since origin is on the ground
|
||||
pickup_spawn.transform.basis = enemy.global_transform.basis
|
||||
pickup_spawn.linear_velocity += enemy.global_transform.basis * random_av_lv()["linear_velocity"]
|
||||
pickup_spawn.angular_velocity += enemy.global_transform.basis * random_av_lv()["angular_velocity"]
|
||||
pickup_spawn.position = character.global_position + Vector3(0,2,0) #added height to spawn location since origin is on the ground
|
||||
pickup_spawn.transform.basis = character.global_transform.basis
|
||||
pickup_spawn.linear_velocity += character.global_transform.basis * random_av_lv()["linear_velocity"]
|
||||
pickup_spawn.angular_velocity += character.global_transform.basis * random_av_lv()["angular_velocity"]
|
||||
await get_tree().create_timer(.05).timeout
|
||||
get_tree().get_root().add_child(pickup_spawn)
|
||||
number_of_drops -= 1
|
||||
|
||||
await number_of_drops <= 0
|
||||
enemy.queue_free()
|
||||
character.queue_free()
|
||||
|
||||
func random_av_lv():
|
||||
var lv_x = randf_range(-MAX_LV,MAX_LV)
|
||||
|
||||
Reference in New Issue
Block a user