hy-farm/godot/FarmGodot/scripts/ui/panels/online_gift_panel.gd
2026-05-29 19:54:56 +08:00

125 lines
5.4 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()