支持摸头捏脸等互动同步

This commit is contained in:
ZouJin 2024-03-20 02:36:35 +08:00
parent 7907dd5f9a
commit 68bf840210
6 changed files with 357 additions and 32 deletions

View File

@ -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
/// </summary>
/// <param name="msg">聊天内容</param>
void DisplayMessage(Chat msg);
/// <summary>
/// 判断是否在忙碌 (被提起等, 不可进行互动)
/// </summary>
/// <returns></returns>
public bool InConvenience();
/// <summary>
/// 判断是否在忙碌 (被提起等, 不可进行互动)
/// </summary>
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;
}
}

View File

@ -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
/// 事件: 结束访客表, 窗口关闭
/// </summary>
event Action ClosingMutiPlayer;
/// <summary>
/// 当前是否有游戏(其他mod的)正在进行 避免多个游戏同时进行而导致冲突
/// 如果你的游戏开始了, 请请设置为true, 并在游戏结束后设置为false
/// </summary>
bool IsGameRunning { get; set; }
}

View File

@ -33,20 +33,16 @@ public struct MPMessage
/// </summary>
DispayGraph,
/// <summary>
/// 摸身体
/// 交互 (Interact)
/// </summary>
TouchHead,
Interact,
/// <summary>
/// 摸头
/// </summary>
TouchBody,
/// <summary>
/// 喂食
/// 喂食 (Feed)
/// </summary>
Feed,
}
/// <summary>
/// 消息类型
/// 消息类型 MOD作者可以随便抽个不是MSGTYPE的数避免冲突,支持负数
/// </summary>
[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<MPMessage>(new LPS(Encoding.UTF8.GetString(data)));
/// <summary>
/// 设置消息内容(类)
/// </summary>
public void SetContent(object content)
{
Content = LPSConvert.GetObjectString(content, convertNoneLineAttribute: true);
}
/// <summary>
/// 获取消息内容(类)
/// </summary>
/// <typeparam name="T">类类型</typeparam>
public T GetContent<T>()
{
return (T)LPSConvert.GetStringObject(Content, typeof(T), convertNoneLineAttribute: true);
}
/// <summary>
/// 设置消息内容(字符串)
/// </summary>
public void SetContent(string content)
{
Content = content;
}
/// <summary>
/// 获取消息内容(字符串)
/// </summary>
public string GetContent()
{
return Content;
}
/// <summary>
/// 聊天结构
/// </summary>
public struct Chat
@ -106,4 +122,36 @@ public struct MPMessage
/// </summary>
public string SendName { get; set; }
}
/// <summary>
/// 交互结构
/// </summary>
public struct Feed
{
/// <summary>
/// 对方是否启用了数据计算 (并且未丢失小标)
/// </summary>
public bool EnableFunction { get; set; }
/// <summary>
/// 食物
/// </summary>
public Food Food { get; set; }
}
/// <summary>
/// 交互类型
/// </summary>
public enum Interact
{
/// <summary>
/// 摸身体
/// </summary>
TouchHead,
/// <summary>
/// 摸头
/// </summary>
TouchBody,
/// <summary>
/// 捏脸
/// </summary>
TouchPinch,
}
}

View File

@ -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;

View File

@ -121,21 +121,22 @@ public partial class MPFriends : WindowX, IMPFriend
return;
}
ImageSources.AddRange(mw.ImageSources);
//加载所有MOD
List<DirectoryInfo> Path = new List<DirectoryInfo>();
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<DirectoryInfo> Path = new List<DirectoryInfo>();
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<MPMOD> MPMODs = new List<MPMOD>();
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");
}
}
/// <summary>
/// 显示摸头情况 (无任何计算和传导)
/// </summary>
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))));
}
/// <summary>
/// 显示摸身体情况 (无任何计算和传导)
/// </summary>
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))));
}
/// <summary>
/// 显示摸身体情况 (无任何计算和传导)
/// </summary>
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))));
}
/// <summary>
/// 收到被互动通知
/// </summary>
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;
}
}
/// <summary>
/// 播放关闭动画并关闭,如果10秒后还未关闭则强制关闭
@ -368,10 +503,12 @@ public partial class MPFriends : WindowX, IMPFriend
/// </summary>
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);
}

View File

@ -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<IMPFriend> 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<Chat>());
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<Interact>())
{
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);
}
/// <summary>
/// 显示本体摸头情况 (会无损加心情)
/// </summary>
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))));
}
/// <summary>
/// 显示摸身体情况 (会无损加心情)
/// </summary>
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))));
}
/// <summary>
/// 显示本体捏脸情况 (会无损加心情)
/// </summary>
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))));
}
}