This commit is contained in:
2026-10-08 05:55:16 +08:00
parent 5062398e77
commit fd100521f9
@@ -39,6 +39,21 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
// 按钮与列表索引的映射(顺序固定:Green=0, Blue=1, Gold=2, VIP=3)
private Button[] _ptButtons;
[Header("炮台解锁限制(索引=按钮顺序 0绿/1蓝/2金/3VIP;非VIP只能用第一个)")]
[Tooltip("每个炮台所需贵族(VIP)等级,0=不限制。当前规则:只要是 VIP(≥1),后面三个都能用")]
public int[] ptUnlockVipLevel = { 0, 1, 1, 1 };
[Tooltip("每个炮台是否额外要求月卡在有效期内(当前规则不启用月卡限制,需要时把第 4 个勾上)")]
public bool[] ptUnlockNeedMonthCard = { false, false, false, false };
[Tooltip("贵族等级不足时按钮 LimitTip 的提示文案,{0}=所需贵族等级(原版 LevelLimit)")]
public string ptLockTipVipFormat = "贵族{0}解锁";
[Tooltip("需要月卡时按钮 LimitTip 的提示文案(原版 MemberBattery2)")]
public string ptLockTipMonthCard = "月卡专属";
[Tooltip("未解锁炮台按钮上的遮挡灰幕颜色(半透明灰)")]
public Color ptLockMaskColor = new Color(0f, 0f, 0f, 0.55f);
// 每个按钮的未解锁灰幕(懒创建后缓存复用;面板销毁时随之销毁)
private readonly Dictionary<Button, GameObject> _ptLockMasks = new Dictionary<Button, GameObject>();
// ⭐ 原版 PW_SelectBatteryView 的三个滑动节点(预制体里就是原版界面结构):
// mGOContent(内容)从下方滑入滑出;mBtnUserInfo(头像)/ mGOGirl(看板娘)从左侧滑入滑出
private RectTransform _ptContent;
@@ -348,6 +363,22 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
if (_ptButtons[i] == null) continue;
bool available = i < count && list[i] != null;
_ptButtons[i].gameObject.SetActive(available);
if (!available) continue;
// ⭐ 解锁限制(原版 PW_SelectBatteryView:InitBattery):未解锁 → 按钮上 LimitTip 显示提示文案
// 非 VIP 玩家后面几个炮台不解锁,只能切第一个(点击时再拦一次,见 OnPTButtonClicked)
string lockTip = GetPTLockTip(i);
bool locked = lockTip != null;
var limitTip = FindChildByName(_ptButtons[i].transform, "LimitTip");
if (limitTip != null)
{
if (limitTip.gameObject.activeSelf != locked) limitTip.gameObject.SetActive(locked);
if (locked) SetTextContent(limitTip, lockTip);
}
// ⭐ 未解锁再压一层半透明灰幕遮挡(纯视觉,不挡点击;压在 LimitTip 下面保证提示可见)
SetPTLockMask(_ptButtons[i], locked);
}
ChangePTPanel.SetActive(true);
@@ -466,6 +497,22 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
return;
}
// ⭐ 解锁限制:未解锁(贵族等级不足 / 需要月卡)不允许切换,保持面板打开
// (原版 SelectBattery:等级不够 → HallShowTip(LevelNotEnough) 后 return)
string lockTip = GetPTLockTip(index);
if (lockTip != null)
{
var btn = index >= 0 && index < _ptButtons.Length ? _ptButtons[index] : null;
var tipNode = btn != null ? FindChildByName(btn.transform, "LimitTip") : null;
if (tipNode != null)
{
if (!tipNode.gameObject.activeSelf) tipNode.gameObject.SetActive(true);
SetTextContent(tipNode, lockTip);
}
Debug.Log($"[XJMH] 炮台{index}未解锁({lockTip}),不切换。当前贵族等级={GetLocalVipLevel()}");
return;
}
int prevIndex = currSitData.currentTurretIndex;
bool success = currSitData.SwitchTurretByIndex(index);
if (!success)
@@ -484,6 +531,79 @@ public class GameMainPanel_XJMH : GameMainPanel_FishBase
HidePTPanel();
}
/// <summary>本地玩家贵族(VIP)等级(0=非VIP)</summary>
private static int GetLocalVipLevel()
{
var u = GameManager.Instance != null ? GameManager.Instance.user : null;
return u != null && u.assets != null ? u.assets.vipLevel : 0;
}
/// <summary>本地玩家月卡是否在有效期内(userCardEndTime;兼容秒/毫秒时间戳)</summary>
private static bool HasMonthCard()
{
var u = GameManager.Instance != null ? GameManager.Instance.user : null;
if (u == null || u.assets == null) return false;
long end = u.assets.userCardEndTime;
if (end <= 0) return false;
if (end < 100000000000L) end *= 1000L; // 秒 → 毫秒
long now = BeijingTimeManager.Instance != null ? BeijingTimeManager.Instance.CurrentTimestampMs : 0L;
return end > now;
}
/// <summary>
/// 该索引炮台的解锁提示文案:未解锁返回提示文字(显示在按钮 LimitTip 上并禁止切换),已解锁返回 null。
/// 判定顺序:月卡限制 → 贵族(VIP)等级限制(对应面板上的 ptUnlockNeedMonthCard / ptUnlockVipLevel)。
/// </summary>
private string GetPTLockTip(int index)
{
if (ptUnlockNeedMonthCard != null && index < ptUnlockNeedMonthCard.Length
&& ptUnlockNeedMonthCard[index] && !HasMonthCard())
return string.IsNullOrEmpty(ptLockTipMonthCard) ? "月卡专属" : ptLockTipMonthCard;
int need = (ptUnlockVipLevel != null && index < ptUnlockVipLevel.Length) ? ptUnlockVipLevel[index] : 0;
if (GetLocalVipLevel() < need)
return string.IsNullOrEmpty(ptLockTipVipFormat) ? $"VIP{need}解锁" : string.Format(ptLockTipVipFormat, need);
return null;
}
/// <summary>
/// 设置按钮上的"未解锁灰幕"显隐(懒创建:半透明灰 Image 铺满按钮,纯视觉、不挡点击)。
/// 灰幕压在 LimitTip 下面,保证"贵族X解锁"提示仍然可见。
/// </summary>
private void SetPTLockMask(Button btn, bool show)
{
if (btn == null) return;
if (!_ptLockMasks.TryGetValue(btn, out var mask) || mask == null)
{
var go = new GameObject("[PTLockMask]", typeof(RectTransform), typeof(Image));
var rt = (RectTransform)go.transform;
rt.SetParent(btn.transform, false);
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.one;
rt.offsetMin = Vector2.zero;
rt.offsetMax = Vector2.zero;
var img = go.GetComponent<Image>();
img.color = ptLockMaskColor;
img.raycastTarget = false; // 纯遮挡:点击仍能落到按钮上走"未解锁"提示
// 排在 LimitTip 之前(层级更低),提示文字不会被灰幕盖住
var tip = FindChildByName(btn.transform, "LimitTip");
if (tip != null) rt.SetSiblingIndex(Mathf.Max(0, tip.GetSiblingIndex()));
mask = go;
_ptLockMasks[btn] = mask;
}
// 颜色每次同步(Play 模式下面板上改完立即生效)
var maskImg = mask.GetComponent<Image>();
if (maskImg != null && maskImg.color != ptLockMaskColor) maskImg.color = ptLockMaskColor;
if (mask.activeSelf != show) mask.SetActive(show);
}
// ==================== 金币柱 ====================
/// <summary>