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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
extends Node
var _resources : Node
var _path
var _enemy_blue
var _dissolve_mat : ShaderMaterial
var _enemy_mat : Material
var control
var _fx_holder
var _fx_enemy_damage
var serial_enemy = 0
var enemies = {}
var load_shapes : Node
var colors = [
Color.red,
Color.purple,
Color.blue,
Color.mediumseagreen,
Color.green,
Color.greenyellow,
Color.yellow,
Color.orange,
Color.violet,
Color.indigo,
]
func _ready():
var root = get_tree().root.get_node("world")
_fx_holder = root.get_node("fx")
control = root.get_node("player").get_node("control")
_path = root.get_node("path")
_resources = root.get_node("player").get_node("resources")
_dissolve_mat = load("res://shaders/dissolve_mat.tres")
_enemy_mat = load("res://assets/models/shapes/Enemy.material")
_enemy_blue = load("res://scenes/enemy.tscn")
_fx_enemy_damage = load("res://scenes/fx/enemy_damage.tscn")
var saveload = root.get_node("saveload")
load_shapes = saveload.get_node("load_shapes")
if !load_shapes.loaded: yield(load_shapes, "done_loading")
func spawn(name, node_cur=0, rel_pos=0, hp=0):
print("spawned " + name)
var instance = _enemy_blue.instance()
add_child(instance)
instance.transform.origin = _path.nodes[0].transform.origin;
instance.name = str(serial_enemy)
var info = load_shapes.info[name]
if hp == 0: hp = info.lives
var instance_model = load_shapes.models[info.model_name].instance()
instance.add_child(instance_model)
instance_model.get_child(0).set_surface_material(0, _enemy_mat.duplicate())
var axis : Vector3 = Quat(Vector3(0, randf()*TAU, 0)) * Vector3.RIGHT
enemies[serial_enemy] = {
"name": name,
"hp": hp,
"slow_effect": 0,
"slow_time": 0,
"cur": node_cur,
"rel": rel_pos,
"axis": [axis.x, axis.y, axis.z],
"basecolor": Color(info.color[0], info.color[1], info.color[2], info.color[3]),
"color": Color(info.color[0], info.color[1], info.color[2], info.color[3])
}
var next_color = Color.black;
if info.has("spawn_on_death"):
next_color = load_shapes.info[info.spawn_on_death].color
enemies[serial_enemy].color = info.color.linear_interpolate(
next_color, enemies[serial_enemy].hp/info.lives)
instance.transform.origin = abs_pos(serial_enemy)
serial_enemy += 1
func node_from_id (id):
return get_node(str(id))
func abs_pos (id):
var enemy = enemies[id]
var from = _path.nodes[enemy.cur].transform.origin
var to = _path.nodes[enemy.cur+1].transform.origin
return lerp(from, to, enemy.rel)
func _physics_process(delta):
var delist = []
for child in get_children():
var id = str(child.name).to_int()
var enemy = enemies[id]
var info = load_shapes.info[enemy.name]
if enemy.hp <= 0:
delist.append(id)
enemy.rel = 0
for n in range(info.get("spawn_num", 0)):
# todo rel +- epslion
spawn(info.spawn_on_death, enemy.cur, enemy.rel - n/10.0)
continue
enemy.slow_time -= delta
if enemy.slow_time < 0: enemy.slow_effect = 0
var speed = info.speed * (1-enemy.slow_effect)
enemy.rel += speed * delta
while enemy.rel > 1:
enemy.rel -= 1
enemy.cur += 1
var destination = enemy.cur+1
if destination >= _path.nodes.size():
delist.append(id)
enemy.rel = 0
_resources.lives -= load_shapes.get_damage(enemy.hp, enemy.name)
continue
child.transform.origin = abs_pos(id)
var axis = Vector3(enemy.axis[0], enemy.axis[1], enemy.axis[2])
child.transform.basis = child.transform.basis.rotated(axis, delta)
var mesh : MeshInstance = child.get_child(1).get_child(0)
mesh.get_active_material(0).albedo_color = enemy.color
for id in delist:
get_node(str(id)).queue_free()
enemies.erase(id)
if enemies.size() == 0:
control.end_wave_event()
func damage(name, dam, slow_effect=0, slow_time=0):
var id = int(name)
var enemy = enemies[id]
var info = load_shapes.info[enemy.name]
if enemy.hp > 0:
if dam > 0:
enemy.hp -= dam
_resources.add({ info.resource: dam })
fx_damage(name)
var next_color = Color.black;
if info.has("spawn_on_death"):
next_color = load_shapes.info[info.spawn_on_death].color
enemy.color = info.color.linear_interpolate(next_color, enemy.hp/info.lives)
if slow_effect > 0:
enemy.slow_effect = max(slow_effect, enemy.slow_effect)
enemy.slow_time = slow_time
func fx_damage(name):
var id = int(name)
var enemy = enemies[id]
var info = load_shapes.info[enemy.name]
var instance = _fx_enemy_damage.instance()
_fx_holder.add_child(instance)
var node = node_from_id(id)
instance.transform = node.transform;
instance.refresh_basis()
var instance_model = load_shapes.models[info.model_name].instance()
instance.add_child(instance_model)
instance.refresh_shader(_dissolve_mat.duplicate(), enemy.color)
|