The last facet of reacting to impacts is to cause damage to targets. This is a generic system that can travel from project to project. We don’t want to make assumptions, so we use signals.
There’s a single damaged
signal on the ModularWeapons.gd
that any health and damage related system you use for your game can use.
signal damaged(target, amount)
We can emit this signal along with the damage in the base ProjectileEmitter.gd
whenever there’s a collision.
func _on_projectile_collided(target: Node, hit_location: Vector2) -> void: weapons_system.emit_signal("damaged", target, damage_per_collision) for event in weapons_system.projectile_impact_events: event.trigger(hit_location, spawned_objects, weapons_system, false)
For the ExplosionEvent.gd
, we trigger the explosion, wait a single frame for the physics server to update, then grab any overlapping bodies and calculate the damage caused to them based on their distance from the explosion epicenter.
func _do_trigger(_spawn_location: Vector2, _spawn_parent: Node, _weapons_system, _missed: bool) -> void: # ... explosion.trigger() yield(explosion.get_tree(), "physics_frame") var bodies: Array = explosion.area.get_overlapping_bodies() for body in bodies: var distance: float = body.global_position.distance_to(explosion.global_position) var damage := explosion_damage if damage_scales_with_distances: damage *= clamp(1.0 - distance / explosion_radius, 0, 1) _weapons_system.emit_signal("damaged", body, damage)