/// <summary> /// プロットの再設定 /// </summary> /// <param name="user"></param> /// <param name="plots"></param> public void SetPlotAgain(UserOrNpcInfo user, List <int> plots) { if (Plots.Keys.Count == 0 && OldPlots.Count != 0) { Plots = OldPlots.Last(); } SetPlot(user, plots); }
public void AddEmotion(UserOrNpcInfo target, Emotion emotion) { if (Emotions.ContainsKey(target)) { Emotions[target] = emotion; } else { Emotions.Add(target, emotion); } }
/// <summary> /// プロットを設定 /// </summary> /// <param name="user"></param> /// <param name="plots"></param> public void SetPlot(UserOrNpcInfo user, List <int> plots) { if (Plots.Keys.Contains(user)) { Plots[user] = plots; } else { Plots.Add(user, plots); } }
/// <summary> /// #ステータス arg のargの部分を渡すことで適切な処理を行う /// </summary> /// <param name="argText"></param> /// <returns></returns> private string Excute(string argText) { var args = argText.ToNarrow().Trim().Split(' ').ToList(); args.RemoveAll(s => s == ""); if (args.Count == 0) { return("引数を指定してね"); } // 第一引数がヘルプ if (args[0] == "help" || args[0] == "usage" || args[0] == "ヘルプ") { return(Help()); } if (args.Count >= 2) { try { user = Server.GetMatchPlayer(args[0]); } catch (Exception e) { return(e.Message); } argText = argText.Substring(args[0].Length).Trim(); if (Regex.IsMatch(argText, @".+(\+=|-=).+")) { return(AddStatus(argText)); } if (Regex.IsMatch(argText, @".+=.+")) { return(SetStatus(argText)); } if (Regex.IsMatch(argText, @".+\s+削除")) { return(RemoveStatus(argText)); } if (Regex.IsMatch(argText, @"(.+)(\+\+|--)")) { return(IncrementStatus(argText)); } } return($"{argText}に一致する操作はないよ。helpを呼んでね"); }
public void AddSecret(UserOrNpcInfo target) { if (!target.IsNpc && Secrets.Any(u => u.UserId == ((UserInfo)target).User.Id)) { return; } else if (Secrets.Any(u => u.Name == target.NickOrName)) { return; } if (target.IsNpc) { Secrets.Add(new Secret(target.NickOrName)); } else { Secrets.Add(new Secret(((UserInfo)target).User)); } }
public static void MakeRelationGraph(List <UserOrNpcInfo> users, string path = "./relation.png") { int fontSize = 15; Font font = new Font("メイリオ", fontSize); Font smallFont = new Font("メイリオ", fontSize - 3); int r = 150; var img = new Bitmap(r * 2 + 200, r * 2 + 200); var g = Graphics.FromImage(img); g.FillRectangle(Brushes.White, g.VisibleClipBounds); var drawNames = new List <DrawStringData>(); var drawSecrets = new List <DrawStringData>(); int n = users.Count(); // x, yを取得 for (int i = 0; i < n; i++) { var u = users[i]; var name = u.NickOrName; var size = g.MeasureString(name, font); u.StringSize = size; double PiI = Math.PI * (i + 1); int x = (int)Math.Round(r * Math.Cos(2 * PiI / n - Math.PI / 2)) + r + (int)(size.Width / 2); int y = (int)Math.Round(r * Math.Sin(2 * PiI / n - Math.PI / 2)) + r + (int)(size.Height / 2); var discordColor = new Discord.Color(0, 0, 0); if (!u.IsNpc && ((UserInfo)u).User.Roles != null && ((UserInfo)u).User.Roles.Count() > 0) { discordColor = ((UserInfo)u).User.Roles.First().Color; } var color = System.Drawing.Color.FromArgb(discordColor.R, discordColor.G, discordColor.B); var drawNameData = new DrawStringData(name, new Point(x, y), color, font); drawNames.Add(drawNameData); int tx = (int)(x - (size.Width / 2)); int ty = (int)(y - (size.Height / 2)); u.Point = new Point(tx, ty); // 秘密 Point secretP = new Point(u.Point.X, (int)(u.Point.Y + drawNameData.GetDrawSize(g).Height + 3)); bool firstSecret = true; foreach (var sec in u.Secrets) { if (firstSecret) { var drawData = new DrawStringData("秘密:", secretP, System.Drawing.Color.Black, smallFont); secretP.X += (int)(drawData.GetDrawSize(g).Width); drawSecrets.Add(drawData); firstSecret = false; } var drawSecretData = new DrawStringData(sec.Name + " ", secretP, sec.Color, smallFont); secretP.Y += (int)(drawSecretData.GetDrawSize(g).Height); drawSecrets.Add(drawSecretData); } } // ------------ 線描画 ----------------------- var drawn = new List <Tuple <UserOrNpcInfo, UserOrNpcInfo> >(); // 描画済みペア foreach (var u in users) { foreach (var emo in u.Emotions) { System.Drawing.Color endColor = System.Drawing.Color.Black; switch (emo.Value.Type) { case EmotionType.plus: endColor = System.Drawing.Color.Orange; break; case EmotionType.minus: endColor = System.Drawing.Color.Blue; break; } UserOrNpcInfo target = users.Find(x => x == emo.Key); // 描画済みならスキップ if (drawn.Contains(new Tuple <UserOrNpcInfo, UserOrNpcInfo>(target, u))) { continue; } System.Drawing.Color startColor = System.Drawing.Color.Gray; if (target.Emotions.ContainsKey(u)) { if (target.Emotions[u].Type == EmotionType.plus) { startColor = System.Drawing.Color.Orange; } else { startColor = System.Drawing.Color.Blue; } } // 始点終点 Point startPoint = new Point(u.Point.X + (int)(u.StringSize.Width / 2), u.Point.Y + (int)(u.StringSize.Height / 2)); Point endPoint = new Point(target.Point.X + (int)(target.StringSize.Width / 2), target.Point.Y + (int)(target.StringSize.Height / 2)); // 中点 Point middle = new Point((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2); var b1 = new SolidBrush(startColor); var b2 = new SolidBrush(endColor); var cap = new AdjustableArrowCap(5, 5, false); Pen p1 = new Pen(b1, 2) { CustomStartCap = cap }; Pen p2 = new Pen(b2, 2) { CustomEndCap = cap }; g.DrawLine(p1, startPoint, middle); g.DrawLine(p2, middle, endPoint); b1.Dispose(); b2.Dispose(); drawn.Add(new Tuple <UserOrNpcInfo, UserOrNpcInfo>(u, target)); } } // ---------------- ユーザー名描画 ---------------------------- foreach (var data in drawNames) { data.Draw(g); } // --------------- TODO:秘密など描画 ------------------------- foreach (var data in drawSecrets) { data.Draw(g); } img.Save(path, System.Drawing.Imaging.ImageFormat.Png); font.Dispose(); g.Dispose(); }
/// <summary> /// プレイヤー情報をファイルから読み込む /// </summary> public void LoadPlayersInfo() { var result = new List <UserOrNpcInfo>(); var lines = System.IO.File.ReadLines($"{Program.serverDataFolder}/{Server.Id}.txt"); User nowUser = null; Point nowPoint = new Point(0, 0); var nowEmotions = new Dictionary <UserOrNpcInfo, Emotion>(); var nowSecrets = new List <Secret>(); var nowStatus = new Dictionary <string, object>(); string nowName = ""; bool skipToNextUser = false; foreach (var line in lines) { if (line.Trim() == "[User]") { nowPoint = new Point(0, 0); nowEmotions = new Dictionary <UserOrNpcInfo, Emotion>(); nowSecrets = new List <Secret>(); nowStatus = new Dictionary <string, object>(); nowUser = null; nowName = ""; skipToNextUser = false; continue; } if (skipToNextUser) { continue; } if (line.Trim() == "[UserEnd]") { if (nowUser == null) { result.Add(new NpcInfo(nowName, nowEmotions, nowSecrets, nowStatus)); } else { result.Add(new UserInfo(nowUser, nowEmotions, nowSecrets, nowStatus)); } continue; } var splited = line.Split('=').ToArray(); if (splited.Length < 2) { continue; } string key = splited[0], value = splited[1]; switch (key) { case "Id": ulong id = ulong.Parse(value); try { nowUser = Server.Users.First(u => u.Id == id); } catch { } break; case "XY": var xy = value.Split(',').Select(a => int.Parse(a)).ToArray(); nowPoint = new Point(xy[0], xy[1]); break; case "Secret": nowSecrets.Add(Secret.FromCSV(value)); break; case "Status": nowStatus = UserInfo.StatusFormCSV(line.Substring("Status=".Length)); break; case "Name": nowName = value; break; default: break; } } Players = result; AllUsers = new List <UserOrNpcInfo>(Players); // Emotion UserOrNpcInfo nowInfo = null; foreach (var line in lines) { if (line.Trim() == "[User]") { nowInfo = null; nowEmotions = new Dictionary <UserOrNpcInfo, Emotion>(); continue; } if (line.Trim() == "[UserEnd]") { if (nowInfo != null) { nowInfo.Emotions = nowEmotions; } continue; } var splited = line.Split('=').ToArray(); if (splited.Length < 2) { continue; } string key = splited[0], value = splited[1]; if (key == "Name") { nowInfo = AllUsers.First(i => i.Name == value); } else if (key == "Emotion") { var nickAndEmo = value.Split(','); string toName = nickAndEmo[0].Trim(); Emotion emo = new Emotion(nickAndEmo[1], Emotion.ParseEmotionType(nickAndEmo[2])); UserOrNpcInfo toUser = null; try { toUser = AllUsers.First(u => u.NickOrName == toName); } catch { continue; } if (toUser == null) { continue; } nowEmotions.Add(toUser, emo); } } }