Add team, teamate manager dlg
This commit is contained in:
@@ -0,0 +1,396 @@
|
||||
// Port of C++ DlgArrangeTeam - Arrange Team dialog (invite, kick, leave, list teammates, nearby players, pickup mode, make leader).
|
||||
// Uses Unity UI: content RectTransforms + item prefab with DlgArrangeTeamListItem (text component, optional Button).
|
||||
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster;
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
namespace BrewMonster.UI
|
||||
{
|
||||
public class DlgArrangeTeam : AUIDialog
|
||||
{
|
||||
#region UI References
|
||||
|
||||
[Header("Teammates list (Unity UI)")]
|
||||
[SerializeField] private RectTransform Content_Teammates;
|
||||
[SerializeField] private GameObject TeammateItemPrefab;
|
||||
|
||||
[Header("Nearby players list (Unity UI)")]
|
||||
[SerializeField] private RectTransform Content_Nearby;
|
||||
[SerializeField] private GameObject NearbyItemPrefab;
|
||||
|
||||
[Header("Buttons")]
|
||||
[SerializeField] private Button m_pBtn_Invite;
|
||||
[SerializeField] private Button m_pBtn_Kick;
|
||||
[SerializeField] private Button m_pBtn_Leave;
|
||||
[SerializeField] private Button m_pBtn_Disband;
|
||||
[SerializeField] private Button m_pBtn_MakeLeader;
|
||||
[SerializeField] private Button m_pBtn_Refresh;
|
||||
|
||||
[Header("Invite")]
|
||||
[SerializeField] private TMP_InputField m_pInput_Name;
|
||||
|
||||
[Header("Pickup Mode")]
|
||||
[SerializeField] private Toggle m_pChk_Random;
|
||||
[SerializeField] private Toggle m_pChk_Free;
|
||||
|
||||
[Header("Profession filter (dropdown: trigger opens panel with multi-select toggles)")]
|
||||
[SerializeField] private TMP_Dropdown m_pDropdown_Prof;
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly List<DlgArrangeTeamListItem> m_TeammateItems = new List<DlgArrangeTeamListItem>();
|
||||
private int m_selectedTeammateId;
|
||||
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
SetName("Win_ArrangeTeam");
|
||||
#if UNITY_EDITOR
|
||||
if (m_pBtn_Leave == null) Debug.LogWarning("[DlgArrangeTeam] m_pBtn_Leave is not assigned in Inspector. Assign the Leave button.");
|
||||
if (m_pBtn_Disband == null) Debug.LogWarning("[DlgArrangeTeam] m_pBtn_Disband is not assigned in Inspector. Assign the Disband button.");
|
||||
#endif
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
BindButtonListeners();
|
||||
}
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
BindButtonListeners();
|
||||
}
|
||||
|
||||
public override void OnDisable()
|
||||
{
|
||||
UnbindButtonListeners();
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
private void BindButtonListeners()
|
||||
{
|
||||
if (m_pBtn_Invite != null) { m_pBtn_Invite.onClick.RemoveListener(OnInvite); m_pBtn_Invite.onClick.AddListener(OnInvite); }
|
||||
if (m_pBtn_Kick != null) { m_pBtn_Kick.onClick.RemoveListener(OnKick); m_pBtn_Kick.onClick.AddListener(OnKick); }
|
||||
if (m_pBtn_Leave != null) { m_pBtn_Leave.onClick.RemoveListener(OnLeave); m_pBtn_Leave.onClick.AddListener(OnLeave); }
|
||||
if (m_pBtn_Disband != null) { m_pBtn_Disband.onClick.RemoveListener(OnDisband); m_pBtn_Disband.onClick.AddListener(OnDisband); }
|
||||
if (m_pBtn_MakeLeader != null) { m_pBtn_MakeLeader.onClick.RemoveListener(OnMakeLeader); m_pBtn_MakeLeader.onClick.AddListener(OnMakeLeader); }
|
||||
if (m_pBtn_Refresh != null) { m_pBtn_Refresh.onClick.RemoveListener(OnRefresh); m_pBtn_Refresh.onClick.AddListener(OnRefresh); }
|
||||
if (m_pChk_Random != null) m_pChk_Random.onValueChanged.AddListener(OnRandomToggled);
|
||||
if (m_pChk_Free != null) m_pChk_Free.onValueChanged.AddListener(OnFreeToggled);
|
||||
BindProfDropdown();
|
||||
}
|
||||
|
||||
private void UnbindButtonListeners()
|
||||
{
|
||||
if (m_pBtn_Invite != null) m_pBtn_Invite.onClick.RemoveListener(OnInvite);
|
||||
if (m_pBtn_Kick != null) m_pBtn_Kick.onClick.RemoveListener(OnKick);
|
||||
if (m_pBtn_Leave != null) m_pBtn_Leave.onClick.RemoveListener(OnLeave);
|
||||
if (m_pBtn_Disband != null) m_pBtn_Disband.onClick.RemoveListener(OnDisband);
|
||||
if (m_pBtn_MakeLeader != null) m_pBtn_MakeLeader.onClick.RemoveListener(OnMakeLeader);
|
||||
if (m_pBtn_Refresh != null) m_pBtn_Refresh.onClick.RemoveListener(OnRefresh);
|
||||
if (m_pChk_Random != null) m_pChk_Random.onValueChanged.RemoveListener(OnRandomToggled);
|
||||
if (m_pChk_Free != null) m_pChk_Free.onValueChanged.RemoveListener(OnFreeToggled);
|
||||
UnbindProfDropdown();
|
||||
CloseProfFilterPanel();
|
||||
}
|
||||
|
||||
private void OnRandomToggled(bool on) { if (on) OnPickupModeChanged(1); }
|
||||
private void OnFreeToggled(bool on) { if (on) OnPickupModeChanged(0); }
|
||||
|
||||
private void BindProfDropdown()
|
||||
{
|
||||
if (m_pDropdown_Prof != null) m_pDropdown_Prof.interactable = false;
|
||||
}
|
||||
|
||||
private void UnbindProfDropdown() { }
|
||||
|
||||
private void CloseProfFilterPanel() { }
|
||||
|
||||
private void UpdateProfDropdownCaption()
|
||||
{
|
||||
if (m_pDropdown_Prof == null) return;
|
||||
var set = GetSelectedProfessionSet();
|
||||
string caption;
|
||||
if (set == null) caption = "All";
|
||||
else if (set.Count >= (int)Profession.NUM_PROFESSION) caption = "All";
|
||||
else
|
||||
{
|
||||
var gameRun = EC_Game.GetGameRun();
|
||||
var names = new List<string>();
|
||||
foreach (int i in set)
|
||||
{
|
||||
string name = gameRun?.GetProfName(i);
|
||||
names.Add(string.IsNullOrEmpty(name) ? $"Prof {i}" : name);
|
||||
}
|
||||
caption = string.Join(", ", names);
|
||||
}
|
||||
var label = m_pDropdown_Prof.captionText;
|
||||
if (label != null) label.text = caption;
|
||||
}
|
||||
|
||||
|
||||
public override void OnShowDialogue()
|
||||
{
|
||||
EnsureProfDropdownHasCaption();
|
||||
UpdateProfDropdownCaption();
|
||||
CloseProfFilterPanel();
|
||||
UpdateTeam(true);
|
||||
}
|
||||
|
||||
private void EnsureProfDropdownHasCaption()
|
||||
{
|
||||
if (m_pDropdown_Prof == null) return;
|
||||
if (m_pDropdown_Prof.options.Count == 0)
|
||||
m_pDropdown_Prof.AddOptions(new List<string> { "Profession" });
|
||||
}
|
||||
|
||||
/// <summary>Selected profession filter: null = show all.</summary>
|
||||
private HashSet<int> GetSelectedProfessionSet()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Refresh teammate list, optional nearby list, and button states.</summary>
|
||||
public bool UpdateTeam(bool bUpdateNear = false)
|
||||
{
|
||||
CECHostPlayer host = GetHostPlayer();
|
||||
if (host == null) return true;
|
||||
|
||||
var team = host.GetTeam();
|
||||
bool hasTeam = team != null;
|
||||
int idHost = host.GetCharacterID();
|
||||
bool isLeader = hasTeam && team.GetLeaderID() == idHost;
|
||||
|
||||
// Teammates list: clear and rebuild from prefab. Sort by each member's single profession, then by name.
|
||||
ClearList(Content_Teammates, m_TeammateItems);
|
||||
m_selectedTeammateId = 0;
|
||||
if (Content_Teammates != null && TeammateItemPrefab != null && hasTeam)
|
||||
{
|
||||
var members = new List<CECTeamMember>();
|
||||
int n = team.GetMemberNum();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var m = team.GetMemberByIndex(i);
|
||||
if (m != null) members.Add(m);
|
||||
}
|
||||
members.Sort((a, b) => { int c = a.GetProfession().CompareTo(b.GetProfession()); if (c != 0) return c; return string.CompareOrdinal(a.GetName() ?? "", b.GetName() ?? ""); });
|
||||
foreach (var m in members)
|
||||
{
|
||||
string mateName = m.GetName();
|
||||
int cid = m.GetCharacterID();
|
||||
if (!string.IsNullOrEmpty(mateName))
|
||||
Debug.Log($"[DlgArrangeTeam] Teammate: {mateName} (id {cid})");
|
||||
var item = CreateListItem(Content_Teammates, TeammateItemPrefab, mateName, cid, true, out var listItem);
|
||||
if (listItem != null)
|
||||
m_TeammateItems.Add(listItem);
|
||||
}
|
||||
}
|
||||
|
||||
// Nearby players list: filter by selected professions (multi-select); sort by each player's single profession, then by name
|
||||
if (bUpdateNear && Content_Nearby != null)
|
||||
{
|
||||
var prefab = NearbyItemPrefab != null ? NearbyItemPrefab : TeammateItemPrefab;
|
||||
ClearList(Content_Nearby, null);
|
||||
var manPlayer = EC_ManMessageMono.Instance?.GetECManPlayer;
|
||||
if (manPlayer != null && prefab != null)
|
||||
{
|
||||
HashSet<int> filterSet = GetSelectedProfessionSet();
|
||||
var nearby = new List<(string name, int cid, int prof)>();
|
||||
var otherIds = manPlayer.GetOtherPlayerCharacterIds();
|
||||
foreach (int cid in otherIds)
|
||||
{
|
||||
if (hasTeam && team.GetMemberByID(cid) != null) continue;
|
||||
var p = manPlayer.GetPlayer(cid, 0);
|
||||
string name = p != null ? (p.GetName() ?? "") : "";
|
||||
if (string.IsNullOrEmpty(name) && p?.gameObject != null && !string.IsNullOrEmpty(p.gameObject.name)) name = p.gameObject.name;
|
||||
if (string.IsNullOrEmpty(name)) name = "Player_" + cid;
|
||||
int prof = (p as CECPlayer) != null ? (p as CECPlayer).GetProfession() : 0;
|
||||
if (filterSet != null && !filterSet.Contains(prof)) continue;
|
||||
nearby.Add((name, cid, prof));
|
||||
}
|
||||
nearby.Sort((a, b) => { int c = a.prof.CompareTo(b.prof); if (c != 0) return c; return string.CompareOrdinal(a.name, b.name); });
|
||||
foreach (var t in nearby)
|
||||
{
|
||||
Debug.Log($"[DlgArrangeTeam] Nearby: {t.name} (id {t.cid})");
|
||||
CreateListItem(Content_Nearby, prefab, t.name, t.cid, false, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Button states
|
||||
if (m_pBtn_Leave != null) m_pBtn_Leave.interactable = hasTeam;
|
||||
if (m_pBtn_Disband != null) m_pBtn_Disband.interactable = hasTeam && isLeader;
|
||||
if (m_pBtn_Kick != null) m_pBtn_Kick.interactable = hasTeam && isLeader;
|
||||
if (m_pBtn_Invite != null) m_pBtn_Invite.interactable = isLeader;
|
||||
if (m_pBtn_MakeLeader != null) m_pBtn_MakeLeader.interactable = hasTeam && isLeader;
|
||||
if (m_pBtn_Refresh != null) m_pBtn_Refresh.interactable = true;
|
||||
|
||||
if (m_pChk_Random != null) m_pChk_Random.interactable = hasTeam && isLeader;
|
||||
if (m_pChk_Free != null) m_pChk_Free.interactable = hasTeam && isLeader;
|
||||
if (hasTeam && isLeader)
|
||||
{
|
||||
ushort pick = team.GetPickupFlag();
|
||||
if (m_pChk_Random != null) m_pChk_Random.SetIsOnWithoutNotify(pick != 0);
|
||||
if (m_pChk_Free != null) m_pChk_Free.SetIsOnWithoutNotify(pick == 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void ClearList(RectTransform content, List<DlgArrangeTeamListItem> items)
|
||||
{
|
||||
if (content == null) return;
|
||||
if (items != null) items.Clear();
|
||||
for (int i = content.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
var child = content.GetChild(i);
|
||||
if (child != null && child.gameObject != null)
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private GameObject CreateListItem(RectTransform content, GameObject prefab, string displayName, int characterId, bool isTeammate, out DlgArrangeTeamListItem listItem)
|
||||
{
|
||||
listItem = null;
|
||||
var go = Instantiate(prefab, content);
|
||||
go.SetActive(true);
|
||||
var comp = go.GetComponent<DlgArrangeTeamListItem>();
|
||||
if (comp != null)
|
||||
{
|
||||
comp.Set(displayName, characterId);
|
||||
listItem = comp;
|
||||
if (isTeammate)
|
||||
comp.SetClickCallback(OnTeammateItemSelected);
|
||||
else
|
||||
{
|
||||
comp.SetClickCallback(OnNearbyItemSelected);
|
||||
comp.SetInviteCallback(OnNearbyItemInvite);
|
||||
}
|
||||
}
|
||||
return go;
|
||||
}
|
||||
|
||||
private void OnTeammateItemSelected(DlgArrangeTeamListItem item)
|
||||
{
|
||||
m_selectedTeammateId = item.CharacterId;
|
||||
foreach (var i in m_TeammateItems)
|
||||
i.SetSelected(i == item);
|
||||
}
|
||||
|
||||
private void OnNearbyItemSelected(DlgArrangeTeamListItem item)
|
||||
{
|
||||
if (m_pInput_Name != null)
|
||||
m_pInput_Name.text = !string.IsNullOrEmpty(item.DisplayName) ? item.DisplayName : item.CharacterId.ToString();
|
||||
}
|
||||
|
||||
private void OnNearbyItemInvite(DlgArrangeTeamListItem item)
|
||||
{
|
||||
if (item?.CharacterId > 0)
|
||||
UnityGameSession.c2s_CmdTeamInvite(item.CharacterId);
|
||||
}
|
||||
|
||||
/// <summary>Invite by name/ID in input field. Public so you can assign to Button.onClick in Inspector.</summary>
|
||||
public void OnInvite()
|
||||
{
|
||||
CECHostPlayer host = GetHostPlayer();
|
||||
if (host == null) return;
|
||||
|
||||
int idPlayer = ResolveInviteTarget();
|
||||
if (idPlayer <= 0) return;
|
||||
UnityGameSession.c2s_CmdTeamInvite(idPlayer);
|
||||
}
|
||||
|
||||
private int ResolveInviteTarget()
|
||||
{
|
||||
if (m_pInput_Name == null || string.IsNullOrWhiteSpace(m_pInput_Name.text)) return 0;
|
||||
string raw = m_pInput_Name.text.Trim();
|
||||
if (int.TryParse(raw, out int id) && id > 0) return id;
|
||||
var manPlayer = EC_ManMessageMono.Instance?.GetECManPlayer;
|
||||
if (manPlayer == null) return 0;
|
||||
var otherIds = manPlayer.GetOtherPlayerCharacterIds();
|
||||
foreach (int cid in otherIds)
|
||||
{
|
||||
var p = manPlayer.GetPlayer(cid, 0);
|
||||
string name = p?.GetName();
|
||||
if (!string.IsNullOrEmpty(name) && string.Equals(name, raw, System.StringComparison.OrdinalIgnoreCase))
|
||||
return cid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>Kick selected teammate. Public so you can assign to Button.onClick in Inspector.</summary>
|
||||
public void OnKick()
|
||||
{
|
||||
int idMember = GetSelectedTeammateId();
|
||||
if (idMember <= 0)
|
||||
{
|
||||
Debug.Log("[DlgArrangeTeam] Kick: select a teammate first (click a row in the list).");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"[DlgArrangeTeam] Kick member id={idMember}");
|
||||
UnityGameSession.c2s_CmdTeamKickMember(idMember);
|
||||
}
|
||||
|
||||
/// <summary>Leave team. Public so you can assign to Button.onClick in Inspector.</summary>
|
||||
public void OnLeave()
|
||||
{
|
||||
if (UnityGameSession.Instance == null)
|
||||
{
|
||||
Debug.LogWarning("[DlgArrangeTeam] OnLeave: UnityGameSession.Instance is null. Cannot send leave command.");
|
||||
return;
|
||||
}
|
||||
Debug.Log("[DlgArrangeTeam] Leave team");
|
||||
UnityGameSession.c2s_CmdTeamLeaveParty();
|
||||
Show(false);
|
||||
}
|
||||
|
||||
/// <summary>Disband team (leader). Uses C2S TEAM_DISMISS_PARTY, not leave.</summary>
|
||||
public void OnDisband()
|
||||
{
|
||||
if (UnityGameSession.Instance == null)
|
||||
{
|
||||
Debug.LogWarning("[DlgArrangeTeam] OnDisband: UnityGameSession.Instance is null. Cannot send disband command.");
|
||||
return;
|
||||
}
|
||||
Debug.Log("[DlgArrangeTeam] Disband team");
|
||||
UnityGameSession.c2s_CmdTeamDismissParty();
|
||||
Show(false);
|
||||
}
|
||||
|
||||
/// <summary>Make selected member leader. Public so you can assign to Button.onClick in Inspector.</summary>
|
||||
public void OnMakeLeader()
|
||||
{
|
||||
int idMember = GetSelectedTeammateId();
|
||||
if (idMember <= 0)
|
||||
{
|
||||
Debug.Log("[DlgArrangeTeam] Make leader: select a teammate first (click a row in the list).");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"[DlgArrangeTeam] Make leader id={idMember}");
|
||||
UnityGameSession.c2s_CmdTeamChangeLeader(idMember);
|
||||
}
|
||||
|
||||
/// <summary>Refresh teammate and nearby lists. Public so you can assign to Button.onClick in Inspector.</summary>
|
||||
public void OnRefresh()
|
||||
{
|
||||
UpdateTeam(true);
|
||||
}
|
||||
|
||||
private void OnPickupModeChanged(short mode)
|
||||
{
|
||||
UnityGameSession.c2s_CmdTeamSetPickupFlag(mode);
|
||||
}
|
||||
|
||||
private int GetSelectedTeammateId()
|
||||
{
|
||||
return m_selectedTeammateId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52c15f7b28624ef4697b1f7eb3a0d17c
|
||||
Reference in New Issue
Block a user