From 68bf840210fe980c05029ccfeb155bf8dce3dea3 Mon Sep 17 00:00:00 2001 From: ZouJin Date: Wed, 20 Mar 2024 02:36:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=91=B8=E5=A4=B4=E6=8D=8F?= =?UTF-8?q?=E8=84=B8=E7=AD=89=E4=BA=92=E5=8A=A8=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MutiPlayer/IMPFriend.cs | 19 ++ .../MutiPlayer/IMPWindows.cs | 8 + .../MutiPlayer/MPMessage.cs | 66 ++++++- .../MutiPlayer/MPController.cs | 6 +- .../MutiPlayer/MPFriends.xaml.cs | 179 ++++++++++++++++-- .../MutiPlayer/winMutiPlayer.xaml.cs | 111 +++++++++++ 6 files changed, 357 insertions(+), 32 deletions(-) diff --git a/VPet-Simulator.Windows.Interface/MutiPlayer/IMPFriend.cs b/VPet-Simulator.Windows.Interface/MutiPlayer/IMPFriend.cs index cf90af5..fba3b04 100644 --- a/VPet-Simulator.Windows.Interface/MutiPlayer/IMPFriend.cs +++ b/VPet-Simulator.Windows.Interface/MutiPlayer/IMPFriend.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using VPet_Simulator.Core; +using static VPet_Simulator.Core.GraphInfo; using static VPet_Simulator.Windows.Interface.MPMessage; namespace VPet_Simulator.Windows.Interface; @@ -53,4 +54,22 @@ public interface IMPFriend /// /// 聊天内容 void DisplayMessage(Chat msg); + + /// + /// 判断是否在忙碌 (被提起等, 不可进行互动) + /// + /// + public bool InConvenience(); + + /// + /// 判断是否在忙碌 (被提起等, 不可进行互动) + /// + public static bool InConvenience(Main Main) + { + if (Main.DisplayType.Type == GraphType.StartUP || Main.DisplayType.Type == GraphType.Raised_Dynamic || Main.DisplayType.Type == GraphType.Raised_Static) + { + return true; + } + return false; + } } diff --git a/VPet-Simulator.Windows.Interface/MutiPlayer/IMPWindows.cs b/VPet-Simulator.Windows.Interface/MutiPlayer/IMPWindows.cs index ce28702..2bed49e 100644 --- a/VPet-Simulator.Windows.Interface/MutiPlayer/IMPWindows.cs +++ b/VPet-Simulator.Windows.Interface/MutiPlayer/IMPWindows.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using static VPet_Simulator.Core.GraphInfo; +using VPet_Simulator.Core; namespace VPet_Simulator.Windows.Interface; @@ -58,4 +60,10 @@ public interface IMPWindows /// 事件: 结束访客表, 窗口关闭 /// event Action ClosingMutiPlayer; + + /// + /// 当前是否有游戏(其他mod的)正在进行 避免多个游戏同时进行而导致冲突 + /// 如果你的游戏开始了, 请请设置为true, 并在游戏结束后设置为false + /// + bool IsGameRunning { get; set; } } diff --git a/VPet-Simulator.Windows.Interface/MutiPlayer/MPMessage.cs b/VPet-Simulator.Windows.Interface/MutiPlayer/MPMessage.cs index 2cb8965..f8d6fb8 100644 --- a/VPet-Simulator.Windows.Interface/MutiPlayer/MPMessage.cs +++ b/VPet-Simulator.Windows.Interface/MutiPlayer/MPMessage.cs @@ -33,20 +33,16 @@ public struct MPMessage /// DispayGraph, /// - /// 摸身体 + /// 交互 (Interact) /// - TouchHead, + Interact, /// - /// 摸头 - /// - TouchBody, - /// - /// 喂食 + /// 喂食 (Feed) /// Feed, } /// - /// 消息类型 + /// 消息类型 MOD作者可以随便抽个不是MSGTYPE的数避免冲突,支持负数 /// [Line] public int Type { get; set; } @@ -61,16 +57,36 @@ public struct MPMessage public static byte[] ConverTo(MPMessage data) => Encoding.UTF8.GetBytes(LPSConvert.SerializeObject(data).ToString()); public static MPMessage ConverTo(byte[] data) => LPSConvert.DeserializeObject(new LPS(Encoding.UTF8.GetString(data))); - + /// + /// 设置消息内容(类) + /// public void SetContent(object content) { Content = LPSConvert.GetObjectString(content, convertNoneLineAttribute: true); } + /// + /// 获取消息内容(类) + /// + /// 类类型 public T GetContent() { return (T)LPSConvert.GetStringObject(Content, typeof(T), convertNoneLineAttribute: true); } /// + /// 设置消息内容(字符串) + /// + public void SetContent(string content) + { + Content = content; + } + /// + /// 获取消息内容(字符串) + /// + public string GetContent() + { + return Content; + } + /// /// 聊天结构 /// public struct Chat @@ -106,4 +122,36 @@ public struct MPMessage /// public string SendName { get; set; } } + /// + /// 交互结构 + /// + public struct Feed + { + /// + /// 对方是否启用了数据计算 (并且未丢失小标) + /// + public bool EnableFunction { get; set; } + /// + /// 食物 + /// + public Food Food { get; set; } + } + /// + /// 交互类型 + /// + public enum Interact + { + /// + /// 摸身体 + /// + TouchHead, + /// + /// 摸头 + /// + TouchBody, + /// + /// 捏脸 + /// + TouchPinch, + } } diff --git a/VPet-Simulator.Windows/MutiPlayer/MPController.cs b/VPet-Simulator.Windows/MutiPlayer/MPController.cs index 38e651e..f1d5775 100644 --- a/VPet-Simulator.Windows/MutiPlayer/MPController.cs +++ b/VPet-Simulator.Windows/MutiPlayer/MPController.cs @@ -65,12 +65,12 @@ namespace VPet_Simulator.Windows public void ShowSetting() { - + } public void ShowPanel() { - + } public void ResetPosition() @@ -108,7 +108,7 @@ namespace VPet_Simulator.Windows public int PressLength => mw.Set.PressLength; - public bool EnableFunction => true; + public bool EnableFunction => false; public int InteractionCycle => mw.Set.InteractionCycle; diff --git a/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs index 24a269c..8773f09 100644 --- a/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs +++ b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs @@ -121,21 +121,22 @@ public partial class MPFriends : WindowX, IMPFriend return; } - ImageSources.AddRange(mw.ImageSources); - - - //加载所有MOD - List Path = new List(); - Path.AddRange(new DirectoryInfo(mw.ModPath).EnumerateDirectories()); - - var workshop = mw.Set["workshop"]; - foreach (Sub ws in workshop) - { - Path.Add(new DirectoryInfo(ws.Name)); - } Task.Run(async () => { + ImageSources.AddRange(mw.ImageSources); + + + //加载所有MOD + List Path = new List(); + Path.AddRange(new DirectoryInfo(mw.ModPath).EnumerateDirectories()); + + var workshop = mw.Set["workshop"]; + foreach (Sub ws in workshop) + { + Path.Add(new DirectoryInfo(ws.Name)); + } + //加载lobby传过来的数据 string tmp = lb.GetMemberData(friend, "save"); while (string.IsNullOrEmpty(tmp)) @@ -161,9 +162,28 @@ public partial class MPFriends : WindowX, IMPFriend SetPetGraph = tmp; await GameLoad(Path); + + Main.Event_TouchHead += Main_Event_TouchHead; + Main.Event_TouchBody += Main_Event_TouchBody; }); } + + private void Main_Event_TouchHead() + { + Main.LabelDisplayShow("{0}在摸{1}的头".Translate(SteamClient.Name, Core.Save.Name)); + var msg = new MPMessage() { Type = (int)MSGType.Interact, To = friend.Id }; + msg.SetContent(Interact.TouchHead); + wmp.SendMessageALL(msg); + } + private void Main_Event_TouchBody() + { + Main.LabelDisplayShow("{0}在摸{1}的头".Translate(SteamClient.Name, Core.Save.Name)); + var msg = new MPMessage() { Type = (int)MSGType.Interact, To = friend.Id }; + msg.SetContent(Interact.TouchBody); + wmp.SendMessageALL(msg); + } + public List MPMODs = new List(); public Main Main { get; set; } @@ -276,13 +296,6 @@ public partial class MPFriends : WindowX, IMPFriend } Main.CountNomal = 0; - if (Core.Controller.EnableFunction && Core.Save.Strength >= 10 && Core.Save.Feeling < 100) - { - Core.Save.StrengthChange(-2); - Core.Save.FeelingChange(1); - Core.Save.Mode = Core.Save.CalMode(); - Main.LabelDisplayShowChangeNumber(LocalizeCore.Translate("体力-{0:f0} 心情+{1:f0}"), 2, 1); - } if (Main.DisplayType.Name == "pinch") { if (Main.DisplayType.Animat == AnimatType.A_Start) @@ -305,6 +318,10 @@ public partial class MPFriends : WindowX, IMPFriend } private void DisplayPinch_loop() { + Main.LabelDisplayShow("{0}在捏{1}的脸".Translate(SteamClient.Name, Core.Save.Name)); + var msg = new MPMessage() { Type = (int)MSGType.Interact, To = friend.Id }; + msg.SetContent(Interact.TouchPinch); + wmp.SendMessageALL(msg); if (Main.isPress && Main.DisplayType.Name == "pinch" && Main.DisplayType.Animat == AnimatType.B_Loop) { if (Core.Controller.EnableFunction && Core.Save.Strength >= 10 && Core.Save.Feeling < 100) @@ -321,6 +338,124 @@ public partial class MPFriends : WindowX, IMPFriend Main.DisplayCEndtoNomal("pinch"); } } + /// + /// 显示摸头情况 (无任何计算和传导) + /// + public void DisplayNOCALTouchHead() + { + if (Main.DisplayType.Type == GraphType.Touch_Head) + { + if (Main.DisplayType.Animat == AnimatType.A_Start) + return; + else if (Main.DisplayType.Animat == AnimatType.B_Loop) + if (Dispatcher.Invoke(() => Main.PetGrid.Tag) is IGraph ig && ig.GraphInfo.Type == GraphType.Touch_Head && ig.GraphInfo.Animat == AnimatType.B_Loop) + { + ig.IsContinue = true; + return; + } + else if (Dispatcher.Invoke(() => Main.PetGrid2.Tag) is IGraph ig2 && ig2.GraphInfo.Type == GraphType.Touch_Head && ig2.GraphInfo.Animat == AnimatType.B_Loop) + { + ig2.IsContinue = true; + return; + } + } + Main.Display(GraphType.Touch_Head, AnimatType.A_Start, (graphname) => + Main.Display(graphname, AnimatType.B_Loop, (graphname) => + Main.Display(graphname, AnimatType.B_Loop, (graphname) => + Main.DisplayCEndtoNomal(graphname)))); + } + /// + /// 显示摸身体情况 (无任何计算和传导) + /// + public void DisplayNOCALTouchBody() + { + if (Main.DisplayType.Type == GraphType.Touch_Body) + { + if (Main.DisplayType.Animat == AnimatType.A_Start) + return; + else if (Main.DisplayType.Animat == AnimatType.B_Loop) + if (Dispatcher.Invoke(() => Main.PetGrid.Tag) is IGraph ig && ig.GraphInfo.Type == GraphType.Touch_Body && ig.GraphInfo.Animat == AnimatType.B_Loop) + { + ig.IsContinue = true; + return; + } + else if (Dispatcher.Invoke(() => Main.PetGrid2.Tag) is IGraph ig2 && ig2.GraphInfo.Type == GraphType.Touch_Body && ig2.GraphInfo.Animat == AnimatType.B_Loop) + { + ig2.IsContinue = true; + return; + } + } + Main.Display(GraphType.Touch_Body, AnimatType.A_Start, (graphname) => + Main.Display(graphname, AnimatType.B_Loop, (graphname) => + Main.Display(graphname, AnimatType.B_Loop, (graphname) => + Main.DisplayCEndtoNomal(graphname)))); + } + /// + /// 显示摸身体情况 (无任何计算和传导) + /// + public void DisplayNOCALTouchPinch() + { + if (Main.DisplayType.Name == "pinch") + { + if (Main.DisplayType.Animat == AnimatType.A_Start) + return; + else if (Main.DisplayType.Animat == AnimatType.B_Loop) + if (Dispatcher.Invoke(() => Main.PetGrid.Tag) is IGraph ig && ig.GraphInfo.Type == GraphType.Touch_Body && ig.GraphInfo.Animat == AnimatType.B_Loop) + { + ig.IsContinue = true; + return; + } + else if (Dispatcher.Invoke(() => Main.PetGrid2.Tag) is IGraph ig2 && ig2.GraphInfo.Type == GraphType.Touch_Body && ig2.GraphInfo.Animat == AnimatType.B_Loop) + { + ig2.IsContinue = true; + return; + } + } + Main.Display("pinch", AnimatType.A_Start, (graphname) => + Main.Display(graphname, AnimatType.B_Loop, (graphname) => + Main.Display(graphname, AnimatType.B_Loop, (graphname) => Main.DisplayCEndtoNomal(graphname)))); + } + + /// + /// 收到被互动通知 + /// + public void ActiveInteract(string byname, Interact interact) + { + if (!Loaded) + { + return; + } + if (InConvenience()) + {//忙碌时候只显示消息 + switch (interact) + { + case Interact.TouchHead: + case Interact.TouchBody: + Main.LabelDisplayShow("{0}在摸{1}的头".Translate(byname, Core.Save.Name)); + break; + case Interact.TouchPinch: + Main.LabelDisplayShow("{0}在捏{1}的脸".Translate(byname, Core.Save.Name)); + break; + } + return; + } + switch (interact) + { + case Interact.TouchHead: + DisplayNOCALTouchHead(); + Main.LabelDisplayShow("{0}在摸{1}的头".Translate(byname, Core.Save.Name)); + break; + case Interact.TouchBody: + DisplayNOCALTouchBody(); + Main.LabelDisplayShow("{0}在摸{1}的头".Translate(byname, Core.Save.Name)); + break; + case Interact.TouchPinch: + DisplayNOCALTouchPinch(); + Main.LabelDisplayShow("{0}在捏{1}的脸".Translate(byname, Core.Save.Name)); + break; + } + } + /// /// 播放关闭动画并关闭,如果10秒后还未关闭则强制关闭 @@ -368,10 +503,12 @@ public partial class MPFriends : WindowX, IMPFriend /// public bool DisplayGraph(GraphInfo gi) { - if (!Loaded || Main.DisplayType.Type == GraphType.StartUP || Main.DisplayType.Type == GraphType.Raised_Dynamic || Main.DisplayType.Type == GraphType.Raised_Static) + if (!Loaded) { return false; } + if (InConvenience()) + return false; if (gi.Type == Main.DisplayType.Type && gi.Animat == Main.DisplayType.Animat) { if (gi.Type != GraphType.Common) @@ -488,4 +625,6 @@ public partial class MPFriends : WindowX, IMPFriend break; } } + + public bool InConvenience() => IMPFriend.InConvenience(Main); } diff --git a/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs index 0d95639..e50e9db 100644 --- a/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs +++ b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs @@ -20,6 +20,7 @@ using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; +using System.Xml.Linq; using VPet_Simulator.Core; using VPet_Simulator.Windows.Interface; using static VPet_Simulator.Core.GraphInfo; @@ -109,12 +110,15 @@ public partial class winMutiPlayer : Window, IMPWindows BitmapFrame result = BitmapFrame.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); return result; } + public ulong OwnerID { get; set; } public ulong LobbyID => lb.Id.Value; public IEnumerable Friends => MPFriends; + public bool IsGameRunning { get; set; } + public void ShowLobbyInfo() { _ = Task.Run(async () => @@ -295,6 +299,31 @@ public partial class winMutiPlayer : Window, IMPWindows To = MPFriends.Find(x => x.friend.Id == MSG.To); To.DisplayMessage(MSG.GetContent()); break; + case (int)MSGType.Interact: + if (MSG.To == SteamClient.SteamId.Value) + { + var byname = lb.Members.First(x => x.Id == From).Name; + bool isok = !IMPFriend.InConvenience(mw.Main); + switch (MSG.GetContent()) + { + case Interact.TouchHead: + mw.Main.LabelDisplayShow("{0}在摸{1}的头".Translate(byname, mw.Core.Save.Name)); + if (isok) + DisplayNOCALTouchHead(); + break; + case Interact.TouchBody: + mw.Main.LabelDisplayShow("{0}在摸{1}的头".Translate(byname, mw.Core.Save.Name)); + if (isok) + DisplayNOCALTouchBody(); + break; + case Interact.TouchPinch: + mw.Main.LabelDisplayShow("{0}在捏{1}的脸".Translate(byname, mw.Core.Save.Name)); + if (isok) + DisplayNOCALTouchPinch(); + break; + } + } + break; } } Thread.Sleep(100); @@ -345,4 +374,86 @@ public partial class winMutiPlayer : Window, IMPWindows { lb.SetJoinable(false); } + + /// + /// 显示本体摸头情况 (会无损加心情) + /// + public void DisplayNOCALTouchHead() + { + mw.Main.Core.Save.FeelingChange(1); + if (mw.Main.DisplayType.Type == GraphType.Touch_Head) + { + if (mw.Main.DisplayType.Animat == AnimatType.A_Start) + return; + else if (mw.Main.DisplayType.Animat == AnimatType.B_Loop) + if (Dispatcher.Invoke(() => mw.Main.PetGrid.Tag) is IGraph ig && ig.GraphInfo.Type == GraphType.Touch_Head && ig.GraphInfo.Animat == AnimatType.B_Loop) + { + ig.IsContinue = true; + return; + } + else if (Dispatcher.Invoke(() => mw.Main.PetGrid2.Tag) is IGraph ig2 && ig2.GraphInfo.Type == GraphType.Touch_Head && ig2.GraphInfo.Animat == AnimatType.B_Loop) + { + ig2.IsContinue = true; + return; + } + } + mw.Main.Display(GraphType.Touch_Head, AnimatType.A_Start, (graphname) => + mw.Main.Display(graphname, AnimatType.B_Loop, (graphname) => + mw.Main.Display(graphname, AnimatType.B_Loop, (graphname) => + mw.Main.DisplayCEndtoNomal(graphname)))); + } + /// + /// 显示摸身体情况 (会无损加心情) + /// + public void DisplayNOCALTouchBody() + { + mw.Main.Core.Save.FeelingChange(1); + if (mw.Main.DisplayType.Type == GraphType.Touch_Body) + { + if (mw.Main.DisplayType.Animat == AnimatType.A_Start) + return; + else if (mw.Main.DisplayType.Animat == AnimatType.B_Loop) + if (Dispatcher.Invoke(() => mw.Main.PetGrid.Tag) is IGraph ig && ig.GraphInfo.Type == GraphType.Touch_Body && ig.GraphInfo.Animat == AnimatType.B_Loop) + { + ig.IsContinue = true; + return; + } + else if (Dispatcher.Invoke(() => mw.Main.PetGrid2.Tag) is IGraph ig2 && ig2.GraphInfo.Type == GraphType.Touch_Body && ig2.GraphInfo.Animat == AnimatType.B_Loop) + { + ig2.IsContinue = true; + return; + } + } + mw.Main.Display(GraphType.Touch_Body, AnimatType.A_Start, (graphname) => + mw.Main.Display(graphname, AnimatType.B_Loop, (graphname) => + mw.Main.Display(graphname, AnimatType.B_Loop, (graphname) => + mw.Main.DisplayCEndtoNomal(graphname)))); + } + /// + /// 显示本体捏脸情况 (会无损加心情) + /// + public void DisplayNOCALTouchPinch() + { + mw.Main.Core.Save.FeelingChange(1); + if (mw.Main.DisplayType.Name == "pinch") + { + if (mw.Main.DisplayType.Animat == AnimatType.A_Start) + return; + else if (mw.Main.DisplayType.Animat == AnimatType.B_Loop) + if (Dispatcher.Invoke(() => mw.Main.PetGrid.Tag) is IGraph ig && ig.GraphInfo.Type == GraphType.Touch_Head && ig.GraphInfo.Animat == AnimatType.B_Loop) + { + ig.IsContinue = true; + return; + } + else if (Dispatcher.Invoke(() => mw.Main.PetGrid2.Tag) is IGraph ig2 && ig2.GraphInfo.Type == GraphType.Touch_Head && ig2.GraphInfo.Animat == AnimatType.B_Loop) + { + ig2.IsContinue = true; + return; + } + } + mw.Main.Display("pinch", AnimatType.A_Start, (graphname) => + mw.Main.Display(graphname, AnimatType.B_Loop, (graphname) => + mw.Main.Display(graphname, AnimatType.B_Loop, (graphname) => + mw.Main.DisplayCEndtoNomal(graphname)))); + } }