extends Node2D const PICKUP_RADIUS := 48.0 const ATTRACTION_RADIUS := 150.0 var item: ItemInstance var _player: CharacterBody2D var _label: Label var _glow_time := 0.0 func _ready() -> void: add_to_group("loot") _player = get_parent().get_node_or_null("PlayerShip") as CharacterBody2D _label = Label.new() _label.position = Vector2(-110, 18) _label.size = Vector2(220, 44) _label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _label.add_theme_font_size_override("font_size", 11) _label.add_theme_color_override("font_color", Color("f1f4f8")) _label.text = item.definition.display_name add_child(_label) z_index = 18 set_process(item.get_addon_count() >= 5) queue_redraw() func _process(delta: float) -> void: _glow_time += delta queue_redraw() func _draw() -> void: if item == null: return if item.get_addon_count() >= 5: _draw_legendary_glow() var border := Color("70f5df") if item.definition.category == ItemDefinition.Category.CONSUMABLE else item.get_type_color() for radius in [28.0, 23.0, 19.0]: draw_circle(Vector2.ZERO, radius, Color(border, 0.07)) draw_circle(Vector2.ZERO, 18.0, item.get_background_color()) draw_arc(Vector2.ZERO, 19.0, 0.15, PI - 0.15, 32, border, 1.5, true) draw_arc(Vector2.ZERO, 19.0, PI + 0.15, TAU - 0.15, 32, border, 1.5, true) if item.definition.icon != null: draw_texture_rect(item.definition.icon, Rect2(-16, -16, 32, 32), false) func _draw_legendary_glow() -> void: var gold := Color("ffbd68") var pulse := 0.85 + 0.15 * sin(_glow_time * 2.0) # Soft layered halo remains visible without requiring viewport bloom. for layer in range(12, 0, -1): var radius := 20.0 + float(layer) * 3.5 draw_circle(Vector2.ZERO, radius, Color(gold, 0.012 * pulse)) # A tapered pillar and a slowly turning broken ring mark a maximum-addon drop. for layer in range(6, 0, -1): var width := float(layer) * 2.2 draw_polygon(PackedVector2Array([Vector2(-width, 0), Vector2(-width * 0.2, -94), Vector2(width * 0.2, -94), Vector2(width, 0)]), PackedColorArray([Color(gold, 0.025 * pulse), Color(gold, 0), Color(gold, 0), Color(gold, 0.025 * pulse)])) var angle := _glow_time * 0.25 for segment in 3: var start := angle + float(segment) * TAU / 3.0 draw_arc(Vector2.ZERO, 29.0, start, start + 1.25, 20, Color(gold, 0.42 * pulse), 1.0, true) func _physics_process(delta: float) -> void: if not is_instance_valid(_player) or bool(_player.get("_is_destroyed")): return var distance := global_position.distance_to(_player.global_position) if distance > ATTRACTION_RADIUS: return var inventory := _player.get_node("ShipInventory") as ShipInventory if not inventory.can_add_item(item): _label.text = "%s\nMagazyn pełny" % item.definition.display_name return _label.text = item.definition.display_name if distance <= PICKUP_RADIUS: if inventory.add_item(item): set_physics_process(false) queue_free() else: global_position = global_position.move_toward(_player.global_position, 180.0 * delta)