This commit is contained in:
kawagiri 2026-05-24 11:37:33 +08:00
parent 57abeb5c05
commit bee4e7d48f
22 changed files with 22607 additions and 21437 deletions

View File

@ -1,5 +1,5 @@
{
"nextId": 258,
"nextId": 263,
"bugs": [
{
"id": 2,
@ -2550,6 +2550,56 @@
"module": "",
"createdAt": 1779506906721,
"updatedAt": 1779506906721
},
{
"id": 258,
"title": "我联机打的时候楼陀罗火车打守矢的那个大白蛇会有bug",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779523517289,
"updatedAt": 1779523517289
},
{
"id": 259,
"title": "所有巨人单位应该是LV6以上升级可选",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779537607662,
"updatedAt": 1779537607662
},
{
"id": 260,
"title": "间谍攻城的时候城里也有间谍怎么办?",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779538468082,
"updatedAt": 1779538468082
},
{
"id": 261,
"title": "玩其他游戏时好像邀请不了",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779539073924,
"updatedAt": 1779539073924
},
{
"id": 262,
"title": "话说什么时候恋升级不可视 升个级还能被人看到(",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779539151076,
"updatedAt": 1779539151076
}
]
}

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,11 @@ MonoBehaviour:
OutsideMultiplayIncludeAIPlayerHint: "(\u5305\u542BAI\u73A9\u5BB6)"
OutsideMultiplayNoRoomHint: "\u6682\u65E0\u8054\u673A\u623F\u95F4"
OutsideMultiplayRoomNameSuffix: "\u7684\u623F\u95F4"
OutsideMultiplayTeamTitle: "\u961F\u4F0D"
OutsideMultiplayAIPlayerTitle: "AI\u73A9\u5BB6"
OutsideMultiplayOpenTitle: "\u5F85\u52A0\u5165"
OutsideMultiplayReadyTitle: "\u5DF2\u51C6\u5907"
OutsideMultiplayOpenHint: "\u73A9\u5BB6\u5E2D\u4F4D\u672A\u6EE1\uFF0C\u8BF7\u8C03\u6574\u5E2D\u4F4D"
OutsideHistoryDropListNoLimitP: "\u4E0D\u9650"
OutsideHistoryDropList2P: "2\u4EBA"
OutsideHistoryDropList3P: "3\u4EBA"

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,136 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3ebbbbba88fe43409c16e83b934b878c, type: 3}
m_Name: NetworkPlayerTipDataAssets
m_EditorClassIdentifier:
DefaultCooldownSeconds: 3
NetworkPlayerTipInfoList:
- TipType: 1
Title: 20000
Message: 20001
CooldownSeconds: 5
- TipType: 2
Title: 20002
Message: 20003
CooldownSeconds: 5
- TipType: 3
Title: 20004
Message: 20005
CooldownSeconds: 10
- TipType: 4
Title: 20006
Message: 20007
CooldownSeconds: 5
- TipType: 5
Title: 20008
Message: 20009
CooldownSeconds: 3
- TipType: 6
Title: 20010
Message: 20011
CooldownSeconds: 3
- TipType: 7
Title: 20012
Message: 20013
CooldownSeconds: 2
- TipType: 8
Title: 20014
Message: 20015
CooldownSeconds: 2
- TipType: 9
Title: 20016
Message: 20017
CooldownSeconds: 3
- TipType: 10
Title: 20018
Message: 20019
CooldownSeconds: 3
- TipType: 11
Title: 20020
Message: 20021
CooldownSeconds: 5
- TipType: 12
Title: 20022
Message: 20023
CooldownSeconds: 3
- TipType: 13
Title: 20024
Message: 20025
CooldownSeconds: 5
- TipType: 14
Title: 20026
Message: 20027
CooldownSeconds: 3
- TipType: 15
Title: 20028
Message: 20029
CooldownSeconds: 3
- TipType: 16
Title: 20030
Message: 20031
CooldownSeconds: 5
- TipType: 17
Title: 20032
Message: 20033
CooldownSeconds: 3
- TipType: 18
Title: 20034
Message: 20035
CooldownSeconds: 5
- TipType: 19
Title: 20036
Message: 20037
CooldownSeconds: 5
- TipType: 20
Title: 20038
Message: 20039
CooldownSeconds: 5
- TipType: 21
Title: 20040
Message: 20041
CooldownSeconds: 3
- TipType: 22
Title: 20042
Message: 20043
CooldownSeconds: 5
- TipType: 23
Title: 20044
Message: 20045
CooldownSeconds: 5
- TipType: 24
Title: 20046
Message: 20047
CooldownSeconds: 5
- TipType: 25
Title: 20048
Message: 20049
CooldownSeconds: 5
- TipType: 26
Title: 20050
Message: 20051
CooldownSeconds: 3
- TipType: 27
Title: 20052
Message: 20053
CooldownSeconds: 3
- TipType: 28
Title: 20054
Message: 20055
CooldownSeconds: 2
- TipType: 29
Title: 20056
Message: 20057
CooldownSeconds: 3
- TipType: 30
Title: 20058
Message: 20059
CooldownSeconds: 5

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e8a9f8a49839186478275813e5fe3dc1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -32,6 +32,11 @@ MonoBehaviour:
OutsideMultiplayIncludeAIPlayerHint: 2405
OutsideMultiplayNoRoomHint: 17453
OutsideMultiplayRoomNameSuffix: 17705
OutsideMultiplayTeamTitle:
OutsideMultiplayAIPlayerTitle:
OutsideMultiplayOpenTitle:
OutsideMultiplayReadyTitle:
OutsideMultiplayOpenHint:
OutsideHistoryDropListNoLimitP: 17352
OutsideHistoryDropList2P: 17353
OutsideHistoryDropList3P: 17354

View File

@ -3404,7 +3404,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 147, y: -23}
m_SizeDelta: {x: 120.01, y: 32.0265}
m_SizeDelta: {x: 0, y: 32.0265}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5182836495056545005
CanvasRenderer:
@ -4348,7 +4348,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 250, y: -550.093}
m_AnchoredPosition: {x: 250, y: -480.093}
m_SizeDelta: {x: 500, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &4676610239985244751
@ -5247,7 +5247,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 250, y: -785.093}
m_AnchoredPosition: {x: 250, y: -550.093}
m_SizeDelta: {x: 500, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1555931548957767936

View File

@ -1587,7 +1587,7 @@ MonoBehaviour:
NoExport: 0
FontBan: 0
Preset: 0
ID: 1401
ID: 19977
FontID: 1
TextCfg:
- Type: 1

View File

@ -828,6 +828,7 @@ GameObject:
- component: {fileID: 4071889833013536115}
- component: {fileID: 3511343210454506103}
- component: {fileID: 7865469868100666246}
- component: {fileID: 8973491618798335770}
m_Layer: 5
m_Name: Placeholder
m_TagString: Untagged
@ -971,6 +972,25 @@ MonoBehaviour:
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &8973491618798335770
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4045480400424864957}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6b27f832d22e4a8d916272b644937774, type: 3}
m_Name:
m_EditorClassIdentifier:
Ban: 0
NoExport: 0
FontBan: 0
Preset: 0
ID: 19647
FontID: 0
TextCfg: []
--- !u!1 &5471446911446404968
GameObject:
m_ObjectHideFlags: 0
@ -1617,7 +1637,7 @@ MonoBehaviour:
NoExport: 0
FontBan: 0
Preset: 0
ID: 17557
ID: 19999
FontID: 1
TextCfg:
- Type: 1
@ -2758,6 +2778,7 @@ GameObject:
- component: {fileID: 334792629644883303}
- component: {fileID: 4652138525967637174}
- component: {fileID: 8169390067649257082}
- component: {fileID: 9058535840347886198}
m_Layer: 5
m_Name: RoomName
m_TagString: Untagged
@ -2881,6 +2902,25 @@ MonoBehaviour:
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &9058535840347886198
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8171858811077351841}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6b27f832d22e4a8d916272b644937774, type: 3}
m_Name:
m_EditorClassIdentifier:
Ban: 0
NoExport: 0
FontBan: 0
Preset: 0
ID: 19979
FontID: 0
TextCfg: []
--- !u!1 &8438381095895913330
GameObject:
m_ObjectHideFlags: 0

View File

@ -86,9 +86,8 @@ GameObject:
- component: {fileID: 2438225421395076648}
- component: {fileID: 591212338599555894}
- component: {fileID: 7030574526118729750}
- component: {fileID: 959187344526487202}
m_Layer: 5
m_Name: UIOutsideMultiplayRoomMemberButtonRow
m_Name: UIOutsideMultiplayRoomMemberLineRow
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@ -152,23 +151,3 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1.25
--- !u!114 &959187344526487202
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7377647467463133788}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: b944c6e03ad742440a76463c2ecf000a, type: 3}
m_Name:
m_EditorClassIdentifier:
AvatarImage: {fileID: 0}
LeaderImage: {fileID: 0}
NameText: {fileID: 0}
StatusText: {fileID: 0}
ForcesText: {fileID: 0}
ForcesButton: {fileID: 0}
RefreshButton: {fileID: 0}
QuitButton: {fileID: 0}

View File

@ -1935,7 +1935,7 @@ MonoBehaviour:
NoExport: 0
FontBan: 0
Preset: 0
ID: 1635
ID: 19995
FontID: 2
TextCfg:
- Type: 1
@ -2505,7 +2505,7 @@ MonoBehaviour:
NoExport: 0
FontBan: 0
Preset: 0
ID: 2225
ID: 2231
FontID: 1
TextCfg:
- Type: 1
@ -3192,3 +3192,8 @@ MonoBehaviour:
ForcesButton: {fileID: 8612292243586636816}
RefreshButton: {fileID: 8612292243586636816}
QuitButton: {fileID: 8717023295481533829}
ForceLeftButton: {fileID: 8612292243586636816}
ForceRightButton: {fileID: 6556385597021353403}
TeamText: {fileID: 3332880645268972119}
TeamLeftButton: {fileID: 8962252367205184452}
TeamRightButton: {fileID: 2906850645216239320}

View File

@ -38,6 +38,9 @@ public class TextDataAssets : ScriptableObject
[MultilingualField]public string OutsideMultiplayRoomNameSuffix;
[MultilingualField]public string OutsideMultiplayTeamTitle;
[MultilingualField]public string OutsideMultiplayAIPlayerTitle;
[MultilingualField]public string OutsideMultiplayOpenTitle;
[MultilingualField]public string OutsideMultiplayReadyTitle;
[MultilingualField]public string OutsideMultiplayOpenHint;
[MultilingualField]public string OutsideHistoryDropListNoLimitP;
[MultilingualField]public string OutsideHistoryDropList2P;

View File

@ -1,5 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using System;
using Logic.Multilingual;
using RuntimeData;
using TH1_Logic.Core;
@ -17,84 +16,118 @@ public class UIOutsideMultiplayMemberRowMono : MonoBehaviour
public TextMeshProUGUI NameText;
public TextMeshProUGUI StatusText;
public TextMeshProUGUI ForcesText;
//public TextMeshProUGUI CivButtonText;
//public Button CivButton;
public Button ForcesButton;
public Button RefreshButton;
public Button QuitButton;
public Button ForceLeftButton;
public Button ForceRightButton;
public TextMeshProUGUI TeamText;
public Button TeamLeftButton;
public Button TeamRightButton;
private SteamLobbyManager _lobby;
// Start is called before the first frame update
private CivEnum _civ;
private ForceEnum _force;
private int _teamId;
private int _maxTeamId;
private string _forceNameOverride;
private Action<int> _onForceChanged;
private Action<int> _onTeamChanged;
private static readonly (CivEnum Civ, ForceEnum Force)[] ForceOptions =
{
(CivEnum.Egyptian, ForceEnum.Remilia),
(CivEnum.French, ForceEnum.Kaguya),
(CivEnum.Germany, ForceEnum.Kanako),
(CivEnum.Indian, ForceEnum.Satori),
};
public bool CheckParam()
{
return AvatarImage != null && NameText != null &&
ForcesText != null && StatusText != null; // && CivButton != null && ForcesButton != null;*/
ForcesText != null && StatusText != null;
}
public void SetContent(MemberInfo info,string status,CivEnum civ,SteamLobbyManager lobby, string forceNameOverride = null)
public void SetContent(MemberInfo info, string status, CivEnum civ, SteamLobbyManager lobby, string forceNameOverride = null)
{
SetHumanContent(info, status, civ, GetDefaultForce(civ), 1, 1, lobby, true, forceNameOverride, null, null);
}
public void SetHumanContent(
MemberInfo info,
string status,
CivEnum civ,
ForceEnum force,
int teamId,
int maxTeamId,
SteamLobbyManager lobby,
bool canEdit,
string forceNameOverride,
Action<int> onForceChanged,
Action<int> onTeamChanged)
{
if (!CheckParam()) return;
_forceNameOverride = forceNameOverride;
NameText.text = info.Name;
var texture = info.Texture;
ResetButtons();
_lobby = lobby;
if(lobby.GetLobbyOwnerId() == info.Id)
MultilingualManager.Instance.SetUIText(StatusText,Table.Instance.TextDataAssets.MultiplayRoomOwnerTitle);
else
MultilingualManager.Instance.SetUIText(StatusText,Table.Instance.TextDataAssets.MultiplayRoomGuestTitle);
if (texture != null)
{
// 使用整个纹理区域创建一个矩形
Rect rect = new Rect(0, 0, texture.width, texture.height);
// 创建Sprite轴心点在中心
Vector2 pivot = new Vector2(0.5f, 0.5f);
_forceNameOverride = forceNameOverride;
_teamId = Mathf.Max(1, teamId);
_maxTeamId = Mathf.Max(1, maxTeamId);
_onForceChanged = onForceChanged;
_onTeamChanged = onTeamChanged;
// Sprite.Create(源纹理, 纹理内的矩形区域, 轴心点)
AvatarImage.sprite = Sprite.Create(texture, rect, pivot);
AvatarImage.rectTransform.localScale = new Vector3(1, -1, 1);
}
ForcesButton.onClick.RemoveAllListeners();
RefreshButton.gameObject.SetActive(false);
if (info.Id == lobby.GetSelfMemberId())
{
ForcesButton?.onClick.AddListener(OnClickForces);
RefreshButton.gameObject.SetActive(true);
}
// 踢人按钮:仅"自己是房主 + 该行不是自己"时显示并绑定,否则隐藏
if (QuitButton != null)
{
QuitButton.onClick.RemoveAllListeners();
bool selfIsOwner = lobby.GetLobbyOwnerId() == lobby.GetSelfMemberId();
bool rowIsSelf = info.Id == lobby.GetSelfMemberId();
bool showQuit = selfIsOwner && !rowIsSelf;
QuitButton.gameObject.SetActive(showQuit);
if (showQuit)
{
// 闭包捕获本地变量,避免行复用时把上一行的 memberId 带进来
var targetMemberId = info.Id;
QuitButton.onClick.AddListener(() => lobby.KickMember(targetMemberId));
}
}
ForceEnum force = civ switch
{
CivEnum.Egyptian => ForceEnum.Remilia,
CivEnum.French => ForceEnum.Kaguya,
CivEnum.Germany => ForceEnum.Kanako,
CivEnum.Indian => ForceEnum.Satori,
_ => ForceEnum.Kanako
};
SetAvatarVisible(true);
NameText.text = info.Name;
SetAvatar(info.Texture);
UpdatePlayerInfoView(civ, force);
MultilingualManager.Instance.SetUIText(StatusText, status);
SetStatus(status);
SetTeamText(_teamId);
SetEditButtonsVisible(canEdit);
BindEditButtons(canEdit);
BindQuitButton(info, lobby);
}
public void UpdatePlayerInfoView(CivEnum civ,ForceEnum force)
public void SetOpenContent()
{
if (!CheckParam()) return;
ResetButtons();
SetAvatarVisible(false);
MultilingualManager.Instance.SetUIText(NameText, Table.Instance.TextDataAssets.OutsideMultiplayOpenTitle);
StatusText.text = string.Empty;
ForcesText.text = string.Empty;
SetTeamText(0);
SetEditButtonsVisible(false);
if (QuitButton != null) QuitButton.gameObject.SetActive(false);
}
public void SetAIContent(
CivEnum civ,
ForceEnum force,
int teamId,
int maxTeamId,
bool canEdit,
string forceNameOverride,
Action<int> onForceChanged,
Action<int> onTeamChanged)
{
if (!CheckParam()) return;
ResetButtons();
_forceNameOverride = forceNameOverride;
_teamId = Mathf.Max(1, teamId);
_maxTeamId = Mathf.Max(1, maxTeamId);
_onForceChanged = onForceChanged;
_onTeamChanged = onTeamChanged;
SetAvatarVisible(false);
MultilingualManager.Instance.SetUIText(NameText, Table.Instance.TextDataAssets.OutsideMultiplayAIPlayerTitle);
StatusText.text = string.Empty;
UpdatePlayerInfoView(civ, force);
SetTeamText(_teamId);
SetEditButtonsVisible(canEdit);
BindEditButtons(canEdit);
if (QuitButton != null) QuitButton.gameObject.SetActive(false);
}
public void UpdatePlayerInfoView(CivEnum civ, ForceEnum force)
{
_civ = civ;
_force = force;
@ -102,19 +135,11 @@ public class UIOutsideMultiplayMemberRowMono : MonoBehaviour
if (!string.IsNullOrEmpty(_forceNameOverride))
ForcesText.text = _forceNameOverride;
else
MultilingualManager.Instance.SetUIText(ForcesText,playerInfo.ForceName);
LeaderImage.sprite = playerInfo.LeaderIllustration;
//MultilingualManager.Instance.SetUIText(CivButtonText,playerInfo.CivName);
//设置按钮颜色(和阵营一致)
//if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(_civ, _force, out var info)) return;
//var civButtonSprite = CivButton?.GetComponent<Image>();
var forceButtonSprite = ForcesButton?.GetComponent<Image>();
//if (civButtonSprite != null) civButtonSprite.color = info.Color;
//if (forceButtonSprite != null) forceButtonSprite.color = info.Color;
MultilingualManager.Instance.SetUIText(ForcesText, playerInfo.ForceName);
if (LeaderImage != null) LeaderImage.sprite = playerInfo.LeaderIllustration;
}
public bool UpdatePlayerInfoData(CivEnum civ,ForceEnum force)
public bool UpdatePlayerInfoData(CivEnum civ, ForceEnum force)
{
var accepted = Main.Instance.MapConfig.UpdateSelfMemberCiv(
Table.Instance.TransCivEnumToCivId(civ),
@ -125,38 +150,131 @@ public class UIOutsideMultiplayMemberRowMono : MonoBehaviour
public void OnClickForces()
{
// 切换阵营时清掉旧的覆盖文本,避免在服务端 UpdateUIOutsideMultiplayRoomSetting 回流前
// 本地 UI 残留上一阵营的 "xx nP" 字样;最终 nP 是否需要由 View 重画时统一计算。
ChangeForce(1);
}
private void ResetButtons()
{
ForcesButton?.onClick.RemoveAllListeners();
RefreshButton?.onClick.RemoveAllListeners();
QuitButton?.onClick.RemoveAllListeners();
ForceLeftButton?.onClick.RemoveAllListeners();
ForceRightButton?.onClick.RemoveAllListeners();
TeamLeftButton?.onClick.RemoveAllListeners();
TeamRightButton?.onClick.RemoveAllListeners();
}
private void SetAvatar(Texture2D texture)
{
if (AvatarImage == null || texture == null) return;
var rect = new Rect(0, 0, texture.width, texture.height);
var pivot = new Vector2(0.5f, 0.5f);
AvatarImage.sprite = Sprite.Create(texture, rect, pivot);
AvatarImage.rectTransform.localScale = new Vector3(1, -1, 1);
}
private void SetAvatarVisible(bool visible)
{
if (AvatarImage != null) AvatarImage.gameObject.SetActive(visible);
if (LeaderImage != null) LeaderImage.gameObject.SetActive(visible);
}
private void SetStatus(string status)
{
if (string.IsNullOrEmpty(status))
{
StatusText.text = string.Empty;
return;
}
MultilingualManager.Instance.SetUIText(StatusText, status);
}
private void SetTeamText(int teamId)
{
if (TeamText == null) return;
if (teamId <= 0)
{
TeamText.text = string.Empty;
return;
}
var title = MultilingualManager.Instance.GetMultilingualText(Table.Instance.TextDataAssets.OutsideMultiplayTeamTitle);
TeamText.text = $"{title}{teamId}";
}
private void SetEditButtonsVisible(bool visible)
{
if (ForcesButton != null) ForcesButton.gameObject.SetActive(visible);
if (RefreshButton != null && RefreshButton != ForcesButton) RefreshButton.gameObject.SetActive(visible);
if (ForceLeftButton != null) ForceLeftButton.gameObject.SetActive(visible);
if (ForceRightButton != null) ForceRightButton.gameObject.SetActive(visible);
if (TeamLeftButton != null) TeamLeftButton.gameObject.SetActive(visible);
if (TeamRightButton != null) TeamRightButton.gameObject.SetActive(visible);
if (TeamText != null) TeamText.gameObject.SetActive(visible || !string.IsNullOrEmpty(TeamText.text));
if (ForcesText != null) ForcesText.gameObject.SetActive(visible || !string.IsNullOrEmpty(ForcesText.text));
}
private void BindEditButtons(bool canEdit)
{
if (!canEdit) return;
if (ForceLeftButton != null) ForceLeftButton.onClick.AddListener(() => ChangeForce(-1));
if (ForceRightButton != null) ForceRightButton.onClick.AddListener(() => ChangeForce(1));
if (ForcesButton != null && ForceLeftButton == null && ForceRightButton == null) ForcesButton.onClick.AddListener(OnClickForces);
if (TeamLeftButton != null) TeamLeftButton.onClick.AddListener(() => ChangeTeam(-1));
if (TeamRightButton != null) TeamRightButton.onClick.AddListener(() => ChangeTeam(1));
}
private void BindQuitButton(MemberInfo info, SteamLobbyManager lobby)
{
if (QuitButton == null) return;
bool selfIsOwner = lobby.GetLobbyOwnerId() == lobby.GetSelfMemberId();
bool rowIsSelf = info.Id == lobby.GetSelfMemberId();
bool showQuit = selfIsOwner && !rowIsSelf;
QuitButton.gameObject.SetActive(showQuit);
if (!showQuit) return;
var targetMemberId = info.Id;
QuitButton.onClick.AddListener(() => lobby.KickMember(targetMemberId));
}
private void ChangeForce(int direction)
{
_forceNameOverride = null;
if (_civ == CivEnum.Egyptian)
{
if (UpdatePlayerInfoData(CivEnum.French,ForceEnum.Kaguya))
UpdatePlayerInfoView(CivEnum.French,ForceEnum.Kaguya);
}
else if (_civ == CivEnum.French)
{
if (UpdatePlayerInfoData(CivEnum.Germany,ForceEnum.Kanako))
UpdatePlayerInfoView(CivEnum.Germany,ForceEnum.Kanako);
}
else if (_civ == CivEnum.Germany)
{
if (UpdatePlayerInfoData(CivEnum.Indian,ForceEnum.Satori))
UpdatePlayerInfoView(CivEnum.Indian,ForceEnum.Satori);
}
else if (_civ == CivEnum.Indian)
{
if (UpdatePlayerInfoData(CivEnum.Egyptian,ForceEnum.Remilia))
UpdatePlayerInfoView(CivEnum.Egyptian,ForceEnum.Remilia);
}
}
void Start()
{
int index = GetForceIndex(_civ, _force);
index = (index + direction + ForceOptions.Length) % ForceOptions.Length;
var next = ForceOptions[index];
_onForceChanged?.Invoke(direction);
UpdatePlayerInfoView(next.Civ, next.Force);
}
// Update is called once per frame
void Update()
private void ChangeTeam(int direction)
{
_teamId += direction;
if (_teamId < 1) _teamId = _maxTeamId;
if (_teamId > _maxTeamId) _teamId = 1;
_onTeamChanged?.Invoke(direction);
SetTeamText(_teamId);
}
private static int GetForceIndex(CivEnum civ, ForceEnum force)
{
for (int i = 0; i < ForceOptions.Length; i++)
{
if (ForceOptions[i].Civ == civ && ForceOptions[i].Force == force) return i;
}
return 0;
}
private static ForceEnum GetDefaultForce(CivEnum civ)
{
return civ switch
{
CivEnum.Egyptian => ForceEnum.Remilia,
CivEnum.French => ForceEnum.Kaguya,
CivEnum.Germany => ForceEnum.Kanako,
CivEnum.Indian => ForceEnum.Satori,
_ => ForceEnum.Kanako
};
}
}

View File

@ -31,6 +31,8 @@ namespace TH1_UI.View.Outside
public Button CreateRoomButton;
public Button LeaveRoomButton;
public Button StartGameButton;
public Button ReadyButton;
public Button CancelReadyButton;
public Toggle ResumeToggle;
[Header("相关提示对象")]
@ -61,6 +63,7 @@ namespace TH1_UI.View.Outside
public GameObject FriendList;
public GameObject MemberRowPrefab;
public GameObject MemberLineRowPrefab;
public GameObject MemberList;
[Header("联机大厅")]
@ -82,9 +85,13 @@ namespace TH1_UI.View.Outside
private List<UIOutsideMultiplayFriendRowMono> _friendRowList;
private List<UIOutsideMultiplayMemberRowMono> _memberRowList;
private List<GameObject> _memberLineRowList;
private List<RoomMemberRowData> _roomMemberRows;
private List<UIOutsideMultiplayLobbyRowMono> _lobbyRowList;
private SteamLobbyManager _lobby;
private int _roomSeatCount = 4;
private int _openMemberRowCount = 0;
//关闭时执行的委托
public ViDelegateAssisstant.Dele OnBtnCloseClick;
@ -101,6 +108,30 @@ namespace TH1_UI.View.Outside
private bool _isSearchingLobby = false;
private bool _hasLobbySearchResult = false;
private enum RoomMemberRowType
{
Human,
Open,
Line,
AI
}
private class RoomMemberRowData
{
public RoomMemberRowType Type;
public MemberCiv MemberCiv;
public MemberInfo MemberInfo;
public int SlotIndex;
}
private static readonly (CivEnum Civ, ForceEnum Force)[] RoomForceOptions =
{
(CivEnum.Egyptian, ForceEnum.Remilia),
(CivEnum.French, ForceEnum.Kaguya),
(CivEnum.Germany, ForceEnum.Kanako),
(CivEnum.Indian, ForceEnum.Satori),
};
protected override void OnInit()
{
base.OnInit();
@ -139,8 +170,24 @@ namespace TH1_UI.View.Outside
LeaveRoomButton.onClick.RemoveAllListeners();
LeaveRoomButton.onClick.AddListener(LeaveRoom);
if (ReadyButton != null)
{
SetButtonText(ReadyButton, MultilingualManager.Instance.GetMultilingualText(Table.Instance.TextDataAssets.OutsideMultiplayReadyTitle));
ReadyButton.onClick.RemoveAllListeners();
ReadyButton.onClick.AddListener(() => SetSelfReadyState(true));
}
if (CancelReadyButton != null)
{
SetButtonText(CancelReadyButton, "取消准备");
CancelReadyButton.onClick.RemoveAllListeners();
CancelReadyButton.onClick.AddListener(() => SetSelfReadyState(false));
}
_friendRowList = new List<UIOutsideMultiplayFriendRowMono>();
_memberRowList = new List<UIOutsideMultiplayMemberRowMono>();
_memberLineRowList = new List<GameObject>();
_roomMemberRows = new List<RoomMemberRowData>();
_lobbyRowList = new List<UIOutsideMultiplayLobbyRowMono>();
_lobby = LobbyManager.Instance.Lobby as SteamLobbyManager;
@ -292,7 +339,6 @@ namespace TH1_UI.View.Outside
private void SetRoomInfoMember()
{
//显示房间区域,隐藏联机大厅
RoomArea?.SetActive(true);
HallArea?.SetActive(false);
@ -305,107 +351,351 @@ namespace TH1_UI.View.Outside
CreateRoomButton.gameObject.SetActive(false);
NoRoomHint.gameObject.SetActive(false);
var memberList = _lobby.GetAllMemberInfo();
Main.Instance.MapConfig.EnsurePlayerSlots(NetMode.Multi);
ReconcileRoomMembers();
var multiCivs = Main.Instance.MapConfig.MultiCivs;
// 按 MultiCivs 顺序渲染(与游戏内 PlayerDataList 中真人玩家顺序一致),
// 这样大厅显示的全局位置与进入游戏后的 nP 编号对齐。
// 不在 memberList 中的 MultiCiv 视为离线,跳过。
var orderedMemberCivs = new List<MemberCiv>();
foreach (var mc in multiCivs)
BuildRoomMemberRows(memberList, multiCivs);
RenderRoomMemberRows(multiCivs);
RefreshRoomButtons();
}
private void BuildRoomMemberRows(Dictionary<ulong, MemberInfo> memberList, List<MemberCiv> multiCivs)
{
_roomMemberRows.Clear();
var humanRows = new List<RoomMemberRowData>();
var emptyAiRows = new List<RoomMemberRowData>();
for (int i = 0; i < multiCivs.Count; i++)
{
if (memberList.ContainsKey(mc.MemberId)) orderedMemberCivs.Add(mc);
var mc = multiCivs[i];
if (mc == null) continue;
if (mc.MemberId != 0 && memberList.TryGetValue(mc.MemberId, out var info))
{
humanRows.Add(new RoomMemberRowData { Type = RoomMemberRowType.Human, MemberCiv = mc, MemberInfo = info, SlotIndex = i });
}
else if (mc.MemberId == 0 && mc.IsAI)
{
emptyAiRows.Add(new RoomMemberRowData { Type = RoomMemberRowType.AI, MemberCiv = mc, SlotIndex = i });
}
}
//如果目前的list内对象不够补足
while (_memberRowList.Count < orderedMemberCivs.Count)
{
var item = Instantiate(MemberRowPrefab,MemberList.transform);
//item.transform.localPosition = Vector3.zero;
var cpn = item.GetComponent<UIOutsideMultiplayMemberRowMono>();
_memberRowList.Add(cpn);
}
for (int i = 0; i < _memberRowList.Count; i++)
_memberRowList[i].gameObject.SetActive(i < orderedMemberCivs.Count);
int totalPlayerCount = Mathf.Max(0, (int)Main.Instance.MapConfig.PlayerCount);
int roomSeatCount = Mathf.Clamp(_roomSeatCount, humanRows.Count, totalPlayerCount);
_openMemberRowCount = Mathf.Max(0, roomSeatCount - humanRows.Count);
int aiCount = Mathf.Max(0, totalPlayerCount - roomSeatCount);
// 统计每个"显示用 (CivEnum,ForceEnum)"在成员中的出现次数;
// 仅当 ≥2 时该位置的成员需要显示 nP 后缀。
// 注意CivId==0 表示玩家尚未主动选择阵营,但 TransCivIdToCivEnum(0) 会兜底到默认阵营,
// 显示上仍然会落到一个真实阵营(通常是埃及/Remilia因此必须按"显示阵营"统计才能与玩家
// 在 UI 上看到的重复情况一致——直接用 raw CivId 跳过 0 会漏掉"两个人都没选、显示同一默认阵营"的场景。
_roomMemberRows.AddRange(humanRows);
for (int i = 0; i < _openMemberRowCount; i++)
_roomMemberRows.Add(new RoomMemberRowData { Type = RoomMemberRowType.Open });
_roomMemberRows.Add(new RoomMemberRowData { Type = RoomMemberRowType.Line });
int aiStart = Mathf.Max(0, emptyAiRows.Count - aiCount);
for (int i = aiStart; i < emptyAiRows.Count; i++)
_roomMemberRows.Add(emptyAiRows[i]);
}
private void RenderRoomMemberRows(List<MemberCiv> multiCivs)
{
var sameCountDict = BuildForceSameCountDict(_roomMemberRows);
int memberRowIndex = 0;
int lineRowIndex = 0;
for (int i = 0; i < _roomMemberRows.Count; i++)
{
var row = _roomMemberRows[i];
if (row.Type == RoomMemberRowType.Line)
{
var line = GetLineRow(lineRowIndex++);
if (line != null) line.transform.SetSiblingIndex(i);
continue;
}
var memberRow = GetMemberRow(memberRowIndex++);
if (memberRow == null) continue;
memberRow.transform.SetSiblingIndex(i);
RenderMemberRow(memberRow, row, multiCivs, sameCountDict);
}
for (int i = memberRowIndex; i < _memberRowList.Count; i++)
_memberRowList[i].gameObject.SetActive(false);
for (int i = lineRowIndex; i < _memberLineRowList.Count; i++)
_memberLineRowList[i].SetActive(false);
}
private Dictionary<(CivEnum, ForceEnum), int> BuildForceSameCountDict(List<RoomMemberRowData> rows)
{
var sameCountDict = new Dictionary<(CivEnum, ForceEnum), int>();
foreach (var mc in orderedMemberCivs)
foreach (var row in rows)
{
var dispCiv = Table.Instance.TransCivIdToCivEnum(mc.CivId);
var dispForce = Table.Instance.TransForceIdToForceEnum(mc.ForceId);
if (row.MemberCiv == null || row.Type == RoomMemberRowType.Open || row.Type == RoomMemberRowType.Line) continue;
var dispCiv = Table.Instance.TransCivIdToCivEnum(row.MemberCiv.CivId);
var dispForce = Table.Instance.TransForceIdToForceEnum(row.MemberCiv.ForceId);
var key = (dispCiv, dispForce);
sameCountDict.TryGetValue(key, out var prevCnt);
sameCountDict[key] = prevCnt + 1;
}
//设置真人玩家行
for (int idx = 0; idx < orderedMemberCivs.Count; idx++)
return sameCountDict;
}
private void RenderMemberRow(UIOutsideMultiplayMemberRowMono memberRow, RoomMemberRowData row, List<MemberCiv> multiCivs, Dictionary<(CivEnum, ForceEnum), int> sameCountDict)
{
memberRow.gameObject.SetActive(true);
if (row.Type == RoomMemberRowType.Open)
{
var mc = orderedMemberCivs[idx];
var info = memberList[mc.MemberId];
var status = _lobby.GetLobbyOwnerId() == mc.MemberId
? Table.Instance.TextDataAssets.OutsideMultiplayTitleHost
: Table.Instance.TextDataAssets.OutsideMultiplayTitleGuest;
var civ = Table.Instance.TransCivIdToCivEnum(mc.CivId);
var force = Table.Instance.TransForceIdToForceEnum(mc.ForceId);
string forceNameOverride = null;
if (sameCountDict.TryGetValue((civ, force), out var sameCnt) && sameCnt >= 2)
{
if (Table.Instance.PlayerDataAssets.GetPlayerInfo(civ, force, out var pi))
{
var raw = MultilingualManager.Instance.GetMultilingualTextSafe(pi.ForceName);
// 全局位置 = 该成员在 PlayerDataList 中的 1-based index = MultiCivs 中的 1-based index
int globalIdx = multiCivs.IndexOf(mc) + 1;
forceNameOverride = $"{raw} {globalIdx}P";
}
}
_memberRowList[idx].SetContent(info, status, civ, _lobby, forceNameOverride);
memberRow.SetOpenContent();
return;
}
//Step #3 设置 是否继续上一个存档的toggle
var mc = row.MemberCiv;
var civ = Table.Instance.TransCivIdToCivEnum(mc.CivId);
var force = Table.Instance.TransForceIdToForceEnum(mc.ForceId);
var teamId = GetValidTeamId(mc);
var forceNameOverride = GetForceNameOverride(mc, civ, force, multiCivs, sameCountDict);
int maxTeamId = Mathf.Max(1, (int)Main.Instance.MapConfig.PlayerCount);
if (row.Type == RoomMemberRowType.AI)
{
memberRow.SetAIContent(civ, force, teamId, maxTeamId, _lobby.IsLobbyOwner(), forceNameOverride,
direction => OnAIRowForceChanged(row.SlotIndex, direction),
direction => OnAIRowTeamChanged(row.SlotIndex, direction));
return;
}
var status = GetHumanStatus(mc);
bool canEditHuman = mc.MemberId == _lobby.GetSelfMemberId();
memberRow.SetHumanContent(row.MemberInfo, status, civ, force, teamId, maxTeamId, _lobby, canEditHuman, forceNameOverride,
direction => OnHumanRowForceChanged(mc.Index, direction),
direction => OnHumanRowTeamChanged(mc.Index, direction));
}
private UIOutsideMultiplayMemberRowMono GetMemberRow(int index)
{
while (_memberRowList.Count <= index)
{
var item = Instantiate(MemberRowPrefab, MemberList.transform);
var cpn = item.GetComponent<UIOutsideMultiplayMemberRowMono>();
_memberRowList.Add(cpn);
}
return _memberRowList[index];
}
private GameObject GetLineRow(int index)
{
if (MemberLineRowPrefab == null) return null;
while (_memberLineRowList.Count <= index)
_memberLineRowList.Add(Instantiate(MemberLineRowPrefab, MemberList.transform));
var line = _memberLineRowList[index];
line.SetActive(true);
return line;
}
private string GetHumanStatus(MemberCiv mc)
{
if (mc.MemberId == _lobby.GetLobbyOwnerId()) return Table.Instance.TextDataAssets.OutsideMultiplayTitleHost;
return mc.IsReady ? Table.Instance.TextDataAssets.OutsideMultiplayReadyTitle : null;
}
private string GetForceNameOverride(MemberCiv mc, CivEnum civ, ForceEnum force, List<MemberCiv> multiCivs, Dictionary<(CivEnum, ForceEnum), int> sameCountDict)
{
if (!sameCountDict.TryGetValue((civ, force), out var sameCnt) || sameCnt < 2) return null;
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(civ, force, out var pi)) return null;
var raw = MultilingualManager.Instance.GetMultilingualTextSafe(pi.ForceName);
int globalIdx = multiCivs.IndexOf(mc) + 1;
return $"{raw} {globalIdx}P";
}
private void RefreshRoomButtons()
{
ResumeToggle.SetIsOnWithoutNotify(false);
ResumeToggle.interactable = false;
if (_lobby.IsLobbyOwner())
{
if(Main.Instance.HasMultiArchive())
ResumeToggle.interactable = true;
}
//Step #4 设置开始按钮
ResumeToggle.interactable = _lobby.IsLobbyOwner() && Main.Instance.HasMultiArchive();
StartGameButton.onClick.RemoveAllListeners();
StartGameButton.interactable = false;
StartGameButton.gameObject.SetActive(_lobby.IsLobbyOwner());
var img = StartGameButton.transform.Find("Color")?.GetComponent<Image>();
var c = (img != null)?img.color : Color.white;
var c = img != null ? img.color : Color.white;
c.a = 0.5f;
if (img != null) img.color = c;
if(_lobby.IsLobbyOwner())
if (_lobby.IsLobbyOwner())
{
var cpn = StartGameButton.GetComponent<ButtonHoverEffect>();
if(cpn != null) cpn.enabled = true;
if (cpn != null) cpn.enabled = true;
var simg = StartGameButton.GetComponent<Image>();
if (simg != null) simg.color = Color.white;
StartGameButton.interactable = true;
c.a = 1f;
if (img != null) img.color = c;
StartGameButton.onClick.AddListener(StartGame);
SetReadyButtonsVisible(false, false);
}
else
{
var cpn = StartGameButton.GetComponent<ButtonHoverEffect>();
if(cpn != null) cpn.enabled = false;
if (cpn != null) cpn.enabled = false;
var simg = StartGameButton.GetComponent<Image>();
if (simg != null) simg.color = new Color(0.5f,0.5f,0.5f,0.5f);
if (simg != null) simg.color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
bool isReady = Main.Instance.MapConfig.IsMemberReady(_lobby.GetSelfMemberId());
SetReadyButtonsVisible(!isReady, isReady);
}
}
private static void SetButtonText(Button button, string text)
{
var label = button.GetComponentInChildren<TextMeshProUGUI>(true);
if (label != null) label.text = text;
}
private void SetReadyButtonsVisible(bool showReady, bool showCancelReady)
{
if (ReadyButton != null) ReadyButton.gameObject.SetActive(showReady);
if (CancelReadyButton != null) CancelReadyButton.gameObject.SetActive(showCancelReady);
}
private void SetSelfReadyState(bool isReady)
{
if (Main.Instance.MapConfig.SetSelfReady(isReady))
{
Main.Instance.MapConfig.CheckMapConfigChanged();
RefreshRoomInfo();
}
}
private void ReconcileRoomMembers()
{
Main.Instance.MapConfig.SetPlayerCount(Main.Instance.MapConfig.PlayerCount, NetMode.Multi);
var multiCivs = Main.Instance.MapConfig.MultiCivs;
int totalPlayerCount = Mathf.Max(0, (int)Main.Instance.MapConfig.PlayerCount);
_roomSeatCount = Mathf.Clamp(_roomSeatCount, _lobby.GetMemberCount(), totalPlayerCount);
int lobbyMemberLimit = _lobby.GetMemberLimit();
if (lobbyMemberLimit > 0) _roomSeatCount = Mathf.Clamp(lobbyMemberLimit, _lobby.GetMemberCount(), totalPlayerCount);
var usedCivs = new HashSet<uint>();
var usedTeams = new HashSet<int>();
for (int i = 0; i < multiCivs.Count; i++)
{
var mc = multiCivs[i];
if (mc == null) continue;
if (mc.TeamId <= 0 || mc.TeamId > totalPlayerCount) mc.TeamId = PickDefaultTeamId(i, totalPlayerCount, usedTeams);
if (!mc.IsCivFixed)
{
var civId = PickDefaultCivId(i, usedCivs);
mc.CivId = civId;
mc.ForceId = civId;
mc.IsCivFixed = true;
}
usedTeams.Add(mc.TeamId);
usedCivs.Add(mc.CivId);
}
}
private int GetValidTeamId(MemberCiv mc)
{
int maxTeamId = Mathf.Max(1, (int)Main.Instance.MapConfig.PlayerCount);
if (mc.TeamId >= 1 && mc.TeamId <= maxTeamId) return mc.TeamId;
return Mathf.Clamp(mc.Index + 1, 1, maxTeamId);
}
private int PickDefaultTeamId(int preferredIndex, int maxTeamId, HashSet<int> usedTeams)
{
maxTeamId = Mathf.Max(1, maxTeamId);
for (int offset = 0; offset < maxTeamId; offset++)
{
int teamId = (preferredIndex + offset) % maxTeamId + 1;
if (!usedTeams.Contains(teamId)) return teamId;
}
return preferredIndex % maxTeamId + 1;
}
private uint PickDefaultCivId(int preferredIndex, HashSet<uint> usedCivs)
{
const int defaultCivCount = 17;
for (int offset = 0; offset < defaultCivCount; offset++)
{
var civId = (uint)((preferredIndex + offset) % defaultCivCount);
if (!usedCivs.Contains(civId)) return civId;
}
return (uint)preferredIndex;
}
private void OnHumanRowForceChanged(int slotIndex, int direction)
{
var slot = Main.Instance.MapConfig.GetPlayerSlot(slotIndex, NetMode.Multi);
if (slot == null) return;
var next = GetNextForce(slot.CivId, slot.ForceId, direction);
if (Main.Instance.MapConfig.UpdateSelfMemberConfig(slotIndex,
Table.Instance.TransCivEnumToCivId(next.Civ),
Table.Instance.TransForceEnumToForceId(next.Force),
GetValidTeamId(slot)))
{
Main.Instance.MapConfig.CheckMapConfigChanged();
}
}
private void OnHumanRowTeamChanged(int slotIndex, int direction)
{
var slot = Main.Instance.MapConfig.GetPlayerSlot(slotIndex, NetMode.Multi);
if (slot == null) return;
int nextTeamId = GetNextTeamId(GetValidTeamId(slot), direction);
if (Main.Instance.MapConfig.UpdateSelfMemberTeam(nextTeamId))
{
Main.Instance.MapConfig.CheckMapConfigChanged();
}
}
private void OnAIRowForceChanged(int slotIndex, int direction)
{
if (!_lobby.IsLobbyOwner()) return;
var slot = Main.Instance.MapConfig.GetPlayerSlot(slotIndex, NetMode.Multi);
if (slot == null) return;
var next = GetNextForce(slot.CivId, slot.ForceId, direction);
if (Main.Instance.MapConfig.SetPlayerSlotCiv(slotIndex,
Table.Instance.TransCivEnumToCivId(next.Civ),
Table.Instance.TransForceEnumToForceId(next.Force)))
{
Main.Instance.MapConfig.ResetGuestReadyStates();
Main.Instance.MapConfig.CheckMapConfigChanged();
}
}
private void OnAIRowTeamChanged(int slotIndex, int direction)
{
if (!_lobby.IsLobbyOwner()) return;
var slot = Main.Instance.MapConfig.GetPlayerSlot(slotIndex, NetMode.Multi);
if (slot == null) return;
int nextTeamId = GetNextTeamId(GetValidTeamId(slot), direction);
if (Main.Instance.MapConfig.SetPlayerSlotTeam(slotIndex, nextTeamId))
{
Main.Instance.MapConfig.ResetGuestReadyStates();
Main.Instance.MapConfig.CheckMapConfigChanged();
}
}
private int GetNextTeamId(int teamId, int direction)
{
int maxTeamId = Mathf.Max(1, (int)Main.Instance.MapConfig.PlayerCount);
teamId += direction;
if (teamId < 1) return maxTeamId;
if (teamId > maxTeamId) return 1;
return teamId;
}
private (CivEnum Civ, ForceEnum Force) GetNextForce(uint civId, uint forceId, int direction)
{
var civ = Table.Instance.TransCivIdToCivEnum(civId);
var force = Table.Instance.TransForceIdToForceEnum(forceId);
int index = 0;
for (int i = 0; i < RoomForceOptions.Length; i++)
{
if (RoomForceOptions[i].Civ == civ && RoomForceOptions[i].Force == force)
{
index = i;
break;
}
}
index = (index + direction + RoomForceOptions.Length) % RoomForceOptions.Length;
return RoomForceOptions[index];
}
private void SetRoomInfoSetting()
@ -527,6 +817,7 @@ namespace TH1_UI.View.Outside
public void SetNoRoom()
{
StartGameButton.gameObject.SetActive(false);
SetReadyButtonsVisible(false, false);
LeaveRoomButton.gameObject.SetActive(false);
RoomSettingArea.gameObject.SetActive(false);
RoomMemberArea.gameObject.SetActive(false);
@ -618,7 +909,8 @@ namespace TH1_UI.View.Outside
//获取房间类型0=公开1=私密
bool isPublic = RoomType?.SelectedIndex == 0;
_lobby.CreateLobby(4, isPublic);
_roomSeatCount = Mathf.Max(1, (int)Main.Instance.MapConfig.PlayerCount);
_lobby.CreateLobby(_roomSeatCount, isPublic);
}
public void LeaveRoom()
@ -640,6 +932,14 @@ namespace TH1_UI.View.Outside
return;
SetMapConfig();
ReconcileRoomMembers();
BuildRoomMemberRows(_lobby.GetAllMemberInfo(), Main.Instance.MapConfig.MultiCivs);
if (_openMemberRowCount > 0)
{
ShowCantStartHint(Table.Instance.TextDataAssets.OutsideMultiplayOpenHint);
return;
}
if (!Main.Instance.MapConfig.AreAllLobbyMembersReady())
{
@ -662,23 +962,28 @@ namespace TH1_UI.View.Outside
if (members.Count > playerCount)
{
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyMembersNotSynced);
CantStartHint.SetActive(true);
CantStartHintText.text = MultilingualManager.Instance.GetMultilingualText(Table.Instance.TextDataAssets.OutsideMultiplayCantStartCount);
CantStartHintAnimancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeIn);
Timer.Instance.TimerRegister(this, () =>
{
CantStartHintAnimancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeOut);
},1f,"MultiplayStartGame");
Timer.Instance.TimerRegister(this, () =>
{
CantStartHint.SetActive(false);
},1f + ResourceCache.Instance.AnimCache.UICommonPanelFadeOut.length,"MultiplayStartGame");
ShowCantStartHint(Table.Instance.TextDataAssets.OutsideMultiplayCantStartCount);
return;
}
ShowLoadingAndStartGame(false);
}
private void ShowCantStartHint(string textKey)
{
CantStartHint.SetActive(true);
CantStartHintText.text = MultilingualManager.Instance.GetMultilingualText(textKey);
CantStartHintAnimancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeIn);
Timer.Instance.TimerRegister(this, () =>
{
CantStartHintAnimancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeOut);
},1f,"MultiplayStartGame");
Timer.Instance.TimerRegister(this, () =>
{
CantStartHint.SetActive(false);
},1f + ResourceCache.Instance.AnimCache.UICommonPanelFadeOut.length,"MultiplayStartGame");
}
private void SetMapConfig(bool resetGuestReady = false)
{

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff