diff options
author | jacopograndi <jacopo.grandi@outlook.it> | 2022-01-17 19:41:46 +0100 |
---|---|---|
committer | jacopograndi <jacopo.grandi@outlook.it> | 2022-01-17 19:41:46 +0100 |
commit | f75ee64e21f67b4f27404147aedaa63750058d5a (patch) | |
tree | 8e35f5b0ca986169e46ef1f90c3fdd951a9af113 | |
parent | a7bda4264b45c0c64fd81ac91b4f1fbbc539e314 (diff) |
wave
-rw-r--r-- | assets/blender/shapes.blend | bin | 1160400 -> 1160400 bytes | |||
-rw-r--r-- | assets/blender/shapes.blend1 | bin | 1159840 -> 1160400 bytes | |||
-rw-r--r-- | scenes/gui.tscn | 36 | ||||
-rw-r--r-- | scenes/wave/timer_batch.tscn | 9 | ||||
-rw-r--r-- | scripts/control.gd | 13 | ||||
-rw-r--r-- | scripts/enemies.gd | 50 | ||||
-rw-r--r-- | scripts/gui.gd | 14 | ||||
-rw-r--r-- | scripts/gui_top_bar.gd | 7 | ||||
-rw-r--r-- | scripts/load_shapes.gd | 20 | ||||
-rw-r--r-- | scripts/movement.gd | 13 | ||||
-rw-r--r-- | scripts/resources.gd | 2 | ||||
-rw-r--r-- | scripts/spawner.gd | 24 | ||||
-rw-r--r-- | scripts/wave.gd | 94 | ||||
-rw-r--r-- | world.tscn | 6 |
14 files changed, 246 insertions, 42 deletions
diff --git a/assets/blender/shapes.blend b/assets/blender/shapes.blend Binary files differindex b2b1dc1..22072fc 100644 --- a/assets/blender/shapes.blend +++ b/assets/blender/shapes.blend diff --git a/assets/blender/shapes.blend1 b/assets/blender/shapes.blend1 Binary files differindex d1c596d..b2b1dc1 100644 --- a/assets/blender/shapes.blend1 +++ b/assets/blender/shapes.blend1 diff --git a/scenes/gui.tscn b/scenes/gui.tscn index 38958a2..123d0ae 100644 --- a/scenes/gui.tscn +++ b/scenes/gui.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=2] +[gd_scene load_steps=11 format=2] [ext_resource path="res://scripts/gui.gd" type="Script" id=1] [ext_resource path="res://themes/DarkTheme/Dark.theme" type="Theme" id=2] @@ -22,6 +22,15 @@ shadow_offset = Vector2( 1, 1 ) bg_color = Color( 0, 0, 0, 0.482353 ) border_width_top = 1 +[sub_resource type="StyleBoxFlat" id=6] +bg_color = Color( 1, 0, 0, 0 ) +draw_center = false +border_width_left = 5 +border_width_top = 5 +border_width_right = 5 +border_width_bottom = 5 +border_color = Color( 0.364706, 0, 0, 1 ) + [node name="gui" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 @@ -149,6 +158,18 @@ __meta__ = { "_edit_use_anchors_": false } +[node name="lives" type="Label" parent="top_bar/panel/resources/HBoxContainer"] +margin_left = 208.0 +margin_top = 7.0 +margin_right = 277.4 +margin_bottom = 31.4 +custom_colors/font_color = Color( 1, 1, 1, 1 ) +text = "100 lives" +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + [node name="editor_button" type="Button" parent="top_bar/panel"] anchor_left = 1.0 anchor_right = 1.0 @@ -171,7 +192,7 @@ margin_top = 5.0 margin_right = -10.0 margin_bottom = -5.0 grow_horizontal = 0 -text = "Wave 3/10" +text = "wave 3" align = 1 valign = 1 __meta__ = { @@ -308,6 +329,17 @@ __meta__ = { "_edit_use_anchors_": false } +[node name="wave_ongoing_indicator" type="Panel" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_top = 41.0 +margin_bottom = -121.0 +mouse_filter = 2 +custom_styles/panel = SubResource( 6 ) +__meta__ = { +"_edit_use_anchors_": false +} + [connection signal="button_down" from="top_bar/panel/editor_button" to="top_bar" method="_on_editor_button_down"] [connection signal="pressed" from="top_bar/panel/wave_button" to="top_bar" method="_on_wave_button_pressed"] [connection signal="button_up" from="bottom_bar/editor_bar/hbox/turrets" to="bottom_bar" method="_on_turrets_button_up"] diff --git a/scenes/wave/timer_batch.tscn b/scenes/wave/timer_batch.tscn new file mode 100644 index 0000000..22b201b --- /dev/null +++ b/scenes/wave/timer_batch.tscn @@ -0,0 +1,9 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://scripts/spawner.gd" type="Script" id=1] + +[node name="timer_batch" type="Timer"] +one_shot = true +script = ExtResource( 1 ) + +[connection signal="timeout" from="." to="." method="_on_timer_batch_timeout"] diff --git a/scripts/control.gd b/scripts/control.gd index 8ef1ff0..a2d7d2b 100644 --- a/scripts/control.gd +++ b/scripts/control.gd @@ -7,11 +7,13 @@ var selected = "" var editing_turret = "" var gui : Node +var wave : Node var player : Node var placer : Node var resources : Node var pointer : Node var turret_holder : Node +var enemies_holder : Node var load_turrets : Node var path : Node var world : VoxelMesh @@ -19,6 +21,7 @@ var world : VoxelMesh func fetch (): if load_turrets != null: return var root = get_tree().root.get_node("world") + wave = root.get_node("wave") player = root.get_node("player") resources = player.get_node("resources") placer = player.get_node("placer") @@ -27,6 +30,7 @@ func fetch (): world = root.get_node("world") path = root.get_node("path") turret_holder = root.get_node("turrets") + enemies_holder = root.get_node("enemies") var saveload = root.get_node("saveload") load_turrets = saveload.get_node("load_turrets") if !load_turrets.loaded: yield(load_turrets, "done_loading") @@ -86,7 +90,7 @@ func sell (turr_name): turr.transform.origin, turr.transform.basis.get_rotation_quat()) func _refresh (): - gui.refresh(ineditor) + gui.refresh() pointer.refresh(state, statetype, selected) func to_pick (): @@ -203,10 +207,11 @@ func do (action, par = {}): func gui_editor_toggle_event (): ineditor = !ineditor - gui.refresh(ineditor) + gui.refresh() path.refresh_path(ineditor) func gui_start_wave_event (): + if wave.ongoing: return path.refresh_path(ineditor) - #_enemies.spawn() - gui.refresh(ineditor) + wave.start() + gui.refresh() diff --git a/scripts/enemies.gd b/scripts/enemies.gd index 62c64ea..4a58198 100644 --- a/scripts/enemies.gd +++ b/scripts/enemies.gd @@ -7,6 +7,7 @@ var _enemy_blue var _dissolve_mat : ShaderMaterial var _enemy_mat : Material +var wave var _fx_holder var _fx_enemy_damage @@ -32,6 +33,7 @@ var colors = [ func _ready(): var root = get_tree().root.get_node("world") _fx_holder = root.get_node("fx") + wave = root.get_node("wave") _path = root.get_node("path") _resources = root.get_node("player").get_node("resources") _dissolve_mat = load("res://shaders/dissolve_mat.tres") @@ -43,18 +45,25 @@ func _ready(): load_shapes = saveload.get_node("load_shapes") if !load_shapes.loaded: yield(load_shapes, "done_loading") -func spawn(): +func spawn(name, node_cur=0, rel_pos=0): var instance = _enemy_blue.instance() add_child(instance) instance.transform.origin = _path.nodes[0].transform.origin; instance.name = str(serial_enemy) - var instance_model = load_shapes.models[load_shapes.models.keys()[randi() % load_shapes.models.size()]].instance() + var info = load_shapes.info[name] + + 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] = { - "cur": 0, "hp": 10, "rel": 0, "ops": instance_model.name, + "name": name, + "hp": info.lives, + "slowed_effect": 0, + "slowed_time": 0, + "cur": 0, + "rel": 0, "axis": [axis.x, axis.y, axis.z] } serial_enemy += 1 @@ -67,20 +76,17 @@ func _physics_process(delta): 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: - if enemy.ops == "T": - delist.append(id) - enemy.rel = 0 - continue - else: - child.get_node(enemy.ops).queue_free() - enemy.ops = enemy.ops.substr(1, enemy.ops.length()-1) - enemy.hp = 10 - var instance_model = load_shapes.models[enemy.ops].instance() - child.add_child(instance_model) + delist.append(id) + enemy.rel = 0 + for n in info.get("spawn_num", 0): + # todo rel +- epslion + spawn(enemy.spawn_on_death, enemy.cur, enemy.rel - n/10) + continue - var speed = 1 + var speed = info.speed enemy.rel += speed * delta while enemy.rel > 1: enemy.rel -= 1 @@ -90,6 +96,7 @@ func _physics_process(delta): if destination >= _path.nodes.size(): delist.append(id) enemy.rel = 0 + _resources.lives -= load_shapes.get_damage(enemy.hp, enemy.name) continue var from = _path.nodes[enemy.cur].transform.origin @@ -99,26 +106,31 @@ func _physics_process(delta): 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_node(enemy.ops).get_child(0) - mesh.get_active_material(0).albedo_color = colors[enemy.hp-1] + var mesh : MeshInstance = child.get_child(1).get_child(0) + mesh.get_active_material(0).albedo_color = colors[0] for id in delist: get_node(str(id)).queue_free() enemies.erase(id) + + if enemies.size() == 0: + wave.end() func damage(name, amt): var id = int(name) var enemy = enemies[id] + var info = load_shapes.info[enemy.name] if enemy.hp > 0: enemy.hp -= amt - _resources.add({ enemy.ops[0]: amt }) + _resources.add({ info.resource: amt }) fx_damage(name) 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) @@ -127,7 +139,7 @@ func fx_damage(name): instance.transform = node.transform; instance.refresh_basis() - var instance_model = load_shapes.models[enemy["ops"]].instance() + var instance_model = load_shapes.models[info.model_name].instance() instance.add_child(instance_model) - instance.refresh_shader(_dissolve_mat.duplicate(), colors[enemy.hp-1]) + instance.refresh_shader(_dissolve_mat.duplicate(), colors[0]) diff --git a/scripts/gui.gd b/scripts/gui.gd index 71eaf76..3ad47aa 100644 --- a/scripts/gui.gd +++ b/scripts/gui.gd @@ -2,22 +2,30 @@ extends Control var player : Node var control : Node +var wave : Node var bottom_bar : Control var top_bar : Control +var _wave_ongoing : Panel func _fetch (): var root = get_tree().root.get_node("world") player = root.get_node("player") control = player.get_node("control") + wave = root.get_node("wave") if bottom_bar == null: bottom_bar = get_node("bottom_bar") if top_bar == null: top_bar = get_node("top_bar") + if _wave_ongoing == null: _wave_ongoing = $wave_ongoing_indicator func _ready(): _fetch() -func refresh (in_editor : bool): +func refresh (): _fetch() - bottom_bar.refresh(in_editor) - top_bar.refresh(in_editor) + + bottom_bar.refresh(control.ineditor) + top_bar.refresh(control.ineditor) + + if wave.ongoing: _wave_ongoing.visible = true + else: _wave_ongoing.visible = false diff --git a/scripts/gui_top_bar.gd b/scripts/gui_top_bar.gd index 6c086ce..63ab759 100644 --- a/scripts/gui_top_bar.gd +++ b/scripts/gui_top_bar.gd @@ -2,17 +2,21 @@ extends Control var _editor_button : Button var _hbox : HBoxContainer +var _wave_label : Label var _resources : Node +var _wave : Node var _gui : Control func refresh (in_editor : bool): var root = get_tree().root.get_node("world") _resources = root.get_node("player").get_node("resources") + _wave = root.get_node("wave") if _gui == null: _gui = get_parent() if _hbox == null: _hbox = $panel/resources/HBoxContainer if _editor_button == null: _editor_button = $panel/editor_button + if _wave_label == null: _wave_label = $panel/wave_label if in_editor: _editor_button.text = "Editor" else: _editor_button.text = "Playmode" @@ -21,6 +25,9 @@ func _process (_delta): for r in _resources.get_names(): _hbox.get_node(r).text = str(_resources[r]) + r + _hbox.get_node("lives").text = str(_resources["lives"]) + " lives" + _wave_label.text = "wave " + str(_wave.wave_num+1) + func _on_editor_button_down(): _gui.control.gui_editor_toggle_event() diff --git a/scripts/load_shapes.gd b/scripts/load_shapes.gd index 32e9104..9ac9f3c 100644 --- a/scripts/load_shapes.gd +++ b/scripts/load_shapes.gd @@ -13,6 +13,7 @@ func _ready(): get_saveload() load_models() load_info() + calc_cost() emit_signal("done_loading") loaded = true @@ -41,3 +42,22 @@ func load_info(): if parsed != null: for tin in parsed: info[tin.name] = tin + + +func calc_cost (): + for i in info: info[i].cost = get_lives(i) + +func get_lives (name): + var i = info[name] + var hp = i.lives + for n in i.get("spawn_num", 0): + hp += get_lives(i.spawn_on_death) + return hp + +func get_damage (hp, name): + var i = info[name] + var dam = hp * i.damage + for n in i.get("spawn_num", 0): + var spawn_info = info[i.spawn_on_death] + dam += get_damage(spawn_info.lives, i.spawn_on_death) + return dam diff --git a/scripts/movement.gd b/scripts/movement.gd index 51deffd..da4227e 100644 --- a/scripts/movement.gd +++ b/scripts/movement.gd @@ -13,22 +13,9 @@ var _pivot var _pivot_dist var _orbit_timer -var _turret_holder : Node -var _attach_point_holder : Node -var path_holder : Node -var load_turrets : Node - -var _enemies : Node - func _ready(): camera = $camera placer = $placer - - var root = get_tree().root.get_node("world") - - path_holder = root.get_node("path") - _enemies = root.get_node("enemies") - func look_free (m): self.transform.basis = self.transform.basis.rotated(Vector3.UP, m.x) diff --git a/scripts/resources.gd b/scripts/resources.gd index 1fc50c5..2575cb3 100644 --- a/scripts/resources.gd +++ b/scripts/resources.gd @@ -6,6 +6,8 @@ var a : float = 0 var d : float = 0 var s : float = 0 +var lives : int = 0 + func get_names(): return "Tkads" func dict_to_str (cost): diff --git a/scripts/spawner.gd b/scripts/spawner.gd new file mode 100644 index 0000000..9866168 --- /dev/null +++ b/scripts/spawner.gd @@ -0,0 +1,24 @@ +extends Timer + +var enemy_holder : Node +var queue : Array + +func fetch (): + var root = get_tree().root.get_node("world") + enemy_holder = root.get_node("enemies") + +func next (): + if queue.size() == 0: return null + var n = queue[0] + queue.remove(0) + return n + +func _on_timer_batch_timeout(): + # fetch called by wave + var n = next() + if n == null: + queue_free() + return + + enemy_holder.spawn(n.enemy) + start(n.cooldown) diff --git a/scripts/wave.gd b/scripts/wave.gd new file mode 100644 index 0000000..c4c43c7 --- /dev/null +++ b/scripts/wave.gd @@ -0,0 +1,94 @@ +extends Node + +var _timer : Resource = load("res://scenes/wave/timer_batch.tscn") + +var wave_num : int = 0 +var waves = [] + +var ongoing = false + +var load_shapes : Node +var gui : Node + +func fetch (): + var root = get_tree().root.get_node("world") + var saveload = root.get_node("saveload") + load_shapes = saveload.get_node("load_shapes") + gui = root.get_node("gui") + +func make_queue (spawn): + var queue = [] + for order in spawn.enemies: + for n in order.amount: + var e = { + "cooldown": order.cooldown, + "enemy": order.enemy + } + queue += [e] + if spawn.random: queue.shuffle() + return queue + +func add_spawner (spawn): + var timer = _timer.instance() + timer.queue = make_queue(spawn) + add_child(timer) + timer.fetch() + timer.start(spawn.time) + +func start_wave (wave): + for spawn in wave: + add_spawner(spawn) + + +func get_hp_budget (x : int): + var hp = pow((x + 10), 2.7) * 1.8 - 850 + return hp + +func get_affordable_enemies (hp_budget : int): + var aff = [] + for enemy in load_shapes.info: + if load_shapes.info[enemy].cost <= hp_budget: + aff += [load_shapes.info[enemy]] + return aff + +func pick_enemy (hp_budget : int): + var amt = 1 + var aff = get_affordable_enemies(hp_budget) + var enemy = aff[randi() % aff.size()] + var order = { + "amount" : amt, + "enemy": enemy.name, + "cooldown": 0.5 + } + return { "enemy": order, "cost": enemy.cost } + +func gen_wave (wave_num : int): + var hp_budget = get_hp_budget(wave_num) + + var enemies = [] + for i in range(0, 1000): + if hp_budget < 10: break + var enemy_cost = pick_enemy(hp_budget) + enemies += [ enemy_cost.enemy ] + hp_budget -= enemy_cost.cost + + var w = [ + { + "time": 0, "random": true, + "enemies": enemies + } + ] + return w + +func start(): + fetch() + ongoing = true + var w = null + if wave_num <= waves.size()-1: w = waves[wave_num] + else: w = gen_wave(wave_num) + start_wave(w) + +func end(): + ongoing = false + wave_num += 1 + gui.refresh() @@ -1,4 +1,4 @@ -[gd_scene load_steps=23 format=2] +[gd_scene load_steps=24 format=2] [ext_resource path="res://scripts/movement.gd" type="Script" id=1] [ext_resource path="res://scripts/enemies.gd" type="Script" id=2] @@ -16,6 +16,7 @@ [ext_resource path="res://scripts/load_shapes.gd" type="Script" id=14] [ext_resource path="res://scripts/control.gd" type="Script" id=15] [ext_resource path="res://scripts/pointer.gd" type="Script" id=16] +[ext_resource path="res://scripts/wave.gd" type="Script" id=17] [sub_resource type="SphereShape" id=1] @@ -197,3 +198,6 @@ script = ExtResource( 7 ) [node name="projectiles" type="Node" parent="."] [node name="attach" type="Node" parent="."] + +[node name="wave" type="Node" parent="."] +script = ExtResource( 17 ) |