using LinePutScript.Localization.WPF; using Panuon.WPF.UI; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using static VPet_Simulator.Core.GraphHelper; using static VPet_Simulator.Core.GraphInfo; namespace VPet_Simulator.Core { public partial class Main { public const int TreeRND = 5; /// /// 处理说话内容 /// public event Action OnSay; /// /// 上次交互时间 /// public DateTime LastInteractionTime { get; set; } = DateTime.Now; /// /// 事件Timer /// public Timer EventTimer = new Timer(15000) { AutoReset = true, Enabled = true }; /// /// 说话,使用随机表情 /// public void SayRnd(string text, bool force = false, string desc = null) { Say(text, Core.Graph.FindName(GraphType.Say), force, desc); } /// /// 说话 /// /// 说话内容 /// 图像名 /// 描述 /// 强制显示图像 public void Say(string text, string graphname = null, bool force = false, string desc = null) { Task.Run(() => { OnSay?.Invoke(text); if (force || !string.IsNullOrWhiteSpace(graphname) && DisplayType.Type == GraphType.Default)//这里不使用idle是因为idle包括学习等 Display(graphname, AnimatType.A_Start, () => { Dispatcher.Invoke(() => { MsgBar.Show(Core.Save.Name, text, graphname, (string.IsNullOrWhiteSpace(desc) ? null : new TextBlock() { Text = desc, FontSize = 20, ToolTip = desc, HorizontalAlignment = HorizontalAlignment.Right })); }); DisplayBLoopingForce(graphname); }); else { Dispatcher.Invoke(() => { MsgBar.Show(Core.Save.Name, text, msgcontent: (string.IsNullOrWhiteSpace(desc) ? null : new TextBlock() { Text = desc, FontSize = 20, ToolTip = desc, HorizontalAlignment = HorizontalAlignment.Right })); }); } }); } /// /// 说话 /// /// 说话内容 /// 图像名 /// 消息内容 /// 强制显示图像 public void Say(string text, UIElement msgcontent, string graphname = null, bool force = false) { Task.Run(() => { OnSay?.Invoke(text); if (force || !string.IsNullOrWhiteSpace(graphname) && DisplayType.Type == GraphType.Default)//这里不使用idle是因为idle包括学习等 Display(graphname, AnimatType.A_Start, () => { Dispatcher.Invoke(() => { MsgBar.Show(Core.Save.Name, text, graphname, msgcontent); }); DisplayBLoopingForce(graphname); }); else { Dispatcher.Invoke(() => { MsgBar.Show(Core.Save.Name, text, msgcontent: msgcontent); }); } }); } int labeldisplaycount = 100; int labeldisplayhash = 0; Timer labeldisplaytimer = new Timer(10) { AutoReset = true, }; double labeldisplaychangenum1 = 0; double labeldisplaychangenum2 = 0; /// /// 显示消息弹窗Label /// /// 文本 /// 持续时间 public void LabelDisplayShow(string text, int time = 2000) { labeldisplayhash = text.GetHashCode(); Dispatcher.Invoke(() => { LabelDisplay.Content = text; LabelDisplay.Opacity = 1; LabelDisplay.Visibility = Visibility.Visible; labeldisplaycount = time / 10; labeldisplaytimer.Start(); }); } /// /// 显示消息弹窗Lable,自动统计数值变化 /// /// 文本, 使用{0:f2} /// 变化值1 /// 变化值2 /// 持续时间 public void LabelDisplayShowChangeNumber(string text, double changenum1, double changenum2 = 0, int time = 2000) { if (labeldisplayhash == text.GetHashCode()) { labeldisplaychangenum1 += changenum1; labeldisplaychangenum2 += changenum2; } else { labeldisplaychangenum1 = changenum1; labeldisplaychangenum2 = changenum2; labeldisplayhash = text.GetHashCode(); } Dispatcher.Invoke(() => { LabelDisplay.Content = string.Format(text, labeldisplaychangenum1, labeldisplaychangenum2); LabelDisplay.Opacity = 1; LabelDisplay.Visibility = Visibility.Visible; labeldisplaycount = time / 10; labeldisplaytimer.Start(); }); } public Work NowWork; /// /// 根据消耗计算相关数据 /// /// 过去时间倍率 public void FunctionSpend(double TimePass) { Core.Save.CleanChange(); Core.Save.StoreTake(); double freedrop = (DateTime.Now - LastInteractionTime).TotalMinutes; if (freedrop < 1) freedrop = 0.25 * TimePass; else freedrop = Math.Min(Math.Sqrt(freedrop) * TimePass / 2, Core.Save.FeelingMax / 400); switch (State) { case WorkingState.Empty: break; case WorkingState.Sleep: //睡觉不消耗 Core.Save.StrengthChange(TimePass * 2); if (Core.Save.StrengthFood <= 25) { Core.Save.StrengthChangeFood(TimePass / 2); } else if (Core.Save.StrengthFood >= 75) Core.Save.Health += TimePass * 2; if (Core.Save.StrengthDrink >= 25) { Core.Save.StrengthChangeDrink(TimePass / 2); } else if (Core.Save.StrengthDrink >= 75) Core.Save.Health += TimePass * 2; LastInteractionTime = DateTime.Now; break; case WorkingState.Work: if (NowWork == null) break; var needfood = TimePass * NowWork.StrengthFood; var needdrink = TimePass * NowWork.StrengthDrink; double efficiency = 0; int addhealth = -2; if (Core.Save.StrengthFood <= Core.Save.StrengthMax * 0.25) {//低状态低效率 Core.Save.StrengthChangeFood(-needfood / 2); efficiency += 0.25; if (Core.Save.Strength >= needfood) { Core.Save.StrengthChange(-needfood); efficiency += 0.1; } addhealth -= 2; } else { Core.Save.StrengthChangeFood(-needfood); efficiency += 0.5; if (Core.Save.StrengthFood >= 75) addhealth += Function.Rnd.Next(1, 3); } if (Core.Save.StrengthDrink <= Core.Save.StrengthMax * 0.25) {//低状态低效率 Core.Save.StrengthChangeDrink(-needdrink / 2); efficiency += 0.25; if (Core.Save.Strength >= needdrink) { Core.Save.StrengthChange(-needdrink); efficiency += 0.1; } addhealth -= 2; } else { Core.Save.StrengthChangeDrink(-needdrink); efficiency += 0.5; if (Core.Save.StrengthDrink >= 75) addhealth += Function.Rnd.Next(1, 3); } if (addhealth > 0) Core.Save.Health += addhealth * TimePass; var addmoney = Math.Max(0, TimePass * NowWork.MoneyBase * (2 * efficiency - 0.5)); if (NowWork.Type == Work.WorkType.Work) Core.Save.Money += addmoney; else Core.Save.Exp += addmoney; WorkTimer.GetCount += addmoney; if (NowWork.Type == Work.WorkType.Play) { LastInteractionTime = DateTime.Now; Core.Save.FeelingChange(-NowWork.Feeling * TimePass); } else Core.Save.FeelingChange(-freedrop * NowWork.Feeling); if (Core.Save.Mode == IGameSave.ModeType.Ill)//生病时候停止工作 WorkTimer.Stop(); break; default://默认 //饮食等乱七八糟的消耗 addhealth = -2; if (Core.Save.StrengthFood >= 50) { Core.Save.StrengthChangeFood(-TimePass); Core.Save.StrengthChange(TimePass); if (Core.Save.StrengthFood >= 75) addhealth += Function.Rnd.Next(1, 3); } else if (Core.Save.StrengthFood <= 25) { Core.Save.Health -= Function.Rnd.NextDouble() * TimePass; addhealth -= 2; } if (Core.Save.StrengthDrink >= 50) { Core.Save.StrengthChangeDrink(-TimePass); Core.Save.StrengthChange(TimePass); if (Core.Save.StrengthDrink >= 75) addhealth += Function.Rnd.Next(1, 3); } else if (Core.Save.StrengthDrink <= 25) { Core.Save.Health -= Function.Rnd.NextDouble() * TimePass; addhealth -= 2; } if (addhealth > 0) Core.Save.Health += addhealth * TimePass; Core.Save.StrengthChangeFood(-TimePass); Core.Save.StrengthChangeDrink(-TimePass); Core.Save.FeelingChange(-freedrop); break; } //if (Core.GameSave.Strength <= 40) //{ // Core.GameSave.Health -= Function.Rnd.Next(0, 1); //} Core.Save.Exp += TimePass; //感受提升好感度 if (Core.Save.Feeling >= 75) { if (Core.Save.Feeling >= 90) { Core.Save.Likability += TimePass; } Core.Save.Exp += TimePass * 2; Core.Save.Health += TimePass; } else if (Core.Save.Feeling <= 25) { Core.Save.Likability -= TimePass; Core.Save.Exp -= TimePass; } if (Core.Save.StrengthDrink <= 25) { Core.Save.Health -= Function.Rnd.Next(0, 1) * TimePass; Core.Save.Exp -= TimePass; } else if (Core.Save.StrengthDrink >= 75) Core.Save.Health += Function.Rnd.Next(0, 1) * TimePass; FunctionSpendHandle?.Invoke(); var newmod = Core.Save.CalMode(); if (Core.Save.Mode != newmod) { //切换显示动画 playSwitchAnimat(Core.Save.Mode, newmod); Core.Save.Mode = newmod; } //看情况播放停止工作动画 if (Core.Save.Mode == IGameSave.ModeType.Ill && State == WorkingState.Work) { WorkTimer.Stop(); } } private void playSwitchAnimat(IGameSave.ModeType before, IGameSave.ModeType after) { if (!(DisplayType.Type == GraphType.Default || DisplayType.Type == GraphType.Switch_Down || DisplayType.Type == GraphType.Switch_Up)) { return; } else if (before == after) { DisplayToNomal(); return; } else if (before < after) { Display(Core.Graph.FindGraph(Core.Graph.FindName(GraphType.Switch_Down), AnimatType.Single, before), () => playSwitchAnimat((IGameSave.ModeType)(((int)before) + 1), after)); } else { Display(Core.Graph.FindGraph(Core.Graph.FindName(GraphType.Switch_Up), AnimatType.Single, before), () => playSwitchAnimat((IGameSave.ModeType)(((int)before) - 1), after)); } } /// /// 状态计算Handle /// public event Action FunctionSpendHandle; /// /// 想要随机显示的接口 (return:是否成功) /// public List> RandomInteractionAction = new List>(); public bool IsIdel => (DisplayType.Type == GraphType.Default || DisplayType.Type == GraphType.Work) && !isPress; /// /// 每隔指定时间自动触发计算 可以关闭EventTimer后手动计算 /// public void EventTimer_Elapsed() { //所有Handle TimeHandle?.Invoke(this); if (Core.Controller.EnableFunction) { FunctionSpend(0.05); } else { //Core.Save.Mode = GameSave.ModeType.Happy; //Core.GameSave.Mode = GameSave.ModeType.Ill; Core.Save.Mode = NoFunctionMOD; } //UIHandle Dispatcher.Invoke(() => TimeUIHandle?.Invoke(this)); if (IsIdel) switch (Function.Rnd.Next(Math.Max(20, Core.Controller.InteractionCycle - CountNomal))) { case 0: case 1: case 2: //显示移动 DisplayMove(); break; case 3: case 4: case 5: //显示待机 DisplayIdel(); break; case 6: DisplayIdel_StateONE(); break; case 7: DisplaySleep(); break; case 8: case 9: case 10: //给其他显示留个机会 var list = RandomInteractionAction.ToList(); for (int i = Function.Rnd.Next(list.Count); 0 != list.Count; i = Function.Rnd.Next(list.Count)) { var act = list[i]; if (act.Invoke()) { break; } else { list.RemoveAt(i); } } break; } } /// /// 定点移动位置向量 /// public Point MoveTimerPoint = new Point(0, 0); /// /// 定点移动定时器 /// public Timer MoveTimer = new Timer(); /// /// 设置计算间隔 /// /// 计算间隔 public void SetLogicInterval(int Interval) { EventTimer.Interval = Interval; } private Timer SmartMoveTimer = new Timer(20 * 60) { AutoReset = true, }; /// /// 是否启用智能移动 /// private bool SmartMove; /// /// 设置移动模式 /// /// 允许移动 /// 启用智能移动 /// 智能移动周期 public void SetMoveMode(bool AllowMove, bool smartMove, int SmartMoveInterval) { MoveTimer.Enabled = false; if (AllowMove) { MoveTimerSmartMove = true; if (smartMove) { SmartMoveTimer.Interval = SmartMoveInterval; SmartMoveTimer.Start(); SmartMove = true; } else { SmartMoveTimer.Enabled = false; SmartMove = false; } } else { MoveTimerSmartMove = false; } } /// /// 当前状态 /// public WorkingState State = WorkingState.Nomal; /// /// 当前正在的状态 /// public enum WorkingState { /// /// 默认:啥都没干 /// Nomal, /// /// 正在干活/学习中 /// Work, /// /// 睡觉 /// Sleep, /// /// 旅游中 /// Travel, /// /// 其他状态,给开发者留个空位计算 /// Empty, } /// /// 获得工作列表分类 /// /// 所有工作 /// 所有学习 /// 所有娱乐 public void WorkList(out List ws, out List ss, out List ps) { ws = new List(); ss = new List(); ps = new List(); foreach (var w in Core.Graph.GraphConfig.Works) { switch (w.Type) { case Work.WorkType.Study: ss.Add(w); break; case Work.WorkType.Work: ws.Add(w); break; case Work.WorkType.Play: ps.Add(w); break; } } } /// /// 工作检测 /// public Func WorkCheck; /// /// 开始工作 /// /// 工作内容 public void StartWork(Work work) { if (!Core.Controller.EnableFunction || Core.Save.Mode != IGameSave.ModeType.Ill) if (!Core.Controller.EnableFunction || Core.Save.Level >= work.LevelLimit) if (State == Main.WorkingState.Work && NowWork.Name == work.Name) WorkTimer.Stop(); else { if (WorkCheck != null && !WorkCheck.Invoke(work)) return; WorkTimer.Start(work); } else MessageBoxX.Show(LocalizeCore.Translate("您的桌宠等级不足{0}/{2}\n无法进行{1}", Core.Save.Level.ToString() , work.NameTrans, work.LevelLimit), LocalizeCore.Translate("{0}取消", work.NameTrans)); else MessageBoxX.Show(LocalizeCore.Translate("您的桌宠 {0} 生病啦,没法进行{1}", Core.Save.Name, work.NameTrans), LocalizeCore.Translate("{0}取消", work.NameTrans)); ToolBar.Visibility = Visibility.Collapsed; } } }