diff --git a/Assets/PerfectWorld/Prefab/UI/Teamate.prefab b/Assets/PerfectWorld/Prefab/UI/Teamate.prefab
index bca1e95cfb..be386da4b5 100644
--- a/Assets/PerfectWorld/Prefab/UI/Teamate.prefab
+++ b/Assets/PerfectWorld/Prefab/UI/Teamate.prefab
@@ -1427,6 +1427,7 @@ RectTransform:
- {fileID: 6747937870382540800}
- {fileID: 9145156114905100934}
- {fileID: 1392280977313824629}
+ - {fileID: 7829150308709081067}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
@@ -1484,6 +1485,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 52c15f7b28624ef4697b1f7eb3a0d17c, type: 3}
m_Name:
m_EditorClassIdentifier:
+ skillNameText: {fileID: 0}
+ imageProgress: {fileID: 0}
Content_Teammates: {fileID: 2702288869473602435}
TeammateItemPrefab: {fileID: 5014101816795320943, guid: ef1af109634dbf44da065d64dc30fa38, type: 3}
Content_Nearby: {fileID: 4562375036863719405}
@@ -6166,6 +6169,138 @@ MonoBehaviour:
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
+--- !u!1 &7140757019260147103
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 7829150308709081067}
+ - component: {fileID: 615136352827836387}
+ - component: {fileID: 3391660217384508209}
+ - component: {fileID: 4321133568498195476}
+ m_Layer: 5
+ m_Name: close_btn
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &7829150308709081067
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7140757019260147103}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 7364890917756710219}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0.5, y: 0.5}
+ m_AnchorMax: {x: 0.5, y: 0.5}
+ m_AnchoredPosition: {x: 426.97388, y: 272.67}
+ m_SizeDelta: {x: 30.682, y: 31.93}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &615136352827836387
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7140757019260147103}
+ m_CullTransparentMesh: 1
+--- !u!114 &3391660217384508209
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7140757019260147103}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 21300000, guid: fb2f2f58be45f6e4890e85cc00b0bcc9, type: 3}
+ m_Type: 0
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!114 &4321133568498195476
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7140757019260147103}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Navigation:
+ m_Mode: 3
+ m_WrapAround: 0
+ m_SelectOnUp: {fileID: 0}
+ m_SelectOnDown: {fileID: 0}
+ m_SelectOnLeft: {fileID: 0}
+ m_SelectOnRight: {fileID: 0}
+ m_Transition: 1
+ m_Colors:
+ m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+ m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+ m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+ m_ColorMultiplier: 1
+ m_FadeDuration: 0.1
+ m_SpriteState:
+ m_HighlightedSprite: {fileID: 0}
+ m_PressedSprite: {fileID: 0}
+ m_SelectedSprite: {fileID: 0}
+ m_DisabledSprite: {fileID: 0}
+ m_AnimationTriggers:
+ m_NormalTrigger: Normal
+ m_HighlightedTrigger: Highlighted
+ m_PressedTrigger: Pressed
+ m_SelectedTrigger: Selected
+ m_DisabledTrigger: Disabled
+ m_Interactable: 1
+ m_TargetGraphic: {fileID: 3391660217384508209}
+ m_OnClick:
+ m_PersistentCalls:
+ m_Calls:
+ - m_Target: {fileID: 2452003196178065293}
+ m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine
+ m_MethodName: SetActive
+ m_Mode: 6
+ m_Arguments:
+ m_ObjectArgument: {fileID: 0}
+ m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+ m_IntArgument: 0
+ m_FloatArgument: 0
+ m_StringArgument:
+ m_BoolArgument: 0
+ m_CallState: 2
--- !u!1 &7172228088205297695
GameObject:
m_ObjectHideFlags: 0
@@ -8448,7 +8583,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_AnchorMax.y
- value: 0
+ value: 1
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_AnchorMin.x
@@ -8456,15 +8591,15 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_AnchorMin.y
- value: 0
+ value: 1
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_SizeDelta.x
- value: 0
+ value: 300
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_SizeDelta.y
- value: 0
+ value: 60
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_LocalPosition.x
@@ -8496,11 +8631,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_AnchoredPosition.x
- value: 0
+ value: 154
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_AnchoredPosition.y
- value: 0
+ value: -35
objectReference: {fileID: 0}
- target: {fileID: 2128182273890188768, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
@@ -8522,6 +8657,10 @@ PrefabInstance:
propertyPath: m_Name
value: team_item
objectReference: {fileID: 0}
+ - target: {fileID: 8777891425110263910, guid: df9492e8a45f4b047bf5ffedaf2921ab, type: 3}
+ propertyPath: m_IsActive
+ value: 0
+ objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
diff --git a/Assets/PerfectWorld/Scene/Bootstrap.unity b/Assets/PerfectWorld/Scene/Bootstrap.unity
index 6ef985d281..35a895d61b 100644
--- a/Assets/PerfectWorld/Scene/Bootstrap.unity
+++ b/Assets/PerfectWorld/Scene/Bootstrap.unity
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:84e412b6f5e36bb93f0b17ced95c929c8773b7ed9d513f792a0f4664d78b7014
-size 282581
+oid sha256:57bb52418b44eb7e3e333915973057be091b0826983b641ceb05263b4dffe2e4
+size 287382
diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs
index f387e0a2ca..707a76639d 100644
--- a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs
+++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs
@@ -33,18 +33,6 @@ namespace PerfectWorld.Scripts.Managers
{
if (CECGameRun.Instance == null) return true;
if (CECGameRun.Instance.GetHostPlayer() == null) return true;
- // Duel invite: show accept/reject popup (origin uses MSG_PM_DUELOPT with command DUEL_RECV_REQUEST = 214)
- // dwParam2 is ushort (pCmdHeader from GameSession); use Convert to avoid InvalidCastException when unboxing
- if ((int)Msg.dwMsg == EC_MsgDef.MSG_PM_DUELOPT && Convert.ToInt32(Msg.dwParam2) == CommandID.DUEL_RECV_REQUEST && Msg.dwParam1 is byte[] pDataBuf && pDataBuf.Length >= 4)
- {
- int inviterId = BitConverter.ToInt32(pDataBuf, 0);
- CECUIManager.Instance?.ShowMessageBox(
- title: "",
- message: "You have received a duel request. Do you accept?",
- messageBoxType: MessageBoxType.BothYesNoButton,
- onClickedYes: () => UnityGameSession.c2s_CmdDuelReply(true, inviterId),
- onClickedNo: () => UnityGameSession.c2s_CmdDuelReply(false, inviterId));
- }
CECGameRun.Instance.GetHostPlayer().ProcessMessage(Msg);
}
else if (Msg.iSubID < 0)
diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs
index b4e93c6fac..6082666510 100644
--- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs
+++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs
@@ -818,6 +818,18 @@ namespace CSNetwork.C2SCommand
return SerializeCommand(CommandID.TEAM_INVITE, new cmd_team_new_member { idMember = idPlayer });
}
+ /// C2S: accept team invite from leader. idLeader = who sent the invite, team_seq = invite sequence from TEAM_LEADER_INVITE.
+ public static Octets CreateTeamAgreeInviteCommand(int idLeader, int team_seq)
+ {
+ return SerializeCommand(CommandID.TEAM_AGREE_INVITE, new cmd_team_agree_invite { idLeader = idLeader, team_seq = team_seq });
+ }
+
+ /// C2S: reject team invite from leader.
+ public static Octets CreateTeamRejectInviteCommand(int idLeader)
+ {
+ return SerializeCommand(CommandID.TEAM_REJECT_INVITE, new cmd_team_reject_invite { idLeader = idLeader });
+ }
+
/// C2S: request duel with target player (same payload shape as team invite).
public static Octets CreateDuelRequestCommand(int idTarget)
{
diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs
index 2fcbaa4fc5..67ca8d2495 100644
--- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs
+++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs
@@ -2208,6 +2208,21 @@ namespace CSNetwork.GPDataType
public int idMember;
}
+ /// C2S: accept team invite. idLeader = who sent the invite, team_seq = invite sequence.
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct cmd_team_agree_invite
+ {
+ public int idLeader;
+ public int team_seq;
+ }
+
+ /// C2S: reject team invite. idLeader = who sent the invite.
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct cmd_team_reject_invite
+ {
+ public int idLeader;
+ }
+
/// C2S duel reply (origin: who = inviter id, param = 0 accept / non-zero reject reason).
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct cmd_duel_reply
diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs
index 2cd0e8486d..073a93dabf 100644
--- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs
+++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs
@@ -840,6 +840,9 @@ namespace CSNetwork
case CommandID.TEAM_MEMBER_DATA:
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_TEAMMEMBERDATA, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
break;
+ case CommandID.TEAM_LEADER_INVITE:
+ EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_TEAMINVITE, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
+ break;
case CommandID.TEAM_MEMBER_LEAVE:
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_LEAVETEAM, (int)MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader);
break;
@@ -1863,6 +1866,20 @@ namespace CSNetwork
SendProtocol(g);
}
+ public void c2s_SendCmdTeamAgreeInvite(int idLeader, int team_seq)
+ {
+ var g = new gamedatasend();
+ g.Data = C2SCommandFactory.CreateTeamAgreeInviteCommand(idLeader, team_seq);
+ SendProtocol(g);
+ }
+
+ public void c2s_SendCmdTeamRejectInvite(int idLeader)
+ {
+ var g = new gamedatasend();
+ g.Data = C2SCommandFactory.CreateTeamRejectInviteCommand(idLeader);
+ SendProtocol(g);
+ }
+
public void c2s_SendCmdDuelRequest(int idTarget)
{
var g = new gamedatasend();
diff --git a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs
index 2ea519aff2..6d4da53a7c 100644
--- a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs
+++ b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs
@@ -599,6 +599,14 @@ namespace BrewMonster.Network
{
Instance._gameSession.c2s_SendCmdTeamInvite(idPlayer);
}
+ public static void c2s_CmdTeamAgreeInvite(int idLeader, int team_seq)
+ {
+ Instance._gameSession.c2s_SendCmdTeamAgreeInvite(idLeader, team_seq);
+ }
+ public static void c2s_CmdTeamRejectInvite(int idLeader)
+ {
+ Instance._gameSession.c2s_SendCmdTeamRejectInvite(idLeader);
+ }
public static void c2s_CmdDuelRequest(int idTarget)
{
Instance._gameSession.c2s_SendCmdDuelRequest(idTarget);
diff --git a/Assets/Scenes/a61.unity.meta b/Assets/Scenes/a61.unity.meta
new file mode 100644
index 0000000000..9897459ab1
--- /dev/null
+++ b/Assets/Scenes/a61.unity.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 2099d0c0fdfc641509729652b0ed485f
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs
index 63405d1aee..cede52a8c3 100644
--- a/Assets/Scripts/CECHostPlayer.cs
+++ b/Assets/Scripts/CECHostPlayer.cs
@@ -608,6 +608,7 @@ namespace BrewMonster
case EC_MsgDef.MSG_HST_JOINTEAM: OnMsgHstJoinTeam(Msg); break;
case EC_MsgDef.MSG_HST_LEAVETEAM: OnMsgHstLeaveTeam(Msg); break;
case EC_MsgDef.MSG_HST_NEWTEAMMEM: OnMsgHstNewTeamMem(Msg); break;
+ case EC_MsgDef.MSG_HST_TEAMINVITE: OnMsgHstTeamInvite(Msg); break;
case EC_MsgDef.MSG_HST_TEAMMEMBERDATA: OnMsgHstTeamMemberData(Msg); break;
case EC_MsgDef.MSG_PM_DUELOPT: OnMsgHstDuelOpt(Msg); break;
case EC_MsgDef.MSG_HST_CLEARTESSERA: OnMsgHstClearTessera(Msg); break;
@@ -653,6 +654,18 @@ namespace BrewMonster
idOpp = BitConverter.ToInt32(data, 0);
switch (cmdId)
{
+ case CommandID.DUEL_RECV_REQUEST:
+ // Duel invite: show accept/reject popup (origin MSG_PM_DUELOPT with command DUEL_RECV_REQUEST = 214)
+ if (idOpp != 0)
+ {
+ CECUIManager.Instance?.ShowMessageBox(
+ title: "",
+ message: "You have received a duel request. Do you accept?",
+ messageBoxType: MessageBoxType.BothYesNoButton,
+ onClickedYes: () => UnityGameSession.c2s_CmdDuelReply(true, idOpp),
+ onClickedNo: () => UnityGameSession.c2s_CmdDuelReply(false, idOpp));
+ }
+ break;
case CommandID.DUEL_PREPARE:
m_pvp.iDuelState = Duel_state.DUEL_ST_PREPARE;
m_pvp.idDuelOpp = idOpp;
@@ -683,6 +696,32 @@ namespace BrewMonster
}
}
+ /// Host received a team invite (MSG_HST_TEAMINVITE). Payload is cmd_team_leader_invite: idLeader, seq, pickFlag. Shows accept/reject message box and sends reply.
+ private void OnMsgHstTeamInvite(ECMSG Msg)
+ {
+ byte[] data = Msg.dwParam1 as byte[];
+ int idLeader = 0;
+ int team_seq = 0;
+ if (data != null && data.Length >= 8)
+ {
+ idLeader = BitConverter.ToInt32(data, 0);
+ team_seq = BitConverter.ToInt32(data, 4);
+ }
+ else if (data != null && data.Length >= 4)
+ {
+ idLeader = BitConverter.ToInt32(data, 0);
+ }
+ if (idLeader == 0)
+ return;
+ int seqCapture = team_seq;
+ CECUIManager.Instance?.ShowMessageBox(
+ title: "",
+ message: "You have received a team invite. Do you accept?",
+ messageBoxType: MessageBoxType.BothYesNoButton,
+ onClickedYes: () => UnityGameSession.c2s_CmdTeamAgreeInvite(idLeader, seqCapture),
+ onClickedNo: () => UnityGameSession.c2s_CmdTeamRejectInvite(idLeader));
+ }
+
/// Called when MSG_PM_PLAYERDUELOPT (229) is received; server may send duel start to both participants. If host is one of the two ids, set duel state.
public void OnMsgPlayerDuelStart(byte[] data)
{