Now About Social Code
summaryrefslogtreecommitdiff
path: root/scripts/enemy.gd
blob: 6be60c7208c45a656f31265b75bb84cd03b7dd6a (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
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
	
	# We only want to navigate on XZ plane
	new_velocity.y = 0
	
	velocity = new_velocity
	
	if not is_on_floor() and gravity_enabled:
		velocity.y -= gravity * delta
	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()