53 lines
1.9 KiB
GDScript
53 lines
1.9 KiB
GDScript
extends Area2D
|
|
|
|
# #101 (#97c): the part of a structure a wave can actually hit.
|
|
#
|
|
# A Building is a plain Node2D, so nothing could collide with it - enemies
|
|
# flew through the mothership without noticing. This gives it a body in the
|
|
# same shape the rest of the game already understands: an Area2D in a group,
|
|
# exactly like a Ship or an asteroid, so EnemyProjectile needed one extra
|
|
# branch rather than a new concept.
|
|
#
|
|
# Damage is applied on a TICK rather than on area_entered. Entry fires once,
|
|
# which is right for a rammer - it dies on the first strike - but would let
|
|
# a sniper that drifted inside sit there scratch-free for ever. On a tick,
|
|
# an enemy parked on a structure is besieging it, which is what #97 asks
|
|
# for.
|
|
|
|
const STRIKE_INTERVAL: float = 0.7
|
|
var _strike_timer: float = 0.0
|
|
|
|
|
|
func _ready() -> void:
|
|
add_to_group("player_buildings")
|
|
|
|
|
|
func building_id() -> int:
|
|
var building: Node = get_parent()
|
|
return 0 if building == null else int(building.building_id)
|
|
|
|
|
|
# Called by EnemyProjectile, which knows nothing about buildings beyond this
|
|
# name - the same call it makes on a Ship.
|
|
func take_damage(amount: int) -> void:
|
|
GameState.damage_building(building_id(), amount)
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
_strike_timer -= delta
|
|
if _strike_timer > 0.0:
|
|
return
|
|
_strike_timer = STRIKE_INTERVAL
|
|
var id: int = building_id()
|
|
if id == 0:
|
|
return
|
|
for area in get_overlapping_areas():
|
|
if not is_instance_valid(area) or not area.is_in_group("enemies"):
|
|
continue
|
|
var damage: int = area.contact_damage() if area.has_method("contact_damage") else 6
|
|
# The structure is told first, for the same reason Ship tells the
|
|
# enemy first: resolving the enemy's own death can free it, and a
|
|
# rammer must still land its hit on the way out.
|
|
GameState.damage_building(id, damage)
|
|
if area.has_method("collide_with_player_building"):
|
|
area.collide_with_player_building()
|