125 lines
5.4 KiB
GDScript
125 lines
5.4 KiB
GDScript
class_name OnlineGiftPanel
|
||
extends PanelModule
|
||
|
||
# 在线礼包面板:
|
||
# - 负责在线时长礼包的状态、倒计时和领取。
|
||
# - 倒计时只在面板打开期间刷新;领取成功后重新拉取服务器状态。
|
||
# - 奖励统一写入库存 Facade,避免活动面板直接改 player_data。
|
||
var _list: VBoxContainer
|
||
var _started_at := 0
|
||
var _timer: Timer
|
||
var _panel: Control
|
||
|
||
const CONTENT_BG_POSITION := Vector2(76.0, 250.0)
|
||
const CONTENT_BG_SIZE := Vector2(488.0, 494.0)
|
||
const SCROLL_POSITION := Vector2(82.0, 258.0)
|
||
const SCROLL_SIZE := Vector2(474.0, 470.0)
|
||
const LIST_WIDTH := 468.0
|
||
const ROW_SIZE := Vector2(468.0, 118.0)
|
||
const ROW_SEPARATION := 18
|
||
|
||
|
||
func open() -> void:
|
||
_close_modal(false)
|
||
if _started_at <= 0:
|
||
_started_at = int(Time.get_unix_time_from_system())
|
||
var title: Texture2D = _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_Title1_png")
|
||
var icon: Texture2D = _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_Gift_png")
|
||
_panel = _ui.create_panel_shell("OnlineGiftPanel", Vector2(600.0, 780.0), icon, title)
|
||
_ui.add_content_panel_background(_panel, "InnerPage", CONTENT_BG_POSITION, CONTENT_BG_SIZE)
|
||
var scroll := ScrollContainer.new()
|
||
scroll.name = "OnlineGiftScroll"
|
||
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 = "OnlineGiftList"
|
||
_list.custom_minimum_size = Vector2(LIST_WIDTH, 0.0)
|
||
_list.add_theme_constant_override("separation", ROW_SEPARATION)
|
||
scroll.add_child(_list)
|
||
_start_timer()
|
||
render()
|
||
_open_modal(_panel)
|
||
|
||
|
||
func render() -> void:
|
||
if _list == null or not is_instance_valid(_list):
|
||
return
|
||
_clear_children(_list)
|
||
var claimed_index := int(_player_data().get("online_gift_get_count", 0)) % 7
|
||
for gift in _game_config.get_online_gift_config():
|
||
var status_data := _status(gift, claimed_index)
|
||
_add_row(_list, gift, int(status_data.get("status", 2)), int(status_data.get("left", 0)))
|
||
|
||
|
||
func _start_timer() -> void:
|
||
if _timer == null:
|
||
_timer = Timer.new()
|
||
_timer.wait_time = 1.0
|
||
_timer.timeout.connect(_on_timer)
|
||
if _owner != null:
|
||
_owner.add_child(_timer)
|
||
if _timer != null and _timer.is_stopped():
|
||
_timer.start()
|
||
|
||
|
||
func _on_timer() -> void:
|
||
if _panel != null and is_instance_valid(_panel) and _panel.get_parent() != null:
|
||
render()
|
||
|
||
|
||
func _status(gift: Dictionary, claimed_index: int) -> Dictionary:
|
||
var id := int(gift.get("id", 0))
|
||
if claimed_index >= id:
|
||
return {"status": 0, "left": 0}
|
||
if claimed_index != id - 1:
|
||
return {"status": 2, "left": int(gift.get("receive_time", 0))}
|
||
var elapsed := int(Time.get_unix_time_from_system()) - _started_at
|
||
var left := maxi(int(gift.get("receive_time", 0)) - elapsed, 0)
|
||
return {"status": 1 if left <= 0 else 2, "left": left}
|
||
|
||
|
||
func _add_row(parent: Control, gift: Dictionary, status: int, left: int) -> void:
|
||
var holder := Control.new()
|
||
holder.name = "OnlineGift%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_texture(holder, "GiftIcon", _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_Gift_png"), Vector2(12.0, 16.0), Vector2(72.0, 74.0), TextureRect.STRETCH_KEEP_ASPECT_CENTERED)
|
||
_ui.add_panel_label(holder, "Title", "在线礼包 %s" % int(gift.get("id", 0)), Vector2(92.0, 12.0), Vector2(158.0, 28.0), 24, Color.html("#fff75f"), 2, Color.html("#7d1c1c"), HORIZONTAL_ALIGNMENT_LEFT)
|
||
_add_cost_slots(holder, _reward_fields_to_text(gift, 1, 4), Vector2(92.0, 45.0), 4, 60.0, Vector2(56.0, 56.0))
|
||
var frame := "onLineGift_lingqu_png" if status == 1 else ("onLineGift_yilingqu_png" if status == 0 else "onLineGift_lingqud_png")
|
||
var button_text := "领取" if status == 1 else ("已领取" if status == 0 else _format_duration(left))
|
||
var button: Control = _ui.add_texture_button(holder, "Claim", _texture_provider.frame(_texture_provider.atlas_path("gift"), frame), Vector2(344.0, 44.0), Vector2(108.0, 46.0), button_text, Callable(self, "_claim").bind(int(gift.get("id", 0))), 18)
|
||
_set_texture_button_enabled(button, status == 1, _texture_provider.frame(_texture_provider.atlas_path("gift"), "onLineGift_lingqu_png"), _texture_provider.frame(_texture_provider.atlas_path("gift"), frame))
|
||
|
||
|
||
func _claim(gift_id: int) -> void:
|
||
if _is_busy():
|
||
return
|
||
var player := _player_data()
|
||
var gift := _find_config_by_id(_game_config.get_online_gift_config(), gift_id)
|
||
if gift.is_empty():
|
||
return
|
||
var status_data := _status(gift, int(player.get("online_gift_get_count", 0)) % 7)
|
||
if int(status_data.get("status", 2)) != 1:
|
||
_show_toast("礼包倒计时未结束")
|
||
return
|
||
_set_busy(true)
|
||
var result: Dictionary = await _activity_api.claim_online_gift(_token())
|
||
_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)
|
||
player["online_gift_get_count"] = int(player.get("online_gift_get_count", 0)) + 1
|
||
_started_at = int(Time.get_unix_time_from_system())
|
||
_show_toast("获得 %s" % _format_reward_text(rewards))
|
||
await _refresh_store_house()
|
||
render()
|