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
133
134
135
136
137
|
class_name Mob
extends CharacterBody2D
static var selected_unit: Mob
var is_selected = false :
set(value):
if value:
Mob.selected_unit = self
else:
if Mob.selected_unit == self:
Mob.selected_unit = null
is_selected = value
queue_redraw()
var is_hovered = false :
set(value):
is_hovered = value
queue_redraw()
var target: Vector2
var immediate_target: Vector2
var path: PackedVector2Array
var current_path_idx = 0
@export var speed: float = 100
@export var hp = 50
# Called when the node enters the scene tree for the first time.
func _ready():
if not target:
print("No target!")
set_process(false)
queue_free()
path = Game.path_grid.get_point_path(Game.map.local_to_map(global_position), Game.map.local_to_map(target))
Game.path_grid_changed.connect(func():
path = Game.path_grid.get_point_path(Game.map.local_to_map(global_position), Game.map.local_to_map(target))
current_path_idx = min(1, path.size() - 1)
)
%HP.max_value = hp
set_hp(hp)
func _physics_process(delta):
# TODO: if path is empty
# TODO: change state to "AttackClosestTowerState"
# TODO: get all towers, sort by distance to mob
# TODO: walk to and attack/destroy closest tower
# TODO: repeat, unless =>
# TODO: check path every frame if still closed off (empty)
# TODO: if path not empty anymore change state to walk next path
if not path.is_empty():
if (global_position - path[current_path_idx]).is_zero_approx():
current_path_idx += 1
if current_path_idx >= path.size():
path = Game.path_grid.get_point_path(Game.map.local_to_map(global_position), Game.map.local_to_map(target))
current_path_idx = 0
#var displacement := target - global_transform.origin
immediate_target = path[current_path_idx]
var displacement := (path[current_path_idx]) - global_position
var direction := displacement.normalized()
var distance := displacement.length()
var max_speed: float = (distance / delta)
velocity = direction * minf(speed, max_speed)
move_and_slide()
func _draw():
if is_selected:
draw_circle(
Vector2.ZERO,
8,
Color(1, 1, 1, 0.75),
false,
1.0
)
modulate = Color(1.5, 1.5, 1.5)
elif is_hovered:
draw_circle(
Vector2.ZERO,
8,
Color(1, 1, 1, 0.5),
false,
1.0
)
modulate = Color(1.25, 1.25, 1.25)
else:
modulate = Color(1, 1, 1)
func _on_navigation_base_area_entered(area: Area2D):
if area.is_in_group("goal"):
queue_free()
if area.is_in_group("path"):
var path_node = area.get_parent()
target = path_node.next_node.global_position
func set_hp(value):
hp = value
%HP.value = value
if is_selected:
$Label.text = str(hp)
else:
$Label.text = ""
if hp <= 0:
queue_free()
func _on_input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
if Game.mode == Game.Mode.DEFAULT:
if event.is_action_pressed("select"):
is_selected = true
$Label.text = str(hp)
func _on_mouse_entered() -> void:
is_hovered = true
func _on_mouse_exited() -> void:
is_hovered = false
func _on_tree_exiting() -> void:
is_selected = false
|