Now About Social Code
summaryrefslogtreecommitdiff
path: root/scripts/enemy.gd
blob: 716493c534cddca13b583df0a3e5895cb7a5b290 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
extends CharacterBody3D

## Speed of enemy
@export var speed: float = 2.0
## Target for enemy to follow
@export var target: Node3D

## Whether to use gravity on enemy
@export var gravity_enabled: bool = true

## Use nav mesh or dumb path finding
@export var use_nav_mesh: bool = true

@onready var nav_agent: NavigationAgent3D = $NavigationAgent3D

var has_astar: bool = false
var astar: AStar3D
var tar_vec: Vector3
var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity")

var original_color: Color

var mesh_ready = false

func _ready() -> void:
	if gravity_enabled:
		motion_mode = MotionMode.MOTION_MODE_GROUNDED
		
	NavigationServer3D.connect("map_changed", map_changed)
	
func map_changed(_rid):
	print("Map changed")
	mesh_ready = true

func chase_target(delta: float) -> void:
	var target_pos = target.position
	var direction = (target_pos - position).normalized()
	
	if direction:
		velocity.x = direction.x * speed
		velocity.z = direction.z * speed
	else:
		velocity.x = move_toward(velocity.x, 0, speed)
		velocity.z = move_toward(velocity.z, 0, speed)
	
	if not is_on_floor() and gravity_enabled:
		velocity.y -= gravity * delta
		
	move_and_slide()
	
func update_target_location(target_location: Vector3):
	nav_agent.target_position = target_location
	
func chase_nav_mesh(delta: float):
	if not mesh_ready:
		return
		
	if target != null:
		update_target_location(target.global_position)
	
	var current_location = global_transform.origin
	var next_location = nav_agent.get_next_path_position()
	var new_velocity = (next_location - current_location).normalized() * speed
	
	#print("Target is ", next_location)
	
	# We only want to navigate on XZ plane
	new_velocity.y = 0
	
	velocity = velocity.move_toward(new_velocity, .25)
	
	if not is_on_floor() and gravity_enabled:
		velocity.y -= gravity * delta
	else:
		velocity.y = 0
	
	move_and_slide()

func _physics_process(delta: float) -> void:
	if target == null:
		return
		
	if Input.is_action_pressed("ui_right"):
		return
		
	if use_nav_mesh:
		chase_nav_mesh(delta)
		return
		
	if not has_astar:
		# Just try to chase player directly
		chase_target(delta)
		return
		
	var target_pos = target.position
	var closest_me = astar.get_closest_point(position)
	var closest_target = astar.get_closest_point(target_pos)
	
	var direction: Vector3
	if closest_me == closest_target:
		direction = (target_pos - position).normalized()
	else:
		var target_path = astar.get_point_path(closest_me, closest_target)
		if len(target_path) >= 2:
			direction = (target_path[1] - position).normalized()

	if direction:
		#velocity.x = move_toward(velocity.x, direction.x * speed, 10.0 * delta)
		#velocity.z = move_toward(velocity.z, direction.z * speed, 10.0 * delta)
		velocity.x = direction.x * speed
		velocity.z = direction.z * speed
	else:
		velocity.x = move_toward(velocity.x, 0, speed)
		velocity.z = move_toward(velocity.z, 0, speed)

	move_and_slide()

func on_hit(_hit_position: Vector3) -> void:
	if $HitTimer.is_stopped():
		var material: StandardMaterial3D = $MeshInstance3D.get_active_material(0)
		original_color = material.albedo_color
		material.albedo_color = Color(1.0, 0.0, 0.0, 1.0)
		$HitTimer.start()

func _on_level_generator_astar_created(in_astar: AStar3D) -> void:
	astar = in_astar
	has_astar = true

func _on_hit_timer_timeout() -> void:
	var material: StandardMaterial3D = $MeshInstance3D.get_active_material(0)
	material.albedo_color = original_color
	$HitTimer.stop()