diff --git a/client/ui/meta/screens/character_creation/character_creation.gd b/client/ui/meta/screens/character_creation/character_creation.gd index ca427fc70..86f4ee84e 100644 --- a/client/ui/meta/screens/character_creation/character_creation.gd +++ b/client/ui/meta/screens/character_creation/character_creation.gd @@ -273,12 +273,16 @@ var _appearance_active_idx: int = 0 var _appearance_sub_btns: Array[Button] = [] var _appearance_sub_sections: Array[Control] = [] -# --- Bookmark tab state (WS6) --- +# --- Bookmark tab state (WS6/WS7) --- var _selected_bookmark_id: String = "" var _selected_location_id: String = "" var _bookmark_cards: Array[Button] = [] var _bookmark_detail_panel: ImplantPanel = null var _bookmark_cards_vbox: VBoxContainer = null +var _location_items: Array[Button] = [] +var _location_item_ids: Array[String] = [] +var _location_item_labels: Array[Label] = [] +var _location_vbox: VBoxContainer = null # --- Asset manifest (loaded once, replaces filesystem scanning) --- var _manifest: Dictionary = {} @@ -739,6 +743,11 @@ func _update_bookmark_card_selection() -> void: func _refresh_bookmark_detail(bm: Dictionary) -> void: _bookmark_detail_panel.clear() + _location_items.clear() + _location_item_ids.clear() + _location_item_labels.clear() + _location_vbox = null + if bm.is_empty(): _bookmark_detail_panel.add_component( ImplantHeader.new("Select a Bookmark", "Choose your starting conditions") @@ -757,9 +766,9 @@ func _refresh_bookmark_detail(bm: Dictionary) -> void: ImplantDataRow.new("Starting Capital: %d tr" % int(capital), TEXT_COLOR) ) - var default_loc: String = bm.get("default_location", "") - if not default_loc.is_empty(): - _bookmark_detail_panel.add_component(ImplantDataRow.new("Starting Location: " + default_loc, TEXT_DIM)) + # Location picker (WS7) — replaces the single "Starting Location: X" DataRow + _bookmark_detail_panel.add_component(ImplantSeparator.new()) + _build_location_picker(bm) var flavor: String = bm.get("flavor", "") if not flavor.is_empty(): @@ -771,6 +780,85 @@ func _update_start_btn_state() -> void: _footer_start.disabled = _selected_bookmark_id.is_empty() or _selected_location_id.is_empty() +func _build_location_picker(bm: Dictionary) -> void: + var allowed: Array = bm.get("allowed_locations", []) + var cultures: Array = bm.get("allowed_locations_cultures", []) + + var section_lbl := Label.new() + section_lbl.text = "STARTING LOCATION" + section_lbl.add_theme_color_override("font_color", TEXT_DIM) + section_lbl.add_theme_font_size_override("font_size", 10) + section_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE + _bookmark_detail_panel.add_component(section_lbl) + + if allowed.is_empty(): + return + + var scroll := ScrollContainer.new() + scroll.custom_minimum_size = Vector2(0, 80) + scroll.size_flags_horizontal = Control.SIZE_FILL + _bookmark_detail_panel.add_component(scroll) + + _location_vbox = VBoxContainer.new() + _location_vbox.size_flags_horizontal = Control.SIZE_FILL + _location_vbox.add_theme_constant_override("separation", 2) + scroll.add_child(_location_vbox) + + for i in allowed.size(): + var loc_id: String = allowed[i] + var culture: String = cultures[i] if i < cultures.size() else "" + + var btn := Button.new() + btn.size_flags_horizontal = Control.SIZE_FILL + btn.flat = false + btn.focus_mode = Control.FOCUS_NONE + btn.pressed.connect(_on_location_selected.bind(loc_id)) + + var vbox := VBoxContainer.new() + vbox.mouse_filter = Control.MOUSE_FILTER_IGNORE + vbox.add_theme_constant_override("separation", 1) + vbox.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + btn.add_child(vbox) + + var name_lbl := Label.new() + name_lbl.text = loc_id + name_lbl.add_theme_color_override("font_color", TEXT_COLOR) + name_lbl.add_theme_font_size_override("font_size", 12) + name_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE + vbox.add_child(name_lbl) + + if not culture.is_empty(): + var culture_lbl := Label.new() + culture_lbl.text = culture + culture_lbl.add_theme_color_override("font_color", TEXT_DIM) + culture_lbl.add_theme_font_size_override("font_size", 10) + culture_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE + vbox.add_child(culture_lbl) + + _location_vbox.add_child(btn) + _location_items.append(btn) + _location_item_ids.append(loc_id) + _location_item_labels.append(name_lbl) + + _update_location_selection() + + +func _on_location_selected(loc_id: String) -> void: + _selected_location_id = loc_id + _update_location_selection() + _update_start_btn_state() + + +func _update_location_selection() -> void: + for i in _location_items.size(): + var selected: bool = (i < _location_item_ids.size() and _location_item_ids[i] == _selected_location_id) + _set_item_selected(_location_items[i], selected) + if i < _location_item_labels.size() and is_instance_valid(_location_item_labels[i]): + _location_item_labels[i].add_theme_color_override( + "font_color", HIGHLIGHT_COLOR if selected else TEXT_COLOR + ) + + # ============================================================================= # Tab: Body (Task #2) # =============================================================================