class_name VesselShieldComponent extends Node const SHIELD_COLOR: Color = Color(0.45, 0.8, 1.0) const SHIELD_RADIUS: float = 30.0 var capability_id: String = "shield" var charges: int = 0 var recharge_left: float = 0.0 var ring: Node2D func setup() -> void: var ship: Node2D = get_parent() var state: Node = ship.get_tree().root.get_node("GameState") ring = NeonPiece.create(ship, Vector2.ZERO, SHIELD_COLOR) var points := PackedVector2Array() for i in range(14): var angle: float = float(i) / 14.0 * TAU points.append(Vector2(cos(angle), sin(angle)) * SHIELD_RADIUS) ring.add_polygon(points, 0.7) ring.queue_redraw() charges = int(state.vessel_stat(ship.vessel_type, "shield_charges")) _update_visual() func apply_stats() -> void: var was_up: bool = charges > 0 if was_up: charges = int(_state().vessel_stat(get_parent().vessel_type, "shield_charges")) _update_visual() func tick(delta: float) -> void: var maximum: int = int(_state().vessel_stat(get_parent().vessel_type, "shield_charges")) if charges >= maximum: return recharge_left -= delta if recharge_left <= 0.0: charges += 1 recharge_left = _state().vessel_stat(get_parent().vessel_type, "shield_recharge") _update_visual() func is_active() -> bool: return charges > 0 func absorb_hit() -> bool: if not is_active(): return false charges -= 1 recharge_left = _state().vessel_stat(get_parent().vessel_type, "shield_recharge") _update_visual() return true func set_charges(value: int) -> void: charges = value _update_visual() func _state() -> Node: return get_tree().root.get_node("GameState") func _update_visual() -> void: if ring != null: ring.visible = is_active()