lcy
2026-06-12 e7e206de7ea26e0037d60ff0c3e9943950340a18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
using Cysharp.Threading.Tasks;
using UnityEngine;
 
public class GuildAtkDefBatBattlePanelItem : MonoBehaviour
{
    [SerializeField] RectTransform modelRect;
    [SerializeField] HorseController horseModel;
    [SerializeField] UIEffectPlayer uIEffectPlayer;
    [SerializeField] ButtonEx clickButton;
    [SerializeField] RectTransform wallRect;
    [SerializeField] TextEx nameText;
    [SerializeField] OutlineEx nameOutlineEx;
    [SerializeField] Color32 nameColorBlue;
    [SerializeField] Color32 nameColorRed;
    [SerializeField] Color32 nameColorGreen;
    [SerializeField] Color32 nameOutLineColorBlue;
    [SerializeField] Color32 nameOutLineColorRed;
    [SerializeField] Color32 nameOutLineColorGreen;
    [SerializeField] RectTransform starGruoupRect1;
    [SerializeField] ImageEx[] starGruoupImages1;
    [SerializeField] RectTransform starGruoupRect2;
    [SerializeField] ImageEx[] starGruoupImages2;
    [SerializeField] RectTransform starGruoupRect3;
    [SerializeField] ImageEx[] starGruoupImages3;
    [SerializeField] TextEx fightPowerText;
    [SerializeField] OfficialTitleCell officialTitleCell;
    [SerializeField] ButtonEx challengeButton;
    [SerializeField] ButtonEx changeButton;
    [SerializeField] ButtonEx sweepButton;
 
    public void Display(bool isMy, HA525_tagSCFamilyAtkDefBatInfo.tagSCFamilyAtkDefBatMem mem, bool showWall)
    {
        if (mem == null)
        {
            this.SetActive(false);
            return;
        }
        this.SetActive(true);
 
        // modelRect 水平翻转:己方-1,敌方1
        Vector3 localScale = modelRect.localScale;
        localScale.x = isMy ? 1f : -1f;
        modelRect.localScale = localScale;
 
        // 判断是否所有属性档位均已被击杀
        bool isCompletelyKilled = IsAllPropertyKilled(mem);
 
        // horseModel:未完全击败显示,完全击败隐藏
        horseModel.SetActive(!isCompletelyKilled);
        if (!isCompletelyKilled)
        {
            // 设置坐骑和角色模型
            int horseSkinID = HorseManager.Instance.GetOtherPlayerHorseSkinID((int)mem.EquipShowSwitch);
            int heroSkinID = ResolveHeroSkinID((int)mem.ModelMark, (int)mem.Job);
            horseModel.Create(horseSkinID, heroSkinID, 0.8f);
        }
 
        // uIEffectPlayer:完全击败显示,未完全击败隐藏(与horseModel相反)
        uIEffectPlayer.SetActive(isCompletelyKilled);
 
        // wallRect:由外部参数控制显隐(仅HeaderCell的副将和镇卫显示)
        wallRect.SetActive(showWall);
 
        // 官职与称号
        officialTitleCell.InitUI(mem.RealmLV, (int)mem.TitleID);
 
        // 名字颜色与描边
        if (isMy)
        {
            // 己方战场:自己的名字绿色,其他人的名字蓝色
            bool isSelf = mem.PlayerID == PlayerDatas.Instance.PlayerId;
            if (isSelf)
            {
                nameText.color = nameColorGreen;
                nameOutlineEx.OutlineColor = nameOutLineColorGreen;
            }
            else
            {
                nameText.color = nameColorBlue;
                nameOutlineEx.OutlineColor = nameOutLineColorBlue;
            }
        }
        else // 敌方统一红色
        {
            nameText.color = nameColorRed;
            nameOutlineEx.OutlineColor = nameOutLineColorRed;
        }
 
        // 名字
        nameText.text = mem.Name;
 
        // 战力显示
        long totalFightPower = GuildAtkDefBatManager.CalcTotalFightPower(mem.FightPower, mem.FightPowerEx);
        fightPowerText.text = UIHelper.ReplaceLargeArtNum(totalFightPower);
 
        // clickButton:点击查看他人详情
        clickButton.SetListener(() =>
        {
            AvatarHelper.TryViewOtherPlayerInfo((int)mem.PlayerID, (int)mem.ServerID, viewPlayerLineupType: (int)BattlePreSetType.GuildAtkDefBat);
        });
 
        // changeButton:备战期时,公会会长/副会长在己方战场显示
        bool canChange = false;
        if (isMy && GuildAtkDefBatManager.Instance.GetGuildBattleDisplayState() == 2)
        {
            uint myPlayerId = PlayerDatas.Instance.PlayerId;
            if (GuildAtkDefBatManager.Instance.MyFamilyMembers.TryGetValue(myPlayerId, out var myMember))
            {
                canChange = myMember.FmLV >= GuildAtkDefBatManager.Instance.adjustPositionJobLevel;
            }
        }
        changeButton.SetActive(canChange);
        changeButton.SetListener(() =>
        {
            GuildAtkDefBatChangeMemberWin.Open(mem);
        });
 
        // 全部属性档位被击杀时显示扫荡按钮,否则显示挑战按钮(仅在敌方战场显示)
        bool isAllKilled = IsAllPropertyKilled(mem);
        challengeButton.SetActive(!isMy && !isAllKilled);
        sweepButton.SetActive(!isMy && isAllKilled);
 
        challengeButton.SetListener(() =>
        {
            if (CheckChallengeCount()) return;
            GuildAtkDefBatChallengeWin.Open(mem);
        });
 
        sweepButton.SetListener(() =>
        {
            if (CheckChallengeCount()) return;
            ConfirmCancel.ToggleConfirmCancelByType(ToggleCheckType.GuildAtkDefBatSweep, 
            Language.Get("GuildAtkDefBat54"), 
            () =>
            {
                SendSweepFight(mem.PlayerID);
            });
        });
 
        // 星星显示
        DisplayStars(mem);
    }
 
    private void SendSweepFight(uint playerID)
    {
        // 扫荡封包:与挑战一致,仅 ValueList 第二位为 1,第一位属性百分比可任意值
        BattleManager.Instance.SendTurnFight((uint)GuildAtkDefBatManager.DataMapID, 0, 1, playerID, new[] { 100u, 1u }, showLoading: false);
    }
 
    /// <summary>
    /// 判断该成员所有属性档位是否均已被击杀
    /// </summary>
    private bool IsAllPropertyKilled(HA525_tagSCFamilyAtkDefBatInfo.tagSCFamilyAtkDefBatMem mem)
    {
        int[] starList = FamilyAtkDefBatDefenderConfig.GetDefStarList(mem.DefType);
        if (starList == null || starList.Length == 0)
            return false;
 
        for (int i = 0; i < starList.Length; i++)
        {
            if (!GuildAtkDefBatManager.Instance.IsPropertyKilled(mem.KilledState, i))
                return false;
        }
        return true;
    }
 
    /// <summary>
    /// 根据 ModelMark 和 Job 解析英雄皮肤ID
    /// </summary>
    private int ResolveHeroSkinID(int modelMark, int job)
    {
        if (modelMark == 0)
        {
            PhantasmPavilionManager.Instance.TryGetDefaultID(PhantasmPavilionType.Model, job, out modelMark);
        }
 
        if (!ModelConfig.HasKey(modelMark))
            return 0;
 
        var modelConfig = ModelConfig.Get(modelMark);
        return modelConfig.SkinID;
    }
 
    /// <summary>
    /// 显示破阵之星
    /// 根据防守类型从 FamilyAtkDefBatDefenderConfig 获取各档位星数,
    /// 按 KilledState 统计被击杀的总星数,从右往左将暗星排在尾部
    /// </summary>
    private void DisplayStars(HA525_tagSCFamilyAtkDefBatInfo.tagSCFamilyAtkDefBatMem mem)
    {
        int totalStars = FamilyAtkDefBatDefenderConfig.GetTotalStarCount(mem.DefType);
        if (totalStars <= 0)
        {
            starGruoupRect1.SetActive(false);
            starGruoupRect2.SetActive(false);
            starGruoupRect3.SetActive(false);
            return;
        }
 
        // 根据总星数选择显示组
        RectTransform activeGroupRect = null;
        ImageEx[] activeStarImages = null;
 
        if (totalStars <= 3)
        {
            activeGroupRect = starGruoupRect1;
            activeStarImages = starGruoupImages1;
        }
        else if (totalStars <= 6)
        {
            activeGroupRect = starGruoupRect2;
            activeStarImages = starGruoupImages2;
        }
        else // <= 9
        {
            activeGroupRect = starGruoupRect3;
            activeStarImages = starGruoupImages3;
        }
 
        starGruoupRect1.SetActive(activeGroupRect == starGruoupRect1);
        starGruoupRect2.SetActive(activeGroupRect == starGruoupRect2);
        starGruoupRect3.SetActive(activeGroupRect == starGruoupRect3);
 
        int[] starList = FamilyAtkDefBatDefenderConfig.GetDefStarList(mem.DefType);
        byte killedState = mem.KilledState;
 
        // 统计被击杀的总星数(从右往左扣)
        int darkStarCount = 0;
        for (int diffIdx = 0; diffIdx < starList.Length; diffIdx++)
        {
            if ((killedState & (1 << diffIdx)) != 0)
                darkStarCount += starList[diffIdx];
        }
        int litStarCount = totalStars - darkStarCount;
 
        int displayCount = Mathf.Min(totalStars, activeStarImages.Length);
        for (int starPos = 0; starPos < displayCount; starPos++)
        {
            string icon = starPos < litStarCount ? "GuildAtkDefBatStarLight" : "GuildAtkDefBatStarDark";
            activeStarImages[starPos].SetSprite(icon);
            activeStarImages[starPos].SetActive(true);
        }
 
        // 隐藏超出总星数的图片
        for (int i = displayCount; i < activeStarImages.Length; i++)
        {
            activeStarImages[i].SetActive(false);
        }
    }
 
    /// <summary>检查进攻次数,不足时提示并返回 true</summary>
    private bool CheckChallengeCount()
    {
        if (GuildAtkDefBatManager.Instance.GetMyRemainingChallengeCount() <= 0)
        {
            SysNotifyMgr.Instance.ShowTip("GuildAtkDefBat5");
            return true;
        }
        return false;
    }
}