using System; using UnityEngine; using System.Collections.Generic; using System.Linq; using LitJson; using Sfs2X.Core; using Sfs2X.Entities; using Sfs2X.Entities.Data; using Sfs2X.Requests; using Sfs2X.Entities.Variables; using UnityEngine.UI; using Random = UnityEngine.Random; public enum JoinRoomResult { RoomFullError = 0, RoomExpireError = 1, Unknown = 2, Succeed = 3, Pending = 4, } public class SFSPlazaRoomManager { private static Vector3 PlazaRoomPlayerScale = new Vector3(0.525f, 0.525f, 0.525f); public class PlazaRoomPlayer { #region Config public string NickName; public Player Player; public Transform NickNameTransform; public List TweenRoots; public BestfitText MessageLab; public Transform MessageBox; #endregion public PlazaRoomPlayer(Player player, string nickname) { Player = player; TweenRoots = new List(); NickNameTransform = ManaReso.Get("NickName", Folder.UI, false, ManaReso.Get("W_HudParent"), false, ObjType.NickName); HudTarget hudTarget = NickNameTransform.GetComponent(); if (hudTarget == null) { hudTarget = NickNameTransform.AddComponent(); } hudTarget.PosTra = Player.ChildDic["NickName"]; hudTarget.SetPosition(); NickName = string.IsNullOrEmpty(nickname) ? Language.GetStr("UI", "未命名") : nickname; NickNameTransform.GetComponent().text = NickName; MessageBox = ManaReso.Get("MessageBox", Folder.UI, false, ManaReso.Get("W_HudParent"), false, ObjType.MessageBox); MessageLab = MessageBox.GetComponentInChildren(); MessageLab.VerticalMinSize = 12; MessageLab.VerticalMaxSize = 20; hudTarget = MessageBox.GetComponent(); if (hudTarget == null) { hudTarget = MessageBox.AddComponent(); } hudTarget.PosTra = Player.ChildDic["MessageBox"]; MessageBox.CreateTweenCG(0, 1, 0.25f, true, true, Curve.EaseOutQuad).InOrigin = true; } public void Save() { foreach (var tweenRoot in TweenRoots) { tweenRoot.Pause(); } ManaReso.Save(Player); ManaReso.Save(NickNameTransform); ManaReso.Save(MessageBox); Player.PlayAnim(Player.IdleAnimationName); Player.DeactiveShadow(); Player.Shadow.SetLZ(0); Player.ExpressionMeshFilter.transform.parent = Player.transform; } public bool IsMoving; public float Speed = 1f; public Vector3 Destination; public TweenVec MoveTween; public void MoveTo(Vector3 destination) { if (destination.Equal(Player.transform.position)) { return; } if (destination.x > Player.transform.position.x) { Player.Flip(PlayerDirection.Right); } else { Player.Flip(PlayerDirection.Left); } float duration = Mathf.Clamp(Vector3.Magnitude(destination - Player.transform.position) / 1.5f, 0.25f, 10f) / Speed; MoveTween = Player.transform.CreateTweenVec3D(destination, duration, false, true, true, Curve.EaseOutQuad); MoveTween.StartForward(); MoveTween.AddEventOnetime(EventType.ForwardFinish, StopMove); TweenRoots.Add(MoveTween); IsMoving = true; Destination = destination; Player.PlayAnim(Player.WalkAnimationName); } public void StopMove() { IsMoving = false; Player.PlayAnim(Player.IdleAnimationName); } public float MessgeTime = 3f; public Coroutine MessgeCoroutine; public void ShowMessage(Color color, string message) { if (MessgeCoroutine != null) { Auxiliary.Instance.StopCoroutine(MessgeCoroutine); } MessageLab.text = message; MessageLab.color = color; MessageBox.TweenForCG(); MessgeCoroutine = Auxiliary.Instance.DelayCall(() => { MessageBox.TweenBacCG(); }, MessgeTime); } } #region Variable public GardenSmartFox GardenSmartFox; public PlazaRoomPlayer SelfInstance; public Room CurrentPlazaRoom; public RoomData CurrentRoomData; public bool JoinedPlazaRoom { get { return CurrentPlazaRoom != null; } } public bool InPlazaRoom; public bool IsBlackMaskFinish; public JoinRoomResult JoinRoomResult = JoinRoomResult.Pending; public Dictionary UserInstanceDictionary = new Dictionary(); #endregion private Coroutine JoinRoomCoroutine; public void BeginEnterPlazaRoom(RoomData roomData) { CurrentRoomData = roomData; IsBlackMaskFinish = false; JoinRoomResult = JoinRoomResult.Pending; ManaAudio.MusicTheme.TweenBacAudio(); ManaReso.Get("B_SignIn0").TweenBacCG(); ManaReso.Get("T_NickName").TweenBacCG(); ManaCenter.SceneSwitchLock = true; TweenRoot tweenRoot = ManaReso.Get("V_BlackMask").TweenBacCG(); tweenRoot.AddEventOnetime ( EventType.BackwardFinish, () => { IsBlackMaskFinish = true; TryEnterPlazaRoom(); } ); GardenSmartFox.ExecuteAfterCheckConection ( null, (succeed, baseEvent) => { if (!succeed) { JoinRoomResult = JoinRoomResult.Unknown; TryEnterPlazaRoom(); } }, (succeed, baseEvent) => { if (!succeed) { JoinRoomResult = JoinRoomResult.Unknown; TryEnterPlazaRoom(); } } ); JoinRoomCoroutine = DelayCall.Call(20f, () => { OnJoinPlazaRoomError(JoinRoomResult.Unknown); }); } public void TryEnterPlazaRoom() { if (!GardenSmartFox.PlazaRoomManager.IsBlackMaskFinish) return; if (JoinRoomResult == JoinRoomResult.Pending) return; if (JoinRoomResult == JoinRoomResult.Succeed) { EnterPlazaRoom(); } else { QuitPlazaRoom(); if (JoinRoomResult == JoinRoomResult.RoomFullError) { Bubble.Show(null, Language.GetStr("UI", "Z_RoomFull"), null, null, () => { ManaReso.Get("V_BlackMask").TweenForCG(); }, null, false); } else if (JoinRoomResult == JoinRoomResult.RoomExpireError) { Bubble.Show(null, Language.GetStr("UI", "Z_RoomExpire"), null, null, () => { ManaReso.Get("V_BlackMask").TweenForCG(); }, null, false); } else { Bubble.Show(null, Language.GetStr("UI", "Z_Unknown"), null, null, () => { ManaReso.Get("V_BlackMask").TweenForCG(); }, null, false); } } } private Vector3 PlayerDefaultPosition; public void EnterPlazaRoom() { PlazaRoom.Initialize(); GardenSmartFox.EventManager.PlazaRoomEvent.GetAllChestData(CurrentRoomData.ID); foreach (var kv in UserInstanceDictionary) { if (kv.Value.Player.transform.parent == null) { kv.Value.Player.transform.parent = ManaReso.Get("PlazaRoom"); kv.Value.Player.transform.localScale = PlazaRoomPlayerScale; } } ManaAudio.MusicPartyTheme.TweenForAudio(); InPlazaRoom = true; PlazaRoomMge.ClosePanel(); ManaGarden.RetrieveAllElf(); ManaIAP.RetrieveADChest(); GardenSmartFox.PlazaRoomManager.PlazaRoomSky = ManaReso.Get("PlazaRoomSky"); SkyOriginPosition = GardenSmartFox.PlazaRoomManager.PlazaRoomSky.position; GardenSmartFox.PlazaRoomManager.PlazaRoomCamera = ManaReso.Get("MainCamera"); GardenSmartFox.PlazaRoomManager.CameraOriginPosition = GardenSmartFox.PlazaRoomManager.PlazaRoomCamera.transform.position; PlayerDefaultPosition = GetDefaultPosition(); SelfInstance = InstantiatePlayer(ManaNickName.NickName, PlayerDefaultPosition, PlayerDirection.Left, ManaData.GetDressDataIDs(ManaPlayer.Player)); SelfInstance.Player.transform.SetZ(SelfInstance.Player.transform.position.z - 0.1f); UserInstanceDictionary.Add(SFSManager.GardenSmartFox.User.Id, SelfInstance); SendInstantiateRequset(-1); GardenSmartFox.PlazaRoomManager.CameraLeftBorder = ManaReso.Get("PlazaRoomCameraLeftBorder").position.x; GardenSmartFox.PlazaRoomManager.CameraRightBorder = ManaReso.Get("PlazaRoomCameraRightBorder").position.x; GardenSmartFox.PlazaRoomManager.PlazaRoomCamera.transform.SetX(GardenSmartFox.PlazaRoomManager.CameraLeftBorder); ManaReso.Get("V_BlackMask").TweenForCG(); ManaReso.SetActive("C_Main2", false); ManaReso.SetActive("Garden", false); ManaReso.SetActive("PlazaRoom", true); ManaReso.SetActive("W_HudParent", true); ManaReso.SetActive("X_PlazaRoom", true); } public void ExitPlazaRoom() { QuitPlazaRoom(); TweenRoot tweenRoot = ManaReso.Get("V_BlackMask").TweenBacCG(); tweenRoot.AddEventOnetime ( EventType.BackwardFinish, () => { ChestMge.RetrieveAllChest(); InPlazaRoom = false; ManaAudio.MusicTheme.TweenForAudio(); PlazaRoomSky.position = SkyOriginPosition; PlazaRoomCamera.transform.position = CameraOriginPosition; ManaReso.SetActive("C_Main2", true); ManaReso.SetActive("Garden", true); ManaReso.SetActive("PlazaRoom", false); ManaReso.SetActive("W_HudParent", false); ManaReso.SetActive("X_PlazaRoom", false); ManaReso.Get("V_BlackMask").TweenForCG(); ManaReso.Get("B_SignIn0").TweenForCG(); ManaReso.Get("T_NickName").TweenForCG(); ManaReso.Get("X_CurrentInfoLab").text = ""; Transform tra = ManaReso.Get("X_Info"); while (tra.childCount > 0) { ManaReso.Save(tra.GetChild(0)); } foreach (var kv in UserInstanceDictionary) { kv.Value.Save(); } UserInstanceDictionary = new Dictionary(); RobotManager.DeactivateAllRobots(true); } ); tweenRoot.AddEventOnetime ( EventType.ForwardFinish, () => { PlazaRoomMge.OpenPanel(); } ); } public void QuitPlazaRoom() { PlazaRoomChest.SystemChest = null; ManaCenter.SceneSwitchLock = false; GardenSmartFox.SmartFox.Send(new LeaveRoomRequest(CurrentPlazaRoom)); GardenSmartFox.PlazaRoomManager.CurrentPlazaRoom = null; } public SFSPlazaRoomManager(GardenSmartFox gardenSmartFox) { GardenSmartFox = gardenSmartFox; gardenSmartFox.Connector.onConnectionLost += OnConectionLost; } public void Update() { if (!JoinedPlazaRoom) return; if (!InPlazaRoom) return; //KeepAliveThread(); //CheckDefautChestThread(); RobotThread(); CameraControllThread(); } public float KeepAliveTime = 30; public float KeepAliveTimer; public void KeepAliveThread() { KeepAliveTimer += Time.deltaTime; if (KeepAliveTimer > KeepAliveTime) { KeepAliveTimer = 0; SFSObject parameter = new SFSObject(); parameter.PutInt(Label.CommandID, PlazaRoomReq.KeepAlive.GetHashCode()); GardenSmartFox.AddRequest(parameter, RequestType.Immediate); } } public float CameraLeftBorder; public float CameraRightBorder; public Vector3 CameraOriginPosition; public Camera PlazaRoomCamera; public void CameraControllThread() { float x; if (SelfInstance.Player.transform.position.x <= CameraLeftBorder) { x = Mathf.Lerp(PlazaRoomCamera.transform.position.x, CameraLeftBorder, Time.deltaTime); if (SkyTween != null) SkyTween.Pause(); } else if (SelfInstance.Player.transform.position.x >= CameraRightBorder) { x = Mathf.Lerp(PlazaRoomCamera.transform.position.x, CameraRightBorder, Time.deltaTime); if (SkyTween != null) SkyTween.Pause(); } else { x = Mathf.Lerp(PlazaRoomCamera.transform.position.x, SelfInstance.Player.transform.position.x, Time.deltaTime); } PlazaRoomCamera.transform.SetX(x); } public void RobotThread() { RobotManager.Update(); } private float CheckTime = 10; private float CheckTimer; public void CheckDefautChestThread() { CheckTimer += Time.deltaTime; if (CheckTimer >= CheckTime) { CheckTimer = 0; GardenSmartFox.EventManager.PlazaRoomEvent.CheckDefaultChestStatus(CurrentRoomData.ID); } } public void MoveTo(Vector3 destination) { SFSManager.GardenSmartFox.PlazaRoomManager.SelfInstance.MoveTo(destination); SFSManager.GardenSmartFox.PlazaRoomManager.SendSynchronizeDestination(destination); MoveSky(SelfInstance.MoveTween.Duration, SelfInstance.MoveTween.Delta); } private float SkyMoveRatio = 0.1f; private Vector3 SkyOriginPosition; private TweenRoot SkyTween; public Transform PlazaRoomSky; private void MoveSky(float duration, Vector3 offset) { offset *= -SkyMoveRatio; offset.y = 0; offset.z = 0; SkyTween = PlazaRoomSky.transform.CreateTweenVecOffset2D(offset, duration, false, true, true, Curve.Linear); SkyTween.StartForward(); } public void OnConectionLost(BaseEvent baseEvent) { if (JoinedPlazaRoom) { OnExitPlazaRoom(); } } public void OnExitPlazaRoom() { ManaAudio.MusicPartyTheme.TweenBacAudio(); ExitPlazaRoom(); } public void OnJoinPlazaRoom(Room room) { if (JoinRoomResult == JoinRoomResult.Pending) { GardenSmartFox.PlazaRoomManager.CurrentPlazaRoom = room; JoinRoomResult = JoinRoomResult.Succeed; TryEnterPlazaRoom(); DelayCall.stopCoroutine(JoinRoomCoroutine); } } public void OnJoinPlazaRoomError(JoinRoomResult joinRoomResult) { if (JoinRoomResult == JoinRoomResult.Pending) { JoinRoomResult = joinRoomResult; TryEnterPlazaRoom(); DelayCall.stopCoroutine(JoinRoomCoroutine); } } public void OnUserExitPlazaRoom(int userID) { UserInstanceDictionary[userID].Save(); UserInstanceDictionary.Remove(userID); } public void OnUserEnterPlazaRoom(int senderID) { SendInstantiateRequset(senderID); } public void Synchronize(int senderID, ISFSObject parameter) { if (!UserInstanceDictionary.ContainsKey(senderID)) return; if (SFSManager.GardenSmartFox.User.Id == senderID) return; if (parameter.ContainsKey(InfoLabel.Destination.GetHashString())) { Vector3 destination = parameter.GetUtfString(InfoLabel.Destination.GetHashString()).StringToVector(); SynchronizeDestination(destination, senderID); } if (parameter.ContainsKey(InfoLabel.Close.GetHashString())) { List closeIDs = parameter.GetIntArray(InfoLabel.Destination.GetHashString()).ToList(); SynchronizeClose(closeIDs, senderID); } } public void SynchronizeClose(List closeIDs, int senderID) { Player player = UserInstanceDictionary[senderID].Player; foreach (var closeID in closeIDs) { CloseUnit closeUnit = ManaPlayer.CloseUnitDic[closeID]; player.ChangeClose(closeUnit.BodyPart, closeUnit.ArmatureName); } } public void SynchronizeDestination(Vector3 destination, int senderID) { UserInstanceDictionary[senderID].MoveTo(destination); } private float ExpressionDuration = 1; public void ReceiveExpression(int expressionID, int senderID) { PlazaRoomPlayer plazaRoomPlayer = UserInstanceDictionary[senderID]; string expressionName = Enum.GetName(typeof(ExpressionID), expressionID); plazaRoomPlayer.Player.ChangeExpression(expressionName, ExpressionDuration); string senderName = senderID == SFSManager.GardenSmartFox.User.Id ? Language.GetStr("UI", "X_Self") : plazaRoomPlayer.NickName; string message = $"{senderName}:\u3000<({expressionName}按钮)>"; Color textColor = senderID == SFSManager.GardenSmartFox.User.Id ? Lib.SelfMessage : Lib.OtherMessage; ManaInfoBox.Show(InfoCategory.PlazaRoom, message, Mathf.Infinity, textColor, ManaReso.LoadSprite("Expression", Folder.Scene)); Text text = ManaReso.Get("X_CurrentInfoLab"); text.color = textColor; text.text = message; } public void ReceivePublicMessage(string message, int senderID) { Color textColor = senderID == SFSManager.GardenSmartFox.User.Id ? Lib.SelfMessage : Lib.OtherMessage; PlazaRoomPlayer plazaRoomPlayer = UserInstanceDictionary[senderID]; plazaRoomPlayer.ShowMessage(textColor, message); string senderName = senderID == SFSManager.GardenSmartFox.User.Id ? Language.GetStr("UI", "X_Self") : plazaRoomPlayer.NickName; message = $"{senderName}:\u3000{message}"; ManaInfoBox.Show(InfoCategory.PlazaRoom, message, Mathf.Infinity, textColor, ManaReso.LoadSprite("Expression", Folder.Scene)); ManaReso.SetText("X_CurrentInfoLab", message); Text text = ManaReso.Get("X_CurrentInfoLab"); text.color = textColor; text.text = message; } public void OnInstantiate(int senderID, ISFSObject parameter) { if (SFSManager.GardenSmartFox.User.Id == senderID) return; UserInstanceDictionary.Add(senderID, InstantiatePlayer(parameter)); } public void SendExpression(ExpressionID expressionID) { SFSManager.GardenSmartFox.EventManager.PlazaRoomEvent.SendExpression(expressionID); } public bool SendPublicMessage(string message) { if (string.IsNullOrEmpty(message)) { Bubble.Show(null, Language.GetStr("UI", "内容不能为空")); return false; } else { message = StringFilter.GetFilteredString(message); SFSManager.GardenSmartFox.EventManager.PlazaRoomEvent.SendPublicMessage(message); return true; } } public void SendInstantiateRequset(int receiverID) { SFSManager.GardenSmartFox.EventManager.PlazaRoomEvent.SendInstantiateRequset(GardenSmartFox.User.Id, ManaData.GetDressDataIDs(SelfInstance.Player).ToArray(), SelfInstance.Player.transform.position, SelfInstance.Player.PlayerDirection, ManaNickName.NickName, receiverID); if (SelfInstance.IsMoving) { SendSynchronizeDestination(SelfInstance.Destination); } } public void SendSynchronizeDestination(Vector3 destination) { SFSManager.GardenSmartFox.EventManager.PlazaRoomEvent.SendSynchronizeDestination(GardenSmartFox.User.Id, destination); } public PlazaRoomPlayer InstantiatePlayer(string nickName, Vector3 position, PlayerDirection direction, List dressDataIDs) { Transform parent = ManaReso.Get("PlazaRoom", false); Transform tra = ManaReso.Get("Player", Folder.Scene, false, parent, false, ObjType.Player); Player player = tra.GetComponent(); if (player == null) { player = tra.AddScript(); player.Build(); } foreach (var id in dressDataIDs) { CloseUnit closeUnit = ManaPlayer.CloseUnitDic[id]; closeUnit.ChangeDress(player); } player.SetAllCollider(false); player.transform.position = position; player.Flip(direction); player.ActiveShadow(); player.Shadow.SetLZ(3); tra.localScale = PlazaRoomPlayerScale; return new PlazaRoomPlayer(player, nickName); } public PlazaRoomPlayer InstantiatePlayer(ISFSObject parameter) { List dressDatas = ManaData.GetDressDataIDs(parameter); Vector3 position = parameter.GetUtfString(InfoLabel.Position.GetHashString()).StringToVector(); PlayerDirection direction = (PlayerDirection) parameter.GetInt(InfoLabel.PlayerDirection.GetHashString()); string nickName = parameter.GetUtfString(InfoLabel.NickName.GetHashString()); PlazaRoomPlayer plazaRoomPlayer = InstantiatePlayer(nickName, position, direction, dressDatas); return plazaRoomPlayer; } private static float minZOffset = 0.01f; private static float maxZOffset = 0.1f; public static Vector3 GetDefaultPosition() //todo { float zOffset = Random.Range(minZOffset, maxZOffset); Vector3 position = ManaReso.Get("PlazaRoomDefaultPosition").position; position.z += zOffset; return position; } }