From c930eb8a0cabaeb3651e2dc7f94a26310fb2dcf3 Mon Sep 17 00:00:00 2001 From: jacopograndi Date: Wed, 19 Jan 2022 20:08:32 +0100 Subject: turrets implementation finished --- scripts/bullet.gd | 94 +++++++++++++++++++++++++++++++--------------- scripts/control.gd | 17 +++++++-- scripts/enemies.gd | 27 ++++++++----- scripts/fx/selfdestruct.gd | 8 ++++ scripts/gui_picker.gd | 2 + scripts/load_scenes.gd | 2 + scripts/placer.gd | 2 +- scripts/resources.gd | 5 ++- scripts/turret.gd | 29 +++++++++----- scripts/wave.gd | 1 - 10 files changed, 131 insertions(+), 56 deletions(-) create mode 100644 scripts/fx/selfdestruct.gd (limited to 'scripts') diff --git a/scripts/bullet.gd b/scripts/bullet.gd index 3a50a12..86319bb 100644 --- a/scripts/bullet.gd +++ b/scripts/bullet.gd @@ -1,9 +1,14 @@ extends Spatial var _enemies_holder +var _fx_holder +var load_scenes var shooter var damage = 0 +var aoe = 0 +var slowness_effect = 0 +var slowness_time = 0 var timer = 0 var time_life = 3 @@ -15,60 +20,89 @@ var hitlist = [] var ignore_collisions = false func _ready(): - if ignore_collisions: return - _enemies_holder = get_tree().root.get_node("world").find_node("enemies") + var root = get_tree().root.get_node("world") + _enemies_holder = root.get_node("enemies") + _fx_holder = root.get_node("fx") var _err = $Area.connect("body_entered", self, "collided") + var saveload = root.get_node("saveload") + load_scenes = saveload.get_node("load_scenes") + +func bounce_physics (delta): + var forward_dir = -global_transform.basis.z.normalized() + var space: PhysicsDirectSpaceState = get_world().direct_space_state + var from = transform.origin + var to = transform.origin + forward_dir * speed * delta + var mask = 0b0101 + var result = space.intersect_ray(from, to, [], mask) + if result.size() > 0: + hitlist.clear() + var bounced = forward_dir.bounce(result.normal).normalized() + var z = -bounced; + var x = bounced.cross(result.normal).normalized(); + var y = x.cross(z).normalized(); + var basis = Basis(x, y, z); + global_transform.basis = basis + forward_dir = -global_transform.basis.z.normalized() + var dist = transform.origin.distance_to(result.position) + transform.origin = result.position + var amt = speed * delta - dist + global_translate(forward_dir * amt) + else: + global_translate(forward_dir * speed * delta) func _physics_process(delta): timer += delta if timer >= time_life: + if aoe > 0: explode() queue_free() return - - if ignore_collisions: return - var forward_dir = -global_transform.basis.z.normalized() if bounce: - var space: PhysicsDirectSpaceState = get_world().direct_space_state - var from = transform.origin - var to = transform.origin + forward_dir * speed * delta - var mask = 0b0101 - var result = space.intersect_ray(from, to, [], mask) - if result.size() > 0: - hitlist.clear() - var bounced = forward_dir.bounce(result.normal).normalized() - var z = -bounced; - var x = bounced.cross(result.normal).normalized(); - var y = x.cross(z).normalized(); - var basis = Basis(x, y, z); - global_transform.basis = basis - forward_dir = -global_transform.basis.z.normalized() - var dist = transform.origin.distance_to(result.position) - transform.origin = result.position - var amt = speed * delta - dist - global_translate(forward_dir * amt) - else: - global_translate(forward_dir * speed * delta) + bounce_physics(delta) else: + var forward_dir = -global_transform.basis.z.normalized() global_translate(forward_dir * speed * delta) +func explode (): + var space = get_world().direct_space_state + + var shape = SphereShape.new() + shape.radius = aoe + + var params: = PhysicsShapeQueryParameters.new() + params.set_shape(shape) + params.collision_mask = 0b1000 + params.transform = transform + + var result = space.intersect_shape(params) + for body in result: + apply_damage(body.collider.get_parent().name) + + var fx_ex = load_scenes.fx_explosion.instance() + fx_ex.transform = transform + fx_ex.transform.basis = fx_ex.transform.basis.scaled(Vector3.ONE * aoe) + fx_ex.time_life = 0.2 + _fx_holder.add_child(fx_ex) + func collided(body): - if ignore_collisions: return var parent = body.get_parent() if parent == shooter: return if parent in hitlist: return if hit_something == false: var groups = parent.get_groups() - if "enemies" in groups: - _enemies_holder.damage(parent.name, damage) + ## TODO design? aoe damages twice: on hit and aoe + if "enemies" in groups: apply_damage(parent.name) + if aoe > 0: explode() - if !bounce: hit_something = true + if aoe > 0: explode() queue_free() else: hitlist.append(parent) - print(hitlist) +func apply_damage (enemyname): + _enemies_holder.damage(enemyname, damage, slowness_effect, slowness_time) + diff --git a/scripts/control.gd b/scripts/control.gd index 7c8b95d..68b0bb4 100644 --- a/scripts/control.gd +++ b/scripts/control.gd @@ -88,8 +88,8 @@ func build_option (st, sttype): func buy (pos, rot, turr_name): var info = load_turrets.info[turr_name] - if resources.greater_than(info.cost): - resources.sub(info.cost) + if ineditor or resources.greater_than(info.cost): + if !ineditor: resources.sub(info.cost) var obj = placer.inst_turret(pos, rot, turr_name) editing_turret = obj.name state = Globals.PlayerState.EDIT @@ -100,8 +100,8 @@ func buy (pos, rot, turr_name): func upgrade (turr_inst_name, upg_name): var info = load_turrets.info[upg_name] - if resources.greater_than(info.cost): - resources.sub(info.cost) + if ineditor or resources.greater_than(info.cost): + if !ineditor: resources.sub(info.cost) var prv = turret_holder.get_node(turr_inst_name) var pos = prv.transform.origin var rot = prv.transform.basis.get_rotation_quat() @@ -254,6 +254,15 @@ func gui_start_wave_event (): wave.start() gui.refresh() +func end_wave_event (): + wave.end() + + for turr in turret_holder.get_children(): + if turr.info.has("resource_per_wave"): + resources.add(turr.info.resource_per_wave) + + _refresh() + func gui_save_map_event (): saveload_map.map_save() func gui_save_as_map_event (mapname : String): diff --git a/scripts/enemies.gd b/scripts/enemies.gd index fe5ae14..a0f4416 100644 --- a/scripts/enemies.gd +++ b/scripts/enemies.gd @@ -7,7 +7,7 @@ var _enemy_blue var _dissolve_mat : ShaderMaterial var _enemy_mat : Material -var wave +var control var _fx_holder var _fx_enemy_damage @@ -33,7 +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") + 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") @@ -61,8 +61,8 @@ func spawn(name, node_cur=0, rel_pos=0): enemies[serial_enemy] = { "name": name, "hp": info.lives, - "slowed_effect": 0, - "slowed_time": 0, + "slow_effect": 0, + "slow_time": 0, "cur": node_cur, "rel": rel_pos, "axis": [axis.x, axis.y, axis.z] @@ -93,8 +93,11 @@ func _physics_process(delta): # todo rel +- epslion spawn(info.spawn_on_death, enemy.cur, enemy.rel - n/10) continue + + enemy.slow_time -= delta + if enemy.slow_time < 0: enemy.slow_effect = 0 - var speed = info.speed + var speed = info.speed * (1-enemy.slow_effect) enemy.rel += speed * delta while enemy.rel > 1: enemy.rel -= 1 @@ -120,18 +123,22 @@ func _physics_process(delta): enemies.erase(id) if enemies.size() == 0: - wave.end() + control.end_wave_event() -func damage(name, amt): +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: - enemy.hp -= amt - _resources.add({ info.resource: amt }) - fx_damage(name) + if dam > 0: + enemy.hp -= dam + _resources.add({ info.resource: dam }) + fx_damage(name) + 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) diff --git a/scripts/fx/selfdestruct.gd b/scripts/fx/selfdestruct.gd new file mode 100644 index 0000000..14f941f --- /dev/null +++ b/scripts/fx/selfdestruct.gd @@ -0,0 +1,8 @@ +extends Node + +var timer = 0 +var time_life = 3 + +func _physics_process(delta): + timer += delta + if timer >= time_life: queue_free() diff --git a/scripts/gui_picker.gd b/scripts/gui_picker.gd index b888572..85909ec 100644 --- a/scripts/gui_picker.gd +++ b/scripts/gui_picker.gd @@ -52,11 +52,13 @@ func build (options : Array = []): if opt.type == "turret buy": var tinfo = load_turrets.info[opt.name] button.get_node("name").text = tinfo.name + button.get_node("panel_cash").visible = true button.get_node("cash").text = resources.dict_to_str(tinfo.cost) button.get_node("texture").texture = load_turrets.thumbnails[tinfo.thumbnail_name] if opt.type == "turret upg": var tinfo = load_turrets.info[opt.name] button.get_node("name").text = tinfo.name + button.get_node("panel_cash").visible = true button.get_node("cash").text = resources.dict_to_str(tinfo.cost) button.get_node("texture").texture = load_turrets.thumbnails[tinfo.thumbnail_name] tback.texture = thumbs_generic["upgrade.svg"] diff --git a/scripts/load_scenes.gd b/scripts/load_scenes.gd index fe237a4..0c28061 100644 --- a/scripts/load_scenes.gd +++ b/scripts/load_scenes.gd @@ -5,3 +5,5 @@ var path_start : PackedScene = load("res://scenes/path_start.tscn") var path : PackedScene = load("res://scenes/path.tscn") var path_end : PackedScene= load("res://scenes/path_end.tscn") var attach_point : PackedScene = load("res://scenes/attach_point.tscn") + +var fx_explosion : PackedScene = load("res://scenes/fx/fx_explosion.tscn") diff --git a/scripts/placer.gd b/scripts/placer.gd index 991f333..18e72e8 100644 --- a/scripts/placer.gd +++ b/scripts/placer.gd @@ -132,7 +132,7 @@ func inst_path (pos, rot): instance.transform.origin = pos + normal * 0.25; instance.transform.basis = Basis(rot); instance.set_name("path") - # remove collision depencency + # TODO multiplayer remove collision depencency colliding_node.transform.basis = Basis(rot); return instance diff --git a/scripts/resources.gd b/scripts/resources.gd index 2575cb3..53462a6 100644 --- a/scripts/resources.gd +++ b/scripts/resources.gd @@ -12,8 +12,11 @@ func get_names(): return "Tkads" func dict_to_str (cost): var st = "" + var i = 0 for n in cost.keys(): - st += str(cost[n]) + n + st += str(cost[n]) + n + if i <= cost.keys().size()-2: st += " " + i += 1 return st func add (cost): diff --git a/scripts/turret.gd b/scripts/turret.gd index a9dfb74..fd44ce0 100644 --- a/scripts/turret.gd +++ b/scripts/turret.gd @@ -2,6 +2,7 @@ extends Spatial var _path : Node var _enemies : Node +var _fx_holder : Node var _projectiles_holder : Node var _enemies_holder : Node @@ -27,6 +28,7 @@ func _ready(): _enemies = root.get_node("enemies") _projectiles_holder = root.get_node("projectiles") _enemies_holder = root.find_node("enemies") + _fx_holder = root.find_node("fx") projectile = load("res://scenes/projectiles/bullet.tscn") ray = load("res://scenes/projectiles/ray.tscn") @@ -81,7 +83,7 @@ func get_target(): else: return null func _physics_process(delta): - if !info.has("damage"): return + if !info.has("projectile"): return if !_enemies.enemies.has(_target): _target = null @@ -93,6 +95,8 @@ func _physics_process(delta): _target = get_target() _target = get_target() + + var turn_speed = info.get("turn_speed", 0) if _target != null: var enemy = _enemies.node_from_id(_target) @@ -112,14 +116,14 @@ func _physics_process(delta): var base_basis = base.global_transform.basis.get_rotation_quat() var base_angle = base_basis.angle_to(base_rot) if base_angle > 0.01: - var base_amt = (info.turn_speed * delta) / base_angle + var base_amt = (turn_speed * delta) / base_angle base_amt = min(1, base_amt) base.global_transform.basis = Basis(base_basis.slerp(Basis(base_rot), base_amt)) var gun_basis = gun.transform.basis.get_rotation_quat() var gun_angle = gun_basis.angle_to(gun_rot) if gun_angle > 0.01: - var gun_amt = (info.turn_speed * delta) / gun_angle + var gun_amt = (turn_speed * delta) / gun_angle gun_amt = min(1, gun_amt) gun.transform.basis = Basis(gun_basis.slerp(Basis(gun_rot), gun_amt)) @@ -142,7 +146,7 @@ func spread (amt : int) -> Array: return dirs func shoot (): - if info.projectile.amount > 1: + if info.projectile.get("amount", 1) > 1: for dir in spread(info.projectile.amount): shoot_switch(dir) else: @@ -160,9 +164,13 @@ func shoot_bullet (dir : Basis, bounce = false): instance.transform.basis = dir instance.transform.origin = _shooting_point - dir.z*0.3; instance.shooter = self - instance.damage = info.damage - instance.speed = info.projectile.speed + instance.damage = info.projectile.get("damage", 0) + instance.speed = info.projectile.get("speed", 0) instance.bounce = bounce + instance.aoe = info.projectile.get("area_of_effect", 0) + instance.slowness_effect = info.projectile.get("slowness_effect", 0) + instance.slowness_time = info.projectile.get("slowness_time", 0) + instance.time_life = info.projectile.get("lifetime", 3) func shoot_ray (dir : Basis): var space: PhysicsDirectSpaceState = get_world().direct_space_state @@ -175,14 +183,17 @@ func shoot_ray (dir : Basis): var parent = result.collider.get_parent() var groups = parent.get_groups() if "enemies" in groups: - _enemies_holder.damage(parent.name, info.damage) + var dam = info.projectile.get("damage", 0) + var eff = info.projectile.get("slowness_effect", 0) + var tim = info.projectile.get("slowness_time", 0) + _enemies_holder.damage(parent.name, dam, eff, tim) var distance = result.position.distance_to(from) var instance = ray.instance() - instance.ignore_collisions = true - _projectiles_holder.add_child(instance) + _fx_holder.add_child(instance) instance.transform.origin = _shooting_point - dir.z*0.3; instance.transform.basis = dir instance.transform.basis.z *= distance instance.time_life = 0.05 + diff --git a/scripts/wave.gd b/scripts/wave.gd index c4c43c7..e61dfef 100644 --- a/scripts/wave.gd +++ b/scripts/wave.gd @@ -91,4 +91,3 @@ func start(): func end(): ongoing = false wave_num += 1 - gui.refresh() -- cgit v1.2.3-54-g00ecf