aboutsummaryrefslogtreecommitdiff
path: root/scripts/enemies.gd
blob: 61529ffe2d4b92c69ee2454e2d1324cf44c0734d (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
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)