class_name LevelGiftPanel extends PanelModule # 等级礼包面板: # - 按玩家等级和领取记录展示可领取/未达成/已领取状态。 # - 奖励文本复用配置表字段,领取后统一调用库存 Facade 落账。 # - 这里只负责活动 UI 和按钮状态,不改变等级经验计算规则。 var _list: VBoxContainer const CONTENT_BG_POSITION := Vector2(76.0, 188.0) const CONTENT_BG_SIZE := Vector2(488.0, 594.0) const SCROLL_POSITION := Vector2(82.0, 198.0) const SCROLL_SIZE := Vector2(474.0, 570.0) const LIST_WIDTH := 468.0 const ROW_SIZE := Vector2(468.0, 118.0) const ROW_SEPARATION := 18 func open() -> void: _close_modal(false) await _refresh_store_house() var title: Texture2D = _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_Title2_png") var icon: Texture2D = _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_Gift1_png") var panel: Control = _ui.create_panel_shell("LevelGiftPanel", Vector2(600.0, 820.0), icon, title) _ui.add_content_panel_background(panel, "InnerPage", CONTENT_BG_POSITION, CONTENT_BG_SIZE) var scroll := ScrollContainer.new() scroll.name = "LevelGiftScroll" scroll.position = SCROLL_POSITION scroll.size = SCROLL_SIZE scroll.clip_contents = true _ui.configure_vertical_scroll(scroll) scroll.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER panel.add_child(scroll) _list = VBoxContainer.new() _list.name = "LevelGiftList" _list.custom_minimum_size = Vector2(LIST_WIDTH, 0.0) _list.add_theme_constant_override("separation", ROW_SEPARATION) scroll.add_child(_list) _open_modal(panel) await render() func render() -> void: var list := _list if not _clear_children_if_live(list): return _ui.add_panel_label(list, "Loading", "读取等级礼包...", Vector2.ZERO, Vector2(490.0, 50.0), 22, Color.html("#753f24"), 0, Color.TRANSPARENT) var result: Dictionary = await _activity_api.fetch_level_gift_list(_token()) if not _is_current_node(list, _list): return _clear_children(list) var received := {} if result.get("ok", false): var data = _response_data(result, {}) if data is Dictionary: for row in data.get("list", []): if row is Dictionary: received[int(row.get("gift_id", row.get("id", 0)))] = true else: _show_toast(_response_status_text(result, "等级礼包读取失败")) var player := _player_data() for gift in _game_config.get_level_gift_config(): var status := 2 if received.has(int(gift.get("id", 0))): status = 0 elif int(gift.get("player_level", 1)) <= int(player.get("level", 1)): status = 1 _add_row(list, gift, status) func _add_row(parent: Control, gift: Dictionary, status: int) -> void: var holder := Control.new() holder.name = "Gift%s" % int(gift.get("id", 0)) holder.custom_minimum_size = ROW_SIZE holder.size = ROW_SIZE parent.add_child(holder) _ui.add_nine_patch(holder, "Bg", _texture_provider.frame(_texture_provider.atlas_path("common2"), "common_itemrender_png"), Vector2.ZERO, holder.size, Vector4(95.0, 70.0, 350.0, 108.0)) _ui.add_panel_label(holder, "Title", "LV.%s 等级礼包" % int(gift.get("player_level", 1)), Vector2(20.0, 10.0), Vector2(175.0, 30.0), 24, Color.html("#fff75f"), 2, Color.html("#7d1c1c"), HORIZONTAL_ALIGNMENT_LEFT) var reward_text := _reward_fields_to_text(gift, 1, 4) _add_cost_slots(holder, reward_text, Vector2(20.0, 43.0), 4, 76.0, Vector2(66.0, 66.0)) var normal: Texture2D = _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_lingqu_png") var disabled: Texture2D = _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_lingqud_png") var button_tex: Texture2D = normal if status == 1 else _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_yilingqu_png") var button_text := "领取" if status == 1 else ("已领取" if status == 0 else "未达成") var button: Control = _ui.add_texture_button(holder, "Claim", button_tex, Vector2(342.0, 43.0), Vector2(108.0, 46.0), button_text, Callable(self, "_claim").bind(int(gift.get("id", 0))), 22) _set_texture_button_enabled(button, status == 1, normal, disabled) func _claim(gift_id: int) -> void: if _is_busy(): return var gift := _find_config_by_id(_game_config.get_level_gift_config(), gift_id) if gift.is_empty(): return _set_busy(true) var result: Dictionary = await _activity_api.claim_level_gift(_token(), gift_id) _set_busy(false) if not result.get("ok", false): _show_toast(_response_status_text(result, "领取等级礼包失败")) return var rewards := _reward_fields_to_text(gift, 1, 4) _add_reward_items(rewards) _show_toast("获得 %s" % _format_reward_text(rewards)) await _refresh_store_house() await render()