From 82f07c959dc7a87251b4617e462003471e3cc071 Mon Sep 17 00:00:00 2001 From: TrueDoctor Date: Mon, 9 Apr 2018 00:54:19 +0200 Subject: Refactoring and Cleanup --- DiscoBot/App.config | 4 - DiscoBot/Audio.cs | 27 -- DiscoBot/AudioService.cs | 88 ------- DiscoBot/Auxiliary/CommandExtension.cs | 46 ++++ DiscoBot/Auxiliary/Dice.cs | 12 + DiscoBot/Auxiliary/KampfTalent.cs | 18 ++ DiscoBot/Auxiliary/Misc.cs | 51 ++++ DiscoBot/Auxiliary/SpellCorrect.cs | 134 ++++++++++ DiscoBot/Auxiliary/Talent.cs | 37 +++ DiscoBot/Auxiliary/Vorteil.cs | 15 ++ DiscoBot/Character.cs | 309 ----------------------- DiscoBot/Characters/Character.cs | 312 +++++++++++++++++++++++ DiscoBot/Characters/ICharacter.cs | 17 ++ DiscoBot/Characters/NPC.cs | 106 ++++++++ DiscoBot/CommandExtension.cs | 47 ---- DiscoBot/Commands.cs | 449 --------------------------------- DiscoBot/Commands/CommandTypes.cs | 12 + DiscoBot/Commands/Gm.cs | 103 ++++++++ DiscoBot/Commands/List.cs | 76 ++++++ DiscoBot/Commands/NpcCommands.cs | 37 +++ DiscoBot/Commands/Test.cs | 47 ++++ DiscoBot/Commands/Utility.cs | 32 +++ DiscoBot/Commands/Voice.cs | 67 +++++ DiscoBot/DSA.cs | 44 ++-- DiscoBot/DiscoBot.csproj | 25 +- DiscoBot/ICharacter.cs | 23 -- DiscoBot/Misc.cs | 212 ---------------- DiscoBot/NPC.cs | 107 -------- DiscoBot/Program.cs | 73 +++--- 29 files changed, 1205 insertions(+), 1325 deletions(-) delete mode 100644 DiscoBot/Audio.cs delete mode 100644 DiscoBot/AudioService.cs create mode 100644 DiscoBot/Auxiliary/CommandExtension.cs create mode 100644 DiscoBot/Auxiliary/Dice.cs create mode 100644 DiscoBot/Auxiliary/KampfTalent.cs create mode 100644 DiscoBot/Auxiliary/Misc.cs create mode 100644 DiscoBot/Auxiliary/SpellCorrect.cs create mode 100644 DiscoBot/Auxiliary/Talent.cs create mode 100644 DiscoBot/Auxiliary/Vorteil.cs delete mode 100644 DiscoBot/Character.cs create mode 100644 DiscoBot/Characters/Character.cs create mode 100644 DiscoBot/Characters/ICharacter.cs create mode 100644 DiscoBot/Characters/NPC.cs delete mode 100644 DiscoBot/CommandExtension.cs delete mode 100644 DiscoBot/Commands.cs create mode 100644 DiscoBot/Commands/CommandTypes.cs create mode 100644 DiscoBot/Commands/Gm.cs create mode 100644 DiscoBot/Commands/List.cs create mode 100644 DiscoBot/Commands/NpcCommands.cs create mode 100644 DiscoBot/Commands/Test.cs create mode 100644 DiscoBot/Commands/Utility.cs create mode 100644 DiscoBot/Commands/Voice.cs delete mode 100644 DiscoBot/ICharacter.cs delete mode 100644 DiscoBot/Misc.cs delete mode 100644 DiscoBot/NPC.cs (limited to 'DiscoBot') diff --git a/DiscoBot/App.config b/DiscoBot/App.config index 5740218..d08a333 100644 --- a/DiscoBot/App.config +++ b/DiscoBot/App.config @@ -14,10 +14,6 @@ - - - - diff --git a/DiscoBot/Audio.cs b/DiscoBot/Audio.cs deleted file mode 100644 index 68c860c..0000000 --- a/DiscoBot/Audio.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - using System.Diagnostics; - - class Audio - { - private Process CreateStream(string path) - { - var ffmpeg = new ProcessStartInfo - { - FileName = "ffmpeg", - Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 pipe:1", - UseShellExecute = false, - RedirectStandardOutput = true, - }; - return Process.Start(ffmpeg); - } - } - - -} diff --git a/DiscoBot/AudioService.cs b/DiscoBot/AudioService.cs deleted file mode 100644 index bb4d21e..0000000 --- a/DiscoBot/AudioService.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Collections.Concurrent; -using System.Diagnostics; -using System.IO; -using System.Threading.Tasks; -using Discord; -using Discord.Audio; - -namespace DiscoBot -{ - public class AudioService - { - private readonly ConcurrentDictionary ConnectedChannels = - new ConcurrentDictionary(); - - public async Task JoinAudio(IGuild guild, IVoiceChannel target) - { - IAudioClient client; - if (ConnectedChannels.TryGetValue(guild.Id, out client)) - { - return; - } - - if (target.Guild.Id != guild.Id) - { - return; - } - - var audioClient = await target.ConnectAsync(); - - if (ConnectedChannels.TryAdd(guild.Id, audioClient)) - { - // If you add a method to log happenings from this service, - // you can uncomment these commented lines to make use of that. - //await Log(LogSeverity.Info, $"Connected to voice on {guild.Name}."); - } - } - - public async Task LeaveAudio(IGuild guild) - { - IAudioClient client; - if (ConnectedChannels.TryRemove(guild.Id, out client)) - { - await client.StopAsync(); - //await Log(LogSeverity.Info, $"Disconnected from voice on {guild.Name}."); - } - } - - public async Task SendAudioAsync(IGuild guild, IMessageChannel channel, string path) - { - // Your task: Get a full path to the file if the value of 'path' is only a filename. - if (!File.Exists(path)) - { - await channel.SendMessageAsync("File does not exist."); - return; - } - - IAudioClient client; - if (ConnectedChannels.TryGetValue(guild.Id, out client)) - { - //await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}"); - using (var ffmpeg = Process.Start(path)) - using (var stream = client.CreatePCMStream(AudioApplication.Music)) - { - try - { - await ffmpeg.StandardOutput.BaseStream.CopyToAsync(stream); - } - finally - { - await stream.FlushAsync(); - } - } - } - } - - private Process CreateStream(string path) - { - return Process.Start( - new ProcessStartInfo - { - FileName = "ffmpeg.exe", - Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1", - UseShellExecute = false, - RedirectStandardOutput = true - }); - } - } -} diff --git a/DiscoBot/Auxiliary/CommandExtension.cs b/DiscoBot/Auxiliary/CommandExtension.cs new file mode 100644 index 0000000..6690d03 --- /dev/null +++ b/DiscoBot/Auxiliary/CommandExtension.cs @@ -0,0 +1,46 @@ +namespace DiscoBot.Auxiliary +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + using System.Threading; + using System.Threading.Tasks; + + using Discord; + using Discord.Commands; + + public static class CommandExtension + { + public static async Task ReplyTimedAsync(this ModuleBase m, string message, TimeSpan time) + { + var token = message.GetHashCode(); + var send = m.Context.Channel.SendMessageAsync($"#{token}\n```xl\n{message}```", true); + + var barInvoker = new BackgroundWorker(); + barInvoker.DoWork += delegate + { + Thread.Sleep(time); + Delete(token, m); + }; + + await send; + barInvoker.RunWorkerAsync(); + } + + private static void Delete(int token, ModuleBase m) + { + var messagesAsync = m.Context.Channel.GetMessagesAsync(); + Task.WaitAll(messagesAsync.ToArray()); + var list = messagesAsync.ToEnumerable().ToList(); + var messages = new List(); + foreach (var task in list) + { + messages.AddRange(task.ToList()); + } + + m.Context.Channel.DeleteMessagesAsync( + messages.Where(x => x.Content.StartsWith($"#{token}\n") && x.Author.IsBot)); + } + } +} diff --git a/DiscoBot/Auxiliary/Dice.cs b/DiscoBot/Auxiliary/Dice.cs new file mode 100644 index 0000000..16a8a77 --- /dev/null +++ b/DiscoBot/Auxiliary/Dice.cs @@ -0,0 +1,12 @@ +namespace DiscoBot.Auxiliary +{ + public static class Dice // roll it! + { + private static readonly System.Random Rnd = new System.Random(); + + public static int Roll(int d = 20) + { + return Rnd.Next(d) + 1; + } + } +} diff --git a/DiscoBot/Auxiliary/KampfTalent.cs b/DiscoBot/Auxiliary/KampfTalent.cs new file mode 100644 index 0000000..05b7c9e --- /dev/null +++ b/DiscoBot/Auxiliary/KampfTalent.cs @@ -0,0 +1,18 @@ +namespace DiscoBot.Auxiliary +{ + public class KampfTalent + { + public KampfTalent(string name, int at, int pa) + { + this.Name = name; + this.At = at; + this.Pa = pa; + } + + public string Name { get; set; } + + public int At { get; set; } + + public int Pa { get; set; } + } +} diff --git a/DiscoBot/Auxiliary/Misc.cs b/DiscoBot/Auxiliary/Misc.cs new file mode 100644 index 0000000..2531f12 --- /dev/null +++ b/DiscoBot/Auxiliary/Misc.cs @@ -0,0 +1,51 @@ +namespace DiscoBot.Auxiliary +{ + using System; + using System.Linq; + using System.Text; + + public static class Misc + { + private static readonly Random Rand = new Random(); + + // use: 4w6 +4 + public static string Roll(string input) + { + var output = new StringBuilder(); + var strings = input.Split('w', 'd').ToList(); + int count = Convert.ToInt32(strings[0]); + strings = strings[1].Split(' ').ToList(); + int d = Convert.ToInt32(strings[0]); + + if (strings.Count > 0) + { + } + + int sum = 0; + for (int i = 0; i < count; i++) + { + var roll = Dice.Roll(d); + sum += roll; + output.Append("[" + roll + "] "); + } + + if (count > 1) + { + output.Append("sum: " + sum); + } + + return output.ToString(); + } + + public static double Random(double stdDev = 1, double mean = 0) + { + double u1 = Rand.NextDouble(); // uniform(0,1) random doubles + double u2 = Rand.NextDouble(); + double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * + Math.Sin(2.0 * Math.PI * u2); // random normal(0,1) + double randNormal = + mean + stdDev * randStdNormal; // random normal(mean,stdDev^2) + return randNormal; + } + } +} diff --git a/DiscoBot/Auxiliary/SpellCorrect.cs b/DiscoBot/Auxiliary/SpellCorrect.cs new file mode 100644 index 0000000..8c5741b --- /dev/null +++ b/DiscoBot/Auxiliary/SpellCorrect.cs @@ -0,0 +1,134 @@ +namespace DiscoBot.Auxiliary +{ + using System; + using System.Diagnostics; + using System.Linq; + + public class SpellCorrect : StringComparer + { + public override int Compare(string x, string y) + { + if (string.IsNullOrEmpty(x)) + { + throw new ArgumentException("message", nameof(x)); + } + + if (string.IsNullOrEmpty(y)) + { + throw new ArgumentException("message", nameof(y)); + } + + if (x.Equals(y)) + { + return 0; + } + + x = x.ToLower(); + y = y.ToLower(); + if (x.Equals(y)) + { + return 1; + } + + var subs = y.Split(' ', '/'); + int score = subs.Count(); + foreach (string s in subs) + { + if (s.Equals(x)) + { + score--; + } + } + + if (score < subs.Count()) + { + return score + 1; + } + + return 100000 - (int)(this.CompareExact(x, y) * 1000.0); + /*if (y.Contains(x)) + return 6;*/ + } + + public override bool Equals(string x, string y) + { + Debug.Assert(x != null, nameof(x) + " != null"); + return x.Equals(y); + } + + public override int GetHashCode(string obj) + { + throw new NotImplementedException(); + } + + public double CompareExact(string s, string q) + { + int i, j; + const double Match = 3.0; + const double Gap = -2.0; + const double Mismatch = -2.0; + + double decay; + + double[,] matrix = new double[s.Length + 1, q.Length + 1]; + double max = 0.0; + matrix[0, 0] = 0.0; + + for (i = 1; i < s.Length; i++) + { + matrix[i, 0] = 0.0; + } + + for (i = 1; i < q.Length; i++) + { + matrix[0, i] = 0.0; + } + + for (i = 1; i <= s.Length; i++) + { + for (j = 1; j <= q.Length; j++) + { + decay = j / (double)(s.Length * 1000); + double add = s[i - 1] == q[j - 1] ? (Match - decay) : Mismatch; + double score = matrix[i - 1, j - 1] + add; + + if (score < (matrix[i - 1, j] + Gap)) + { + score = matrix[i - 1, j] + Gap; + } + + if (score < (matrix[i, j - 1] + Gap)) + { + score = matrix[i, j - 1] + Gap; + } + + if (i > 1 && j > 1) + { + if (s[i - 1] == q[j - 2] && s[i - 2] == q[j - 1]) + { + add = (3 / 2.0) * Match - decay; + if (score < matrix[i - 2, j - 2] + add) + { + score = matrix[i - 2, j - 2] + add; + } + } + } + + if (score < 0) + { + score = 0; + } + + if (max < score) + { + max = score; + } + + matrix[i, j] = score; + } + } + + return max; + } + } +} diff --git a/DiscoBot/Auxiliary/Talent.cs b/DiscoBot/Auxiliary/Talent.cs new file mode 100644 index 0000000..969304c --- /dev/null +++ b/DiscoBot/Auxiliary/Talent.cs @@ -0,0 +1,37 @@ +namespace DiscoBot.Auxiliary +{ + using System; + + public class Talent // talent objekt + { + public Talent(string name, string probe, int value) + { + this.Name = name; + this.Probe = probe; + this.Value = value; + } + + public string Name { get; set; } + + public string Probe { get; set; } + + public int Value { get; set; } + + public string[] Test() // turn XX/XX/XX into string[]{XX,XX,XX} + { + var temp = this.Probe.Split('/'); + for (var index = 0; index < temp.Length; index++) + { + temp[index] = temp[index].Replace("/", string.Empty); + } + + return temp; + } + + public int CheckName(string quarry) + { + var sc = (StringComparer)new SpellCorrect(); + return sc.Compare(quarry, this.Name); + } + } +} diff --git a/DiscoBot/Auxiliary/Vorteil.cs b/DiscoBot/Auxiliary/Vorteil.cs new file mode 100644 index 0000000..823305c --- /dev/null +++ b/DiscoBot/Auxiliary/Vorteil.cs @@ -0,0 +1,15 @@ +namespace DiscoBot.Auxiliary +{ + public class Vorteil // talent objekt + { + public Vorteil(string name, int value = 0) + { + this.Name = name; + this.Value = value; + } + + public string Name { get; set; } + + public int Value { get; set; } + } +} diff --git a/DiscoBot/Character.cs b/DiscoBot/Character.cs deleted file mode 100644 index 18b6213..0000000 --- a/DiscoBot/Character.cs +++ /dev/null @@ -1,309 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml; - -namespace DiscoBot -{ - public class Character : ICharacter - { - public string Name { get; set; } //charname - public Dictionary Eigenschaften = new Dictionary(); //char porperties - public List Talente = new List(); //ist of talent objects (talents and spells) - public List Kampftalente = new List(); //list of combat objects - public List Vorteile = new List(); - - public Dictionary Proptable = new Dictionary(); //KK -> Körperkraft - - - public Character(String path) - { - Load(path); //load - Proptable.Add("MU", "Mut"); //routing - Proptable.Add("KL", "Klugheit"); - Proptable.Add("IN", "Intuition"); - Proptable.Add("CH", "Charisma"); - Proptable.Add("FF", "Fingerfertigkeit"); - Proptable.Add("GE", "Gewandtheit"); - Proptable.Add("KO", "Konstitution"); - Proptable.Add("KK", "Körperkraft"); - } - - public Character(Character c, string name, int stDv = 2) - { - Proptable.Add("MU", "Mut"); //routing - Proptable.Add("KL", "Klugheit"); - Proptable.Add("IN", "Intuition"); - Proptable.Add("CH", "Charisma"); - Proptable.Add("FF", "Fingerfertigkeit"); - Proptable.Add("GE", "Gewandtheit"); - Proptable.Add("KO", "Konstitution"); - Proptable.Add("KK", "Körperkraft"); - this.Proptable.Add("**", "Klugheit"); - - this.Name = name; - foreach (var i in c.Eigenschaften) - { - this.Eigenschaften.Add(i.Key, i.Value + (int)Math.Round(Misc.Random(stDv))); - } - - foreach (var i in c.Vorteile) - { - this.Vorteile.Add(new Vorteil(i.name, i.value + (int)Math.Round(Misc.Random(stDv)))); - } - - foreach (var i in c.Talente) - { - this.Talente.Add(new Talent(i.name, i.probe, i.value + (int)Math.Round(Misc.Random(stDv)))); - } - - foreach (var i in c.Kampftalente) - { - this.Kampftalente.Add(new Kampf(i.name, i.at + (int)Math.Round(Misc.Random(stDv)), i.pa + (int)Math.Round(Misc.Random(stDv)))); - } - } - - private void Load(string path) - { - XmlTextReader reader = new XmlTextReader(path); - while (reader.Read()) //read until he hits keywords - { - if (reader.NodeType == XmlNodeType.Element) - { - - switch (reader.Name) - { - case "Wesen": - reader.Skip(); - break; - case "held": - Name = reader.GetAttribute("name"); //name - break; - case "eigenschaft": - Eigenschaften.Add( - reader.GetAttribute("name"), - Convert.ToInt32(reader.GetAttribute("value")) - + Convert.ToInt32(reader.GetAttribute("mod"))); - break; - case "vt": - reader.Read(); - while (reader.Name.Equals("vorteil")) - { - try - { - this.Vorteile.Add(new Vorteil( - reader.GetAttribute("name"), - Convert.ToInt32(reader.GetAttribute("value")))); - } - catch - { - this.Vorteile.Add(new Vorteil(reader.GetAttribute("name"))); - } - reader.Read(); - } - - break; - case "talentliste": - reader.Read(); - while (reader.Name.Equals("talent")) - { - Talente.Add( - new Talent( - reader.GetAttribute("name"), - reader.GetAttribute("probe").Remove(0, 2).Trim(')'), - Convert.ToInt32(reader.GetAttribute("value")))); - reader.Read(); - } - break; - case "zauberliste": - reader.Read(); - while (reader.Name.Equals("zauber")) - { - Talente.Add( - new Talent( - reader.GetAttribute("name"), - reader.GetAttribute("probe").Remove(0, 2).Trim(')'), - Convert.ToInt32(reader.GetAttribute("value")))); - reader.Read(); - } - break; - case "kampfwerte": - string atname = reader.GetAttribute("name"); - reader.Read(); - int at = Convert.ToInt32(reader.GetAttribute("value")); - reader.Read(); - int pa = Convert.ToInt32(reader.GetAttribute("value")); - Kampftalente.Add(new Kampf(atname, at, pa)); - break; - } - } - } - - - } - - public string TestTalent(string talent, int erschwernis = 0) //Talentprobe - { - try - { - var output = new StringBuilder(); - var sc = new SpellCorrect(); - var ttalent = Talente.OrderBy(x => sc.Compare(talent, x.name)).First(); - - var deug = Talente.OrderBy(x => sc.Compare(talent, x.name)); - var fit = deug.Select(x => sc.Compare(talent, x.name)); - - if (sc.Compare(talent, ttalent.name) > 94100) throw new Exception(); - - var props = ttalent.Test(); //get the required properties - int tap = ttalent.value; //get tap - var werte = props.Select(p => this.Eigenschaften[this.Proptable[p]]).ToList(); - - output.AppendFormat( - "{0} würfelt: {1} \n{2} - {3} taw:{4} {5} \n", - this.Name, - ttalent.name, - ttalent.probe, - String.Join("/", werte), - ttalent.value, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - - output.Append(" "); - tap -= erschwernis; - int gesamt_erschwernis = tap; - if (gesamt_erschwernis < 0) - { - tap = 0; - for (int i = 0; i <= 2; i++) //foreach property, dice and tap - { - int temp = dice.Roll(); - int eigenschaft = Eigenschaften[Proptable[props[i]]]; - - if (eigenschaft - gesamt_erschwernis < temp) - { - tap -= temp - eigenschaft + gesamt_erschwernis; - } - - output.Append($"[{temp}]"); //add to string - } - - if (tap >= 0) - { - tap = 1; - } - } - else - { - for (int i = 0; i <= 2; i++) //foreach property, dice and tap - { - int temp = dice.Roll(); - int eigenschaft = Eigenschaften[Proptable[props[i]]]; - - if (eigenschaft < temp) - { - tap -= temp - eigenschaft; - } - output.Append($"[{temp}]"); //add to string - } - } - - tap = tap == 0 ? 1 : tap; - - output.AppendFormat(" tap: {0,2}", tap); - - return output.ToString(); //return output - } - catch (Exception) - { - throw new Exception( - $"{talent} nicht vorhanden! Besitzt {Name} {talent} nicht? \n Oder ist {talent} falsch geschrieben?"); - } - } - - public string TestEigenschaft(string eigenschaft, int erschwernis = 0) - { - var output = new StringBuilder(); - var prop = this.Proptable[eigenschaft.ToUpper()]; - int tap = this.Eigenschaften[prop]; - output.AppendFormat( - "{0}-Eigenschaftsprobe ew:{1} {2} \n", - prop, - tap, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - int roll = dice.Roll(); - output.Append($"Gewürfelt: {roll} übrig: {tap - roll - erschwernis}"); - return output.ToString(); - } - - public string Angriff(string talent, int erschwernis = 0) //prety self explanetory - { - var output = new StringBuilder(); - var sc = new SpellCorrect(); - var attack = Kampftalente.OrderBy(x => sc.Compare(talent, x.name)).First(); - if (sc.Compare(talent, attack.name) > 94) - { - return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; - } - - int tap = attack.at; - output.AppendFormat("{0}-Angriff taw:{1} {2} \n", - attack.name, - tap, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - - int temp = dice.Roll(); - output.Append(temp - erschwernis); - return output.ToString(); - } - public string Parade(string talent, int erschwernis = 0) - { - var output = new StringBuilder(); - var sc = new SpellCorrect(); - var attack = Kampftalente.OrderBy(x => sc.Compare(talent, x.name)).First(); - - if (sc.Compare(talent, attack.name) > 94) - { - return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; - } - - int tap = attack.pa; - output.AppendFormat( - "{0}-Parade taw:{1} {2}\n", - attack.name, - tap, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - - int temp = dice.Roll(); - output.Append(temp - erschwernis); - return output.ToString(); - } - - public string Fernkampf(string talent, int erschwernis = 0) - { - var output = new StringBuilder(); - var sc = new SpellCorrect(); - int fk = Eigenschaften["fk"]; - var attack = Talente.OrderBy(x => sc.Compare(talent, x.name)).First(); - if(sc.Compare(talent, attack.name) > 94) - { - return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; - } - - int tap = attack.value; - output.AppendFormat( - "{0} taw:{1} {2} \n", - attack.name, - tap, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - tap -= erschwernis; - int temp = dice.Roll(); - tap -= temp > fk ? temp - fk : 0; - output.Append($"W20: {temp} tap: {tap}"); - return output.ToString(); - } - - } - -} diff --git a/DiscoBot/Characters/Character.cs b/DiscoBot/Characters/Character.cs new file mode 100644 index 0000000..a78e613 --- /dev/null +++ b/DiscoBot/Characters/Character.cs @@ -0,0 +1,312 @@ +namespace DiscoBot.Characters +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Xml; + + using DiscoBot.Auxiliary; + + public class Character : ICharacter + { + public Character() + { + this.PropTable.Add("MU", "Mut"); // routing + this.PropTable.Add("KL", "Klugheit"); + this.PropTable.Add("IN", "Intuition"); + this.PropTable.Add("CH", "Charisma"); + this.PropTable.Add("FF", "Fingerfertigkeit"); + this.PropTable.Add("GE", "Gewandtheit"); + this.PropTable.Add("KO", "Konstitution"); + this.PropTable.Add("KK", "Körperkraft"); + } + + public Character(string path) : this() + { + this.Load(path); // load + } + + public Character(Character c, string name, int stDv = 2) : this() + { + this.Name = name; + foreach (var i in c.Eigenschaften) + { + this.Eigenschaften.Add(i.Key, i.Value + (int)Math.Round(Misc.Random(stDv))); + } + + foreach (var i in c.Vorteile) + { + this.Vorteile.Add(new Vorteil(i.Name, i.Value + (int)Math.Round(Misc.Random(stDv)))); + } + + foreach (var i in c.Talente) + { + this.Talente.Add(new Talent(i.Name, i.Probe, i.Value + (int)Math.Round(Misc.Random(stDv)))); + } + + foreach (var i in c.Kampftalente) + { + this.Kampftalente.Add(new KampfTalent(i.Name, i.At + (int)Math.Round(Misc.Random(stDv)), i.Pa + (int)Math.Round(Misc.Random(stDv)))); + } + } + + public string Name { get; set; } // char name + + public Dictionary Eigenschaften { get; set; } = new Dictionary(); // char properties + + public List Talente { get; set; } = new List(); // list of talent objects (talents and spells) + + public List Kampftalente { get; set; } = new List(); // list of combat objects + + public List Vorteile { get; set; } = new List(); + + public Dictionary PropTable { get; set; } = new Dictionary(); // -> Körperkraft + + public string TestTalent(string talent, int erschwernis = 0) // Talentprobe + { + try + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var tTalent = this.Talente.OrderBy(x => sc.Compare(talent, x.Name)).First(); + + if (sc.Compare(talent, tTalent.Name) > 94100) + { + return $"{this.Name} kann nicht {talent}..."; + } + + var props = tTalent.Test(); // get the required properties + int tap = tTalent.Value; // get tap + var werte = props.Select(p => this.Eigenschaften[this.PropTable[p]]).ToList(); + + output.AppendFormat( + "{0} würfelt: {1} \n{2} - {3} taw:{4} {5} \n", + this.Name, + tTalent.Name, + tTalent.Probe, + string.Join("/", werte), + tTalent.Value, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + output.Append(" "); + tap -= erschwernis; + int gesamtErschwernis = tap; + if (gesamtErschwernis < 0) + { + tap = 0; + for (int i = 0; i <= 2; i++) + { + // foreach property, dice and tap + int temp = Dice.Roll(); + int eigenschaft = this.Eigenschaften[this.PropTable[props[i]]]; + + if (eigenschaft - gesamtErschwernis < temp) + { + tap -= temp - eigenschaft + gesamtErschwernis; + } + + output.Append($"[{temp}]"); // add to string + } + + if (tap >= 0) + { + tap = 1; + } + } + else + { + for (int i = 0; i <= 2; i++) + { + // foreach property, dice and tap + int temp = Dice.Roll(); + int eigenschaft = this.Eigenschaften[this.PropTable[props[i]]]; + + if (eigenschaft < temp) + { + tap -= temp - eigenschaft; + } + + output.Append($"[{temp}]"); // add to string + } + } + + tap = tap == 0 ? 1 : tap; + + output.AppendFormat(" tap: {0,2}", tap); + + return output.ToString(); // return output + } + catch (Exception) + { + throw new Exception( + $"{talent} nicht vorhanden! Besitzt {this.Name} {talent} nicht? \n Oder ist {talent} falsch geschrieben?"); + } + } + + public string TestEigenschaft(string eigenschaft, int erschwernis = 0) + { + var output = new StringBuilder(); + var prop = this.PropTable[eigenschaft.ToUpper()]; + int tap = this.Eigenschaften[prop]; + output.AppendFormat( + "{0}-Eigenschaftsprobe ew:{1} {2} \n", + prop, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + int roll = Dice.Roll(); + output.Append($"Gewürfelt: {roll} übrig: {tap - roll - erschwernis}"); + return output.ToString(); + } + + public string Angriff(string talent, int erschwernis = 0) // pretty self explanatory + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var attack = this.Kampftalente.OrderBy(x => sc.Compare(talent, x.Name)).First(); + if (sc.Compare(talent, attack.Name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.At; + output.AppendFormat( + "{0}-Angriff taw:{1} {2} \n", + attack.Name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + int temp = Dice.Roll(); + output.Append(temp - erschwernis); + return output.ToString(); + } + + public string Parade(string talent, int erschwernis = 0) + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var attack = this.Kampftalente.OrderBy(x => sc.Compare(talent, x.Name)).First(); + + if (sc.Compare(talent, attack.Name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.Pa; + output.AppendFormat( + "{0}-Parade taw:{1} {2}\n", + attack.Name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + int temp = Dice.Roll(); + output.Append(temp - erschwernis); + return output.ToString(); + } + + public string Fernkampf(string talent, int erschwernis = 0) + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + int fk = this.Eigenschaften["fk"]; + var attack = this.Talente.OrderBy(x => sc.Compare(talent, x.Name)).First(); + if (sc.Compare(talent, attack.Name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.Value; + output.AppendFormat( + "{0} taw:{1} {2} \n", + attack.Name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + tap -= erschwernis; + int temp = Dice.Roll(); + tap -= temp > fk ? temp - fk : 0; + output.Append($"W20: {temp} tap: {tap}"); + return output.ToString(); + } + + private void Load(string path) + { + var reader = new XmlTextReader(path); + while (reader.Read()) + { + // read until he hits keywords + if (reader.NodeType != XmlNodeType.Element) + { + continue; + } + + switch (reader.Name) + { + case "Wesen": + reader.Skip(); + break; + case "held": + this.Name = reader.GetAttribute("name"); // name + break; + case "eigenschaft": + this.Eigenschaften.Add( + reader.GetAttribute("name") ?? throw new InvalidOperationException(), + Convert.ToInt32(reader.GetAttribute("value")) + Convert.ToInt32(reader.GetAttribute("mod"))); + break; + case "vt": + reader.Read(); + while (reader.Name.Equals("vorteil")) + { + try + { + this.Vorteile.Add(new Vorteil( + reader.GetAttribute("name"), + Convert.ToInt32(reader.GetAttribute("value")))); + } + catch + { + this.Vorteile.Add(new Vorteil(reader.GetAttribute("name"))); + } + + reader.Read(); + } + + break; + case "talentliste": + reader.Read(); + while (reader.Name.Equals("talent")) + { + this.Talente.Add( + new Talent( + reader.GetAttribute("name"), + reader.GetAttribute("probe")?.Remove(0, 2).Trim(')'), + Convert.ToInt32(reader.GetAttribute("value")))); + reader.Read(); + } + + break; + case "zauberliste": + reader.Read(); + while (reader.Name.Equals("zauber")) + { + this.Talente.Add( + new Talent( + reader.GetAttribute("name"), + reader.GetAttribute("probe")?.Remove(0, 2).Trim(')'), + Convert.ToInt32(reader.GetAttribute("value")))); + reader.Read(); + } + + break; + case "kampfwerte": + string atName = reader.GetAttribute("name"); + reader.Read(); + int at = Convert.ToInt32(reader.GetAttribute("value")); + reader.Read(); + int pa = Convert.ToInt32(reader.GetAttribute("value")); + this.Kampftalente.Add(new KampfTalent(atName, at, pa)); + break; + } + } + } + } +} diff --git a/DiscoBot/Characters/ICharacter.cs b/DiscoBot/Characters/ICharacter.cs new file mode 100644 index 0000000..135243a --- /dev/null +++ b/DiscoBot/Characters/ICharacter.cs @@ -0,0 +1,17 @@ +namespace DiscoBot.Characters +{ + public interface ICharacter + { + string Name { get; set; } + + string TestTalent(string talent, int erschwernis = 0); + + string TestEigenschaft(string eigenschaft, int erschwernis = 0); + + string Angriff(string talent, int erschwernis = 0); + + string Parade(string talent, int erschwernis = 0); + + string Fernkampf(string talent, int erschwernis = 0); + } +} diff --git a/DiscoBot/Characters/NPC.cs b/DiscoBot/Characters/NPC.cs new file mode 100644 index 0000000..470d5ff --- /dev/null +++ b/DiscoBot/Characters/NPC.cs @@ -0,0 +1,106 @@ +namespace DiscoBot.Characters +{ + using System; + + using DiscoBot.Auxiliary; + + public class Npc : ICharacter + { + private readonly int mean, stDv; + + public Npc(string name, int mean, int stDv) + { + this.mean = mean; + this.stDv = stDv; + this.Name = name; + } + + public string Name { get; set; } + + public string TestTalent(string talent, int tap = 3) + { + for (int i = 0; i <= 2; i++) + { + // foreach property, dice and tap + int temp = Dice.Roll(); + int eigenschaft = (int)Math.Round(Misc.Random(this.stDv, this.mean)); + + if (eigenschaft < temp) + { + tap -= temp - eigenschaft; + } + } + + if (tap >= 0) + { + return $"{this.Name} vollführt {talent} erfolgreich"; + } + + return $"{this.Name} scheitert an {talent}"; + } + + public string TestEigenschaft(string eigenschaft, int erschwernis = 0) + { + int temp = Dice.Roll(); + int prop = (int)Math.Round(Misc.Random(this.stDv, this.stDv)); + + if (temp + erschwernis < prop) + { + return $"{this.Name} vollführt {eigenschaft} erfolgreich"; + } + + return $"{this.Name} scheitert an {eigenschaft}"; + } + + public string Angriff(string waffe, int erschwernis = 0) + { + int temp = Dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} greift kritisch mit {waffe} an"; + } + + if (temp < erschwernis) + { + return $"{this.Name} greift mit {waffe} an"; + } + + return $"{this.Name} haut mit {waffe} daneben"; + } + + public string Parade(string waffe, int erschwernis = 0) + { + int temp = Dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} pariert mit {waffe} meisterlich"; + } + + if (temp < erschwernis) + { + return $"{this.Name} pariert mit {waffe} an"; + } + + return $"{this.Name} schafft es nicht mit {waffe} zu parieren"; + } + + public string Fernkampf(string waffe, int erschwernis = 0) + { + int temp = Dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} trifft kritisch mit {waffe}"; + } + + if (temp < erschwernis) + { + return $"{this.Name} greift mit {waffe} an"; + } + + return $"{this.Name} schießt mit {waffe} daneben"; + } + } +} diff --git a/DiscoBot/CommandExtension.cs b/DiscoBot/CommandExtension.cs deleted file mode 100644 index 06eec92..0000000 --- a/DiscoBot/CommandExtension.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - using System.ComponentModel; - using System.Threading; - using Discord; - using Discord.Commands; - - public static class CommandExtension - { - public static async Task ReplyTimed(this ModuleBase m, string message, TimeSpan time) - { - var token = message.GetHashCode(); - var send = m.Context.Channel.SendMessageAsync($"#{token}\n```xl\n{message}```", true); - - BackgroundWorker barInvoker = new BackgroundWorker(); - barInvoker.DoWork += delegate - { - Thread.Sleep(time); - delete(token, m); - }; - - await send; - barInvoker.RunWorkerAsync(); - } - - private static async void delete(int token, ModuleBase m) - { - var messagesAsync = m.Context.Channel.GetMessagesAsync(100); - Task.WaitAll(messagesAsync.ToArray()); - var list = messagesAsync.ToEnumerable().ToList(); - var messages = new List(); - foreach (var task in list) - { - messages.AddRange(task.ToList()); - } - - await m.Context.Channel.DeleteMessagesAsync(messages.Where(x => x.Content.StartsWith($"#{token}\n") && x.Author.IsBot)); - } - } - -} diff --git a/DiscoBot/Commands.cs b/DiscoBot/Commands.cs deleted file mode 100644 index 6ba2b8a..0000000 --- a/DiscoBot/Commands.cs +++ /dev/null @@ -1,449 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Discord; -using Discord.Commands; -using Discord.WebSocket; - - -namespace DiscoBot -{ - using System.ComponentModel; - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; - using System.Threading; - - using Discord.Audio; - - public class Info : ModuleBase - { - [Command("say"), Summary("Echos a message.")] - [Alias("s")] - public async Task Say([Remainder, Summary("The text to echo")] string echo) - { - var a = Context.User.Username; - - await ReplyAsync(echo); - } - } - - public class Roll : ModuleBase - { - [Command("r"), Summary("Würfelt ")] - [Alias("R", "Roll", "roll", "Würfle")] - public async Task Say([Remainder, Summary("Weapon")] string roll) - { - await ReplyAsync("```xl\n" + Misc.Roll(roll) + "\n```"); - } - } - - public class SetGeneral : ModuleBase - { - [Command("general"), Summary("Set General ")] - public async Task Say([Remainder, Summary("Set General")] int i = 0) - { - DSA.GeneralContext = this.Context; - await this.Context.Channel.SendMessageAsync($"```xl\n Der Dachs hat in '{this.Context.Channel.Name}' ein Zuhause gefunden. Gm Nachrichten werden nun auch in diesem Channel gepostet. \n```"); - } - } - - [SuppressMessage("ReSharper", "PublicMembersMustHaveComments", Justification = "OK")] - public class TestTalent : ModuleBase - { - [Command("t"), Summary("Würfelt ein Talent-/Zauberprobe")] - [Alias("T", "Talent", "talent", "zauber", "z", "versuche")] - public async Task Say([Summary("Talent oder Zaubername")] string talent, int erschwernis = 0) - { - string res = Gm.CheckCommand(DSA.relation[Context.User.Username], Commands.Talent, talent, erschwernis); - await this.ReplyAsync("```xl\n" + res + "\n```"); - - var tmessages = this.Context.Channel.GetMessagesAsync(10); - Task.WaitAll(tmessages.ToArray()); - var list = tmessages.ToEnumerable().ToList(); - var messages = new List(); - foreach (var task in list) - { - messages.AddRange(task.ToList()); - } - - //await this.Context.Channel.DeleteMessagesAsync(messages.Where(x => x.Content[0].Equals('!') && (x.Author as SocketGuildUser).Roles.ToList().Exists(v => v.Name.Equals("Meister")))); - } - } - - public class TestEigenschaft : ModuleBase - { - [Command("e"), Summary("Würfelt eine Eifenschaftsprobe")] - [Alias("E", "Eigenschaft", "eigenschaft", "eigen")] - public async Task Say([Summary("Eigenschafts kürzel und Erschwernis")] string talent, int erschwernis = 0) - { - var chr = DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])); - string res = chr.TestEigenschaft(talent, erschwernis); - await this.ReplyAsync("```xl\n" + res + "\n```"); - - } - } - - public class Angriff : ModuleBase - { - [Command("a"), Summary("Würfelt ein Angriff")] - [Alias("At", "at", "Angriff", "angriff", "attackiere_mit", "attacke", "Attacke")] - public async Task Say([Summary("Weapon")] string weapon, int erschwernis = 0) - { - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Angriff(weapon, erschwernis) + "\n```"); - - } - } - public class Parade : ModuleBase - { - // ~say hello -> hello - [Command("p"), Summary("Würfelt eine Parade Probe")] - [Alias("P", "Parade", "parade", "pariere_mit")] - public async Task Say([Summary("Parade Weapon")] string talent, int erschwernis = 0) - { - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Parade(talent, erschwernis) + "\n```"); - - } - } - public class Fernkampf : ModuleBase - { - // ~say hello -> hello - [Command("f"), Summary("Führt eine Fernkampfprobe aus")] - [Alias("F", "fernkampf", "Fernkampf", "schieße", "schieße_mit")] - public async Task Say([Summary("Fernkampfwaffe")] string waffe, int erschwernis = 0) - { - // ReplyAsync is a method on ModuleBase - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Fernkampf(waffe, erschwernis) + "\n```"); - } - public async Task Say([Summary("Fernkampfwaffe")] string charName, string waffe, ICommandContext context, int erschwernis = 0) - { - // ReplyAsync is a method on ModuleBase - await context.Channel.SendMessageAsync("Hello World\n"); - await context.Channel.SendMessageAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(charName)).Fernkampf(waffe, erschwernis) + "\n```"); - } - } - - public class Voice : ModuleBase - { - public static IAudioClient client { get; set; } - [Command("join", RunMode = RunMode.Async)] - public async Task JoinChannel(IVoiceChannel channel = null) - { - var msg = this.Context.Message; - // Get the audio channel - channel = channel ?? (msg.Author as IGuildUser)?.VoiceChannel; - if (channel == null) { await msg.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument."); return; } - - // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. - var audioClient = await channel.ConnectAsync(); - client = audioClient; - } - - [Command("leave", RunMode = RunMode.Async)] - public async Task LeaveChannel(IVoiceChannel channel = null) - { - // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. - client.StopAsync(); - } - - [Command("play")] - public async Task PlayAudio(string path) - { - SendAsync(client, path); - } - - private Process CreateStream(string path) - { - var ffmpeg = new ProcessStartInfo - { - FileName = "ffmpeg", - Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 -ab 620000 pipe:1", - UseShellExecute = false, - RedirectStandardOutput = true, - }; - return Process.Start(ffmpeg); - } - - private async Task SendAsync(IAudioClient client, string path) - { - // Create FFmpeg using the previous example - var ffmpeg = CreateStream(path); - var output = ffmpeg.StandardOutput.BaseStream; - var discord = client.CreatePCMStream(AudioApplication.Music); - await output.CopyToAsync(discord); - await discord.FlushAsync(); - } - } - - - [Group("gmtr")] - public class Sample : ModuleBase - { - // ~sample square 20 -> 400 - [Command("square"), Summary("Squares a number.")] - public async Task Square([Summary("The number to square.")] int num) - { - // We can also access the channel from the Command Context. - await Context.Channel.SendMessageAsync($"{num}^2 = {Math.Pow(num, 2)}"); - } - - [Command("userinfo"), Summary("Returns info about the current user, or the user parameter, if one passed.")] - [Alias("user", "whois")] - public async Task UserInfo([Summary("The (optional) user to get info for")] IUser user = null) - { - var userInfo = user ?? Context.Client.CurrentUser; - await ReplyAsync($"{userInfo.Username}#{userInfo.Discriminator}"); - } - } - - public class List : ModuleBase - { - // ~say hello -> hello - [Command("list"), Summary("gibt eine Auflistung aus")] - public async Task Say([Summary("Aktion")] string prop) - { - var res = new List(); - switch (prop.ToLower()) - { - case "chars": - case "Chars": - res.AddRange(DSA.chars.Select(x => x.Name)); - break; - case "t": - case "ta": - case "talent": - case "zauber": - res.AddRange( - ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) - .Talente.Select(s => s.name + "\t " + s.value + "\t " + s.probe)); - break; - case "w": - case "waffe": - case "waffen": - res.AddRange( - ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) - .Kampftalente.Select(s => s.name)); - break; - case "fern": - res.AddRange( - ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) - .Talente.Select(s => s.name)); - break; - case "v": - case "vt": - case "vor": - case "vorteil": - res.AddRange( - ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) - .Vorteile - .Select(s => s.name + "\t " + (s.value == 0 ? "" : s.value.ToString()))); - break; - - default: - res.Add($"Kommando {prop} nicht gefunden"); - break; - } - - //await this.ReplyAsync(res.Aggregate((seed, next) => seed + "\n" + next)); - var sb = new StringBuilder(); - foreach (string re in res) - { - if (sb.Length + re.Length > 1798) - { - await this.ReplyTimed(sb.ToString(), TimeSpan.FromSeconds(90)); - sb.Clear(); - } - - sb.AppendLine(re); - } - - await this.ReplyTimed(sb.ToString(), TimeSpan.FromSeconds(90)); - } - - } - - public class Gm : ModuleBase - { - // ~say hello -> hello - [Command("gm"), Summary("Führt eine probe aus")] - [Alias("GM", "as", "As", "als")] - public async Task Say([Summary("Fernkampfwaffe")] string name, string command, string waffe, int erschwernis = 0) - { - if (!(this.Context.User as SocketGuildUser).Roles.ToList().Exists(v => v.Name.Equals("Meister"))) - { - await ReplyAsync("```xl\n Keine ausreichenden Berechtigunen\n```"); - return; - } - - command = command.ToLower(); - string res; - switch (command) - { - case "f": - case "fern": - case "fernkampf": - res = CheckCommand(name, Commands.Fernkampf, waffe, erschwernis); - break; - case "t": - case "ta": - case "talent": - res = CheckCommand(name, Commands.Talent, waffe, erschwernis); - break; - case "e": - case "ei": - case "eigenschaft": - res = CheckCommand(name, Commands.Eigenschaft, waffe, erschwernis); - break; - case "z": - case "za": - case "zauber": - case "magie": - case "m": - res = CheckCommand(name, Commands.Talent, waffe, erschwernis); - break; - case "a": - case "at": - case "an": - case "angrif": - case "angriff": - res = CheckCommand(name, Commands.Angriff, waffe, erschwernis); - break; - case "p": - case "pa": - case "parade": - res = CheckCommand(name, Commands.Parade, waffe, erschwernis); - break; - case "talente": - throw new NotImplementedException(); - default: - res = $"Kommando {command} nicht gefunden"; - break; - } - - if (DSA.GeneralContext != null) - { - if (DSA.GeneralContext.Channel.Id != Context.Channel.Id) - { - await DSA.GeneralContext.Channel.SendMessageAsync("```xl\n" + res + "\n```"); - } - - await ReplyAsync("```xl\n" + res + "\n```"); - } - else - { - await ReplyAsync("```xl\n" + res + "\n```"); - } - } - - public static string CheckCommand(string name, Commands command, string waffe, int erschwernis = 0) - { - var comp = new SpellCorrect(); - var chr = DSA.chars.OrderBy(x => comp.Compare(x.Name, name)).First(); - switch (command) - { - case Commands.Talent: - return chr.TestTalent(waffe, erschwernis); - case Commands.Eigenschaft: - return chr.TestEigenschaft(waffe, erschwernis); - case Commands.Angriff: - return chr.Angriff(waffe, erschwernis); - case Commands.Parade: - return chr.Parade(waffe, erschwernis); - case Commands.Fernkampf: - return chr.Fernkampf(waffe, erschwernis); - } - - return $"{name} verwendet {waffe}"; - } - } - - public class GenerateNpc : ModuleBase - { - // ~say hello -> hello - [Command("npc"), Summary("Erstellt ein NPC")] - [Alias("Npc", "NPc", "NPC", "nPC")] - public async Task Say([Summary("Create Random")] string npcName, int mean = 9, int stDv = 1) - { - DSA.chars.Add(new NPC(npcName, mean, stDv)); - await this.ReplyAsync($"{npcName} wurde zufällig generiert"); - } - } - - public class CopyNpc : ModuleBase - { - // ~say hello -> hello - [Command("npc"), Summary("Erstellt ein NPC")] - [Alias("Npc", "NPc", "NPC", "nPC")] - public async Task Say([Summary("Create Copy")] string npcName, string source, int stDv = 1) - { - if (DSA.chars.Exists(x => x.Name.Equals(npcName))) - { - throw new Exception("Char gibt es schon"); - } - - var comp = new SpellCorrect(); - var chr = DSA.chars.OrderBy(x => comp.Compare(x.Name, source)).First(); - DSA.chars.Add(new Character(chr as Character, npcName, stDv)); - await ReplyAsync($"{npcName} wurde als variierte Kopie von {source} erstellt"); - } - } - - public class NpcAction : ModuleBase - { - // ~say hello -> hello - [Command("npc"), Summary("Führt eine NPC-Probe aus")] - [Alias("Npc", "NPc", "NPC", "nPC")] - public async Task Say([Summary("Aktion")] string NpcName, string command, string Aktion, int erschwernis = 0) - { - string test = ""; - } - } - - /*public class AudioModule : ModuleBase - { - // Scroll down further for the AudioService. - // Like, way down - private readonly AudioService _service; - - // Remember to add an instance of the AudioService - // to your IServiceCollection when you initialize your bot - public AudioModule(AudioService service) - { - _service = service; - } - - // You *MUST* mark these commands with 'RunMode.Async' - // otherwise the bot will not respond until the Task times out. - [Command("join", RunMode = RunMode.Async)] - public async Task JoinCmd() - { - await _service.JoinAudio(Context.Guild, (Context.User as IVoiceState).VoiceChannel); - } - - // Remember to add preconditions to your commands, - // this is merely the minimal amount necessary. - // Adding more commands of your own is also encouraged. - [Command("leave", RunMode = RunMode.Async)] - public async Task LeaveCmd() - { - await _service.LeaveAudio(Context.Guild); - } - - [Command("play", RunMode = RunMode.Async)] - public async Task PlayCmd([Remainder] string song) - { - await _service.SendAudioAsync(Context.Guild, Context.Channel, song); - } - }*/ - - public enum Commands - { - Talent, - Eigenschaft, - Angriff, - Parade, - Fernkampf, - KeinChar - } -} diff --git a/DiscoBot/Commands/CommandTypes.cs b/DiscoBot/Commands/CommandTypes.cs new file mode 100644 index 0000000..4ff0814 --- /dev/null +++ b/DiscoBot/Commands/CommandTypes.cs @@ -0,0 +1,12 @@ +namespace DiscoBot.Commands +{ + public enum CommandTypes + { + Talent, + Eigenschaft, + Angriff, + Parade, + Fernkampf, + KeinChar + } +} diff --git a/DiscoBot/Commands/Gm.cs b/DiscoBot/Commands/Gm.cs new file mode 100644 index 0000000..60b82fb --- /dev/null +++ b/DiscoBot/Commands/Gm.cs @@ -0,0 +1,103 @@ +namespace DiscoBot.Commands +{ + using System.Linq; + using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + + using Discord.Commands; + using Discord.WebSocket; + + public class Gm : ModuleBase + { + public static string CheckCommand(string name, CommandTypes command, string waffe, int erschwernis = 0) + { + var comp = new SpellCorrect(); + var chr = Dsa.Chars.OrderBy(x => comp.Compare(x.Name, name)).First(); + switch (command) + { + case CommandTypes.Talent: + return chr.TestTalent(waffe, erschwernis); + case CommandTypes.Eigenschaft: + return chr.TestEigenschaft(waffe, erschwernis); + case CommandTypes.Angriff: + return chr.Angriff(waffe, erschwernis); + case CommandTypes.Parade: + return chr.Parade(waffe, erschwernis); + case CommandTypes.Fernkampf: + return chr.Fernkampf(waffe, erschwernis); + } + + return $"{name} verwendet {waffe}"; + } + + [Command("gm"), Summary("Führt eine probe aus")] + [Alias("GM", "as", "As", "als")] + public async Task ProbeAsync([Summary("Fernkampfwaffe")] string name, string command, string waffe, int erschwernis = 0) + { + if (!((SocketGuildUser)this.Context.User).Roles.ToList().Exists(v => v.Name.Equals("Meister"))) + { + await this.ReplyAsync("```xl\n Keine ausreichenden Berechtigunen\n```"); + return; + } + + command = command.ToLower(); + string res = this.Test(name, command, waffe, erschwernis); + + if (Dsa.GeneralContext != null && Dsa.GeneralContext.Channel.Id != this.Context.Channel.Id) + { + await Dsa.GeneralContext.Channel.SendMessageAsync("```xl\n" + res + "\n```"); + } + + await this.ReplyAsync("```xl\n" + res + "\n```"); + } + + private string Test(string name, string command, string waffe, int erschwernis = 0) + { + string res; + switch (command) + { + case "f": + case "fern": + case "fernkampf": + res = CheckCommand(name, CommandTypes.Fernkampf, waffe, erschwernis); + break; + case "t": + case "ta": + case "talent": + case "talente": + res = CheckCommand(name, CommandTypes.Talent, waffe, erschwernis); + break; + case "e": + case "ei": + case "eigenschaft": + res = CheckCommand(name, CommandTypes.Eigenschaft, waffe, erschwernis); + break; + case "z": + case "za": + case "zauber": + case "magie": + case "m": + res = CheckCommand(name, CommandTypes.Talent, waffe, erschwernis); + break; + case "a": + case "at": + case "an": + case "angrif": + case "angriff": + res = CheckCommand(name, CommandTypes.Angriff, waffe, erschwernis); + break; + case "p": + case "pa": + case "parade": + res = CheckCommand(name, CommandTypes.Parade, waffe, erschwernis); + break; + default: + res = $"Kommando {command} nicht gefunden"; + break; + } + + return res; + } + } +} diff --git a/DiscoBot/Commands/List.cs b/DiscoBot/Commands/List.cs new file mode 100644 index 0000000..9eac3a1 --- /dev/null +++ b/DiscoBot/Commands/List.cs @@ -0,0 +1,76 @@ +namespace DiscoBot.Commands +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + using DiscoBot.Characters; + + using Discord.Commands; + + public class List : ModuleBase + { + [Command("list"), Summary("gibt eine Auflistung aus")] + public async Task ListAsync([Summary("Aktion")] string prop) + { + var res = new List(); + switch (prop.ToLower()) + { + case "chars": + case "Chars": + res.AddRange(Dsa.Chars.Select(x => x.Name)); + break; + case "t": + case "ta": + case "talent": + case "zauber": + res.AddRange( + ((Character)Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username]))) + .Talente.Select(s => s.Name + "\t " + s.Value + "\t " + s.Probe)); + break; + case "w": + case "waffe": + case "waffen": + res.AddRange( + ((Character)Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username]))) + .Kampftalente.Select(s => s.Name)); + break; + case "fern": + res.AddRange( + ((Character)Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username]))) + .Talente.Select(s => s.Name)); + break; + case "v": + case "vt": + case "vor": + case "vorteil": + res.AddRange( + ((Character)Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username]))) + .Vorteile + .Select(s => s.Name + "\t " + (s.Value == 0 ? string.Empty : s.Value.ToString()))); + break; + + default: + res.Add($"Kommando {prop} nicht gefunden"); + break; + } + + var sb = new StringBuilder(); + foreach (string re in res) + { + if (sb.Length + re.Length > 1798) + { + await this.ReplyTimedAsync(sb.ToString(), TimeSpan.FromSeconds(90)); + sb.Clear(); + } + + sb.AppendLine(re); + } + + await this.ReplyTimedAsync(sb.ToString(), TimeSpan.FromSeconds(90)); + } + } +} diff --git a/DiscoBot/Commands/NpcCommands.cs b/DiscoBot/Commands/NpcCommands.cs new file mode 100644 index 0000000..f2b17b6 --- /dev/null +++ b/DiscoBot/Commands/NpcCommands.cs @@ -0,0 +1,37 @@ +namespace DiscoBot.Commands +{ + using System; + using System.Linq; + using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + using DiscoBot.Characters; + + using Discord.Commands; + + public class NpcCommands : ModuleBase + { + [Command("npc"), Summary("Erstellt ein NPC")] + [Alias("Npc", "NPc", "NPC", "nPC")] + public Task RandomAsync([Summary("Create Random")] string npcName, int mean = 9, int stDv = 1) + { + Dsa.Chars.Add(new Npc(npcName, mean, stDv)); + return this.ReplyAsync($"{npcName} wurde zufällig generiert"); + } + + [Command("npc"), Summary("Erstellt ein NPC")] + [Alias("Npc", "NPc", "NPC", "nPC")] + public Task CopyAsync([Summary("Create Copy")] string npcName, string source, int stDv = 1) + { + if (Dsa.Chars.Exists(x => x.Name.Equals(npcName))) + { + throw new Exception("Char gibt es schon"); + } + + var comp = new SpellCorrect(); + var chr = Dsa.Chars.OrderBy(x => comp.Compare(x.Name, source)).First(); + Dsa.Chars.Add(new Character(chr as Character, npcName, stDv)); + return this.ReplyAsync($"{npcName} wurde als variierte Kopie von {source} erstellt"); + } + } +} diff --git a/DiscoBot/Commands/Test.cs b/DiscoBot/Commands/Test.cs new file mode 100644 index 0000000..d56a43c --- /dev/null +++ b/DiscoBot/Commands/Test.cs @@ -0,0 +1,47 @@ +namespace DiscoBot.Commands +{ + using System.Threading.Tasks; + + using Discord.Commands; + + public class Test : ModuleBase + { + [Command("t"), Summary("Würfelt ein Talent-/Zauberprobe")] + [Alias("T", "Talent", "talent", "zauber", "z", "versuche")] + public Task TalentAsync([Summary("Talent oder Zaubername")] string talent, int erschwernis = 0) + { + string res = Gm.CheckCommand(Dsa.Relation[this.Context.User.Username], CommandTypes.Talent, talent, erschwernis); + return this.ReplyAsync("```xl\n" + res + "\n```"); + } + + [Command("e"), Summary("Würfelt eine Eigenschaftsprobe")] + [Alias("E", "Eigenschaft", "eigenschaft", "eigen")] + public Task EigenschaftAsync([Summary("Eigenschaftskürzel und Erschwernis")] string talent, int erschwernis = 0) + { + var chr = Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username])); + string res = chr.TestEigenschaft(talent, erschwernis); + return this.ReplyAsync("```xl\n" + res + "\n```"); + } + + [Command("a"), Summary("Würfelt ein Angriff")] + [Alias("At", "at", "Angriff", "angriff", "attackiere_mit", "attacke", "Attacke")] + public Task AngriffAsync([Summary("Weapon")] string weapon, int erschwernis = 0) + { + return this.ReplyAsync("```xl\n" + Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username])).Angriff(weapon, erschwernis) + "\n```"); + } + + [Command("p"), Summary("Würfelt eine Parade Probe")] + [Alias("P", "Parade", "parade", "pariere_mit")] + public Task ParadeAsync([Summary("Parade Weapon")] string talent, int erschwernis = 0) + { + return this.ReplyAsync("```xl\n" + Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username])).Parade(talent, erschwernis) + "\n```"); + } + + [Command("f"), Summary("Führt eine Fernkampfprobe aus")] + [Alias("F", "fernkampf", "Fernkampf", "schieße", "schieße_mit")] + public Task FernkampfAsync([Summary("Fernkampfwaffe")] string waffe, int erschwernis = 0) + { + return this.ReplyAsync("```xl\n" + Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username])).Fernkampf(waffe, erschwernis) + "\n```"); + } + } +} diff --git a/DiscoBot/Commands/Utility.cs b/DiscoBot/Commands/Utility.cs new file mode 100644 index 0000000..bbba1a1 --- /dev/null +++ b/DiscoBot/Commands/Utility.cs @@ -0,0 +1,32 @@ +namespace DiscoBot.Commands +{ + using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + + using Discord.Commands; + + public class Utility : ModuleBase + { + [Command("r"), Summary("Würfelt ")] + [Alias("R", "Roll", "roll", "Würfle")] + public Task RollAsync([Remainder, Summary("Weapon")] string roll) + { + return this.ReplyAsync("```xl\n" + Misc.Roll(roll) + "\n```"); + } + + [Command("general"), Summary("Set General ")] + public Task SetGeneralAsync([Remainder, Summary("Set General")] int i = 0) + { + Dsa.GeneralContext = this.Context; + return this.Context.Channel.SendMessageAsync($"```xl\n Der Dachs hat in '{this.Context.Channel.Name}' ein Zuhause gefunden. Gm Nachrichten werden nun auch in diesem Channel gepostet. \n```"); + } + + [Command("say"), Summary("Echos a message.")] + [Alias("s")] + public Task SayAsync([Remainder, Summary("The text to echo")] string echo) + { + return this.ReplyAsync(echo); + } + } +} diff --git a/DiscoBot/Commands/Voice.cs b/DiscoBot/Commands/Voice.cs new file mode 100644 index 0000000..72988d4 --- /dev/null +++ b/DiscoBot/Commands/Voice.cs @@ -0,0 +1,67 @@ +namespace DiscoBot.Commands +{ + using System.Diagnostics; + using System.Threading.Tasks; + + using Discord; + using Discord.Audio; + using Discord.Commands; + + public class Voice : ModuleBase + { + public static IAudioClient Client { get; set; } + [Command("join", RunMode = RunMode.Async)] + public async Task JoinChannelAsync(IVoiceChannel channel = null) + { + var msg = this.Context.Message; + + // Get the audio channel + channel = channel ?? (msg.Author as IGuildUser)?.VoiceChannel; + if (channel == null) + { + await msg.Channel.SendMessageAsync( + "User must be in a voice channel, or a voice channel must be passed as an argument."); + return; + } + + // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. + var audioClient = await channel.ConnectAsync(); + Client = audioClient; + } + + [Command("leave", RunMode = RunMode.Async)] + public Task LeaveChannelAsync(IVoiceChannel channel = null) + { + // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. + return Client.StopAsync(); + } + + [Command("play")] + public Task PlayAudioAsync(string path) + { + return this.SendAsync(Client, path); + } + + private Process CreateStream(string path) + { + var ffmpeg = new ProcessStartInfo + { + FileName = "ffmpeg", + Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 -ab 620000 pipe:1", + UseShellExecute = false, + RedirectStandardOutput = true, + }; + return Process.Start(ffmpeg); + } + + private async Task SendAsync(IAudioClient client, string path) + { + // Create FFmpeg using the previous example + var ffmpeg = this.CreateStream(path); + var output = ffmpeg.StandardOutput.BaseStream; + var discord = client.CreatePCMStream(AudioApplication.Music); + await output.CopyToAsync(discord); + await discord.FlushAsync(); + } + } +} diff --git a/DiscoBot/DSA.cs b/DiscoBot/DSA.cs index af02023..d9cefb2 100644 --- a/DiscoBot/DSA.cs +++ b/DiscoBot/DSA.cs @@ -3,37 +3,43 @@ using System.Collections.Generic; using System.IO; using System.Linq; - using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + using DiscoBot.Characters; using Discord.Commands; - public static class DSA + public static class Dsa { public static ICommandContext GeneralContext { get; set; } - public static Dictionary relation = new Dictionary(); //dictionary to match the char - public static List chars = new List(); //list of all charackters - public static List Talente { get; set; } = new List(); + public static Dictionary Relation { get; set; } = new Dictionary(); // dictionary to match the char + + public static List Chars { get; set; } = new List(); // list of all characters - public static async Task Startup() + public static List Talente { get; set; } = new List(); + + public static void Startup() { - relation.Add("The Doctor", "Numeri Illuminus");//Relation - relation.Add("Tardis", "Morla");//"Numeri Illuminus"); - relation.Add("DSA Bot", "Morla");//"Felis Exodus Schattenwald"); - relation.Add("Morla", "Morla"); - relation.Add("Rhoktar", "Rhoktar4"); - //relation.Add("Papo","Gwendelson"); - relation.Add("Papo", "Pump aus der Gosse"); - relation.Add("Potus", "Potus"); - //relation.Add("Papo", "Pump aus der Gosse"); + Relation.Add("The Doctor", "Numeri Illuminus"); // Relation + Relation.Add("Tardis", "Morla"); // "Numeri Illuminus"); + Relation.Add("DSA Bot", "Morla"); // "Felis Exodus Schattenwald"); + Relation.Add("Morla", "Morla"); + Relation.Add("Rhoktar", "Rhoktar4"); + + // relation.Add("Papo","Gwendelson"); + Relation.Add("Papo", "Pump aus der Gosse"); + Relation.Add("Potus", "Potus"); + + // relation.Add("Papo", "Pump aus der Gosse"); foreach (var filename in Directory.GetFiles("helden", "*.xml")) { - chars.Add(new Character(filename)); - (chars.Last() as Character)?.Talente.Select(x => new Talent(x.name, x.probe, 0)) - .Where(c => !Talente.Exists(v => v.name.Equals(c.name))).ToList().ForEach(v => Talente.Add(v)); + Chars.Add(new Character(filename)); + (Chars.Last() as Character)?.Talente.Select(x => new Talent(x.Name, x.Probe, 0)) + .Where(c => !Talente.Exists(v => v.Name.Equals(c.Name))).ToList().ForEach(v => Talente.Add(v)); } - Talente = Talente.OrderBy(x => x.name).ToList(); + Talente = Talente.OrderBy(x => x.Name).ToList(); } } } \ No newline at end of file diff --git a/DiscoBot/DiscoBot.csproj b/DiscoBot/DiscoBot.csproj index d0fc986..2bf17e5 100644 --- a/DiscoBot/DiscoBot.csproj +++ b/DiscoBot/DiscoBot.csproj @@ -140,15 +140,24 @@ - - - - - + + + + + + + + + + + + + + - - - + + + diff --git a/DiscoBot/ICharacter.cs b/DiscoBot/ICharacter.cs deleted file mode 100644 index fbaabd3..0000000 --- a/DiscoBot/ICharacter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - public interface ICharacter - { - string Name { get; set; } - - string TestTalent(string talent, int erschwernis = 0); - - string TestEigenschaft(string eigenschaft, int erschwernis = 0); - - string Angriff(string talent, int erschwernis = 0); - - string Parade(string talent, int erschwernis = 0); - - string Fernkampf(string talent, int erschwernis = 0); - } -} diff --git a/DiscoBot/Misc.cs b/DiscoBot/Misc.cs deleted file mode 100644 index 9c9456c..0000000 --- a/DiscoBot/Misc.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - public static class Misc - { - private static readonly Random Rand = new Random(); - - // use: 4w6 +4 - public static string Roll(string input) - { - int count = 1, d ,mod=0; - var Output = new StringBuilder(); - List strings = input.Split('w','d').ToList(); - count = Convert.ToInt32(strings[0]); - strings = strings[1].Split(' ').ToList(); - d = Convert.ToInt32(strings[0]); - - if (strings.Count > 0) - mod = Convert.ToInt32(strings.Last()); - int sum = 0; - for (int i = 0; i < count; i++) - { - var roll = dice.Roll(d); - sum += roll; - Output.Append("["+roll + "] "); - } - if (count > 1) - Output.Append("sum: " + (sum)); - - return Output.ToString(); - } - - public static double Random(double stdDev = 1, double mean = 0) - { - double u1 = Rand.NextDouble(); // uniform(0,1) random doubles - double u2 = Rand.NextDouble(); - double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * - Math.Sin(2.0 * Math.PI * u2); // random normal(0,1) - double randNormal = - mean + stdDev * randStdNormal; // random normal(mean,stdDev^2) - return randNormal; - } - } - - public class SpellCorrect : StringComparer - { - public override int Compare(string x, string y) - { - if (x.Equals(y)) - return 0; - x=x.ToLower(); - y=y.ToLower(); - if (x.Equals(y)) - return 1; - var subs = y.Split(' ', '/'); - int score = subs.Count(); - foreach (string s in subs) - { - if (s.Equals(x)) - { - score--; - } - } - - if (score < subs.Count()) - { - return score + 1; - } - - return 100000 - (int)(compare_exact(x, y) * 1000.0); - /*if (y.Contains(x)) - return 6;*/ - - } - - public override bool Equals(string x, string y) - { - throw new NotImplementedException(); - } - - public override int GetHashCode(string obj) - { - throw new NotImplementedException(); - } - - public double compare_exact(string s, string q) - { - int i, j; - const double Match = 3.0; - const double Gap = -2.0; - const double Mismatch = -2.0; - - double decay = 0.0; - - double[,] matrix = new double[s.Length + 1, q.Length + 1]; - double max = 0.0; - matrix[0, 0] = 0.0; - - for (i = 1; i < s.Length; i++) - { - matrix[i, 0] = 0.0; - } - - for (i = 1; i < q.Length; i++) - { - matrix[0, i] = 0.0; - } - - for (i = 1; i <= s.Length; i++) - { - for (j = 1; j <= q.Length; j++) - { - decay = j / (double)(s.Length * 1000); - double add = s[i - 1] == q[j - 1] ? (Match - decay) : Mismatch; - double score = matrix[i - 1, j - 1] + add; - - if (score < (matrix[i - 1, j] + Gap)) - { - score = matrix[i - 1, j] + Gap; - } - - if (score < (matrix[i, j - 1] + Gap)) - { - score = matrix[i, j - 1] + Gap; - } - - if (i > 1 && j > 1) - { - if (s[i - 1] == q[j - 2] && s[i - 2] == q[j - 1]) - { - add = (3 / 2.0) * Match - decay; - if (score < matrix[i - 2, j - 2] + add) - { - score = matrix[i - 2, j - 2] + add; - } - } - } - - if (score < 0) - { - score = 0; - } - - if (max < score) - { - max = score; - } - - matrix[i, j] = score; - } - } - - return max; - } - } - - public static class dice//roll it! - { - static System.Random rnd = new System.Random(); - public static int Roll(int d=20) - { - return rnd.Next(1, d+1); - } - } - - public class Vorteil //talent objekt - { - public string name; - public int value; - - public Vorteil(string name, int value = 0) - { - this.name = name; - this.value = value; - } - } - - public class Talent //talent objekt - { - public string name, probe; - public int value; - public Talent(string name, string probe, int value) { this.name = name; this.probe = probe; this.value = value; } - public string[] Test() //turn XX/XX/XX into string[]{XX,XX,XX} - { - var temp = probe.Split('/'); - foreach (string s in temp) - s.Replace("/", ""); - return temp; - } - - public int CheckName(string quary) - { - var sc = (StringComparer)new SpellCorrect(); - return sc.Compare(quary, this.name); - } - - } - - public class Kampf - { - public string name; - public int at, pa; - public Kampf(string name, int at, int pa) { this.name = name; this.at = at; this.pa = pa; } - void Test() { } - } - -} diff --git a/DiscoBot/NPC.cs b/DiscoBot/NPC.cs deleted file mode 100644 index 4104947..0000000 --- a/DiscoBot/NPC.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - public class NPC : ICharacter - { - private int mean, stDv; - - public NPC(string name, int mean, int stDv) - { - this.mean = mean; - this.stDv = stDv; - this.Name = name; - } - - public string Name { get; set; } - - public string TestTalent(string talent, int tap = 3) - { - for (int i = 0; i <= 2; i++) //foreach property, dice and tap - { - int temp = dice.Roll(); - int eigenschaft = (int)Math.Round(Misc.Random(this.stDv, this.mean)); - - if (eigenschaft < temp) - { - tap -= temp - eigenschaft; - } - } - - if (tap >= 0) - { - return $"{this.Name} vollführt {talent} erfolgreich"; - } - - return $"{this.Name} scheitert an {talent}"; - } - - public string TestEigenschaft(string eigenschaft, int erschwernis = 0) - { - int temp = dice.Roll(); - int prop = (int)Math.Round(Misc.Random(this.stDv, this.stDv)); - - if (temp + erschwernis < prop) - { - return $"{this.Name} vollführt {eigenschaft} erfolgreich"; - } - - return $"{this.Name} scheitert an {eigenschaft}"; - } - - public string Angriff(string waffe, int erschwernis = 0) - { - int temp = dice.Roll(); - - if (temp == 1) - { - return $"{this.Name} greift kritisch mit {waffe} an"; - } - - if (temp < erschwernis) - { - return $"{this.Name} greift mit {waffe} an"; - } - - return $"{this.Name} haut mit {waffe} daneben"; - } - - public string Parade(string waffe, int erschwernis = 0) - { - int temp = dice.Roll(); - - if (temp == 1) - { - return $"{this.Name} pariert mit {waffe} meisterlich"; - } - - if (temp < erschwernis) - { - return $"{this.Name} pariert mit {waffe} an"; - } - - return $"{this.Name} schafft es nicht mit {waffe} zu parieren"; - } - - public string Fernkampf(string waffe, int erschwernis = 0) - { - int temp = dice.Roll(); - - if (temp == 1) - { - return $"{this.Name} trifft kritisch mit {waffe}"; - } - - if (temp < erschwernis) - { - return $"{this.Name} greift mit {waffe} an"; - } - - return $"{this.Name} schießt mit {waffe} daneben"; - } - } -} diff --git a/DiscoBot/Program.cs b/DiscoBot/Program.cs index 7ae8244..6bf870e 100644 --- a/DiscoBot/Program.cs +++ b/DiscoBot/Program.cs @@ -1,78 +1,87 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Reflection; +using System.Threading.Tasks; + using Discord; -using Discord.WebSocket; using Discord.Commands; -using Microsoft.Extensions.DependencyInjection; +using Discord.WebSocket; +using Microsoft.Extensions.DependencyInjection; namespace DiscoBot { + using DiscoBot.Commands; + public class Program { private CommandService commands; private DiscordSocketClient client; private IServiceProvider services; - + public static void Main(string[] args) => new Program().StartAsync().GetAwaiter().GetResult(); - static void Main(string[] args) => new Program().Start().GetAwaiter().GetResult(); - - public async Task Start() + public async Task StartAsync() { - var loading = DSA.Startup(); - client = new DiscordSocketClient(); - commands = new CommandService(); + Dsa.Startup(); + this.client = new DiscordSocketClient(); + this.commands = new CommandService(); string token = Properties.Settings.Default.Token; - services = new ServiceCollection() + this.services = new ServiceCollection() .BuildServiceProvider(); - AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit); - - await InstallCommands(); + AppDomain.CurrentDomain.ProcessExit += OnProcessExit; - await client.LoginAsync(TokenType.Bot, token); - await client.StartAsync(); + await this.InstallCommandsAsync(); - await loading; + await this.client.LoginAsync(TokenType.Bot, token); + await this.client.StartAsync(); + await Task.Delay(-1); } - public async Task InstallCommands() + public Task InstallCommandsAsync() { // Hook the MessageReceived Event into our Command Handler - client.MessageReceived += HandleCommand; + this.client.MessageReceived += this.HandleCommandAsync; + // Discover all of the commands in this assembly and load them. - await commands.AddModulesAsync(Assembly.GetEntryAssembly()); + return this.commands.AddModulesAsync(Assembly.GetEntryAssembly()); } - public async Task HandleCommand(SocketMessage messageParam) + public async Task HandleCommandAsync(SocketMessage messageParam) { // Don't process the command if it was a System Message - var message = messageParam as SocketUserMessage; - if (message == null) return; + if (!(messageParam is SocketUserMessage message)) + { + return; + } + // Create a number to track where the prefix ends and the command begins int argPos = 0; + // Determine if the message is a command, based on if it starts with '!' or a mention prefix - if (!(message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(client.CurrentUser, ref argPos))) return; + if (!(message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(this.client.CurrentUser, ref argPos))) + { + return; + } + // Create a Command Context - var context = new CommandContext(client, message); + var context = new CommandContext(this.client, message); + // Execute the command. (result does not indicate a return value, // rather an object stating if the command executed successfully) - var result = await commands.ExecuteAsync(context, argPos, services); + var result = await this.commands.ExecuteAsync(context, argPos, this.services); if (!result.IsSuccess) + { await context.Channel.SendMessageAsync(result.ErrorReason); + } } - static void OnProcessExit(object sender, EventArgs e) + + private static void OnProcessExit(object sender, EventArgs e) { Console.WriteLine("I'm out of here"); - Voice.client.StopAsync(); + Voice.Client.StopAsync(); } } - } -- cgit v1.2.3-54-g00ecf