internal override void Init(CommandGroupBuilder cgb) { cgb.CreateCommand(Module.Prefix + "lolchamp") .Description("Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role.\n**Usage**:~lolchamp Riven or ~lolchamp Annie sup") .Parameter("champ", ParameterType.Required) .Parameter("position", ParameterType.Unparsed) .Do(async e => { try { //get role var role = ResolvePos(e.GetArg("position")); var resolvedRole = role; var name = e.GetArg("champ").Replace(" ", "").ToLower(); CachedChampion champ = null; lock (cacheLock) { CachedChampionImages.TryGetValue(name + "_" + resolvedRole, out champ); } if (champ != null) { champ.ImageStream.Position = 0; await e.Channel.SendFile("champ.png", champ.ImageStream); return; } var allData = JArray.Parse(await Classes.SearchHelper.GetResponseStringAsync($"http://api.champion.gg/champion/{name}?api_key={NadekoBot.Creds.LOLAPIKey}")); JToken data = null; if (role != null) { for (var i = 0; i < allData.Count; i++) { if (allData[i]["role"].ToString().Equals(role)) { data = allData[i]; break; } } if (data == null) { await e.Channel.SendMessage("💢 Data for that role does not exist."); return; } } else { data = allData[0]; role = allData[0]["role"].ToString(); resolvedRole = ResolvePos(role); } lock (cacheLock) { CachedChampionImages.TryGetValue(name + "_" + resolvedRole, out champ); } if (champ != null) { Console.WriteLine("Sending lol image from cache."); champ.ImageStream.Position = 0; await e.Channel.SendFile("champ.png", champ.ImageStream); return; } //name = data["title"].ToString(); // get all possible roles, and "select" the shown one var roles = new string[allData.Count]; for (var i = 0; i < allData.Count; i++) { roles[i] = allData[i]["role"].ToString(); if (roles[i] == role) roles[i] = ">" + roles[i] + "<"; } var general = JArray.Parse(await SearchHelper.GetResponseStringAsync($"http://api.champion.gg/stats/" + $"champs/{name}?api_key={NadekoBot.Creds.LOLAPIKey}")) .FirstOrDefault(jt => jt["role"].ToString() == role)?["general"]; if (general == null) { Console.WriteLine("General is null."); return; } //get build data for this role var buildData = data["items"]["mostGames"]["items"]; var items = new string[6]; for (var i = 0; i < 6; i++) { items[i] = buildData[i]["id"].ToString(); } //get matchup data to show counters and countered champions var matchupDataIE = data["matchups"].ToObject<List<MatchupModel>>(); var matchupData = matchupDataIE.OrderBy(m => m.StatScore).ToArray(); var countered = new[] { matchupData[0].Name, matchupData[1].Name, matchupData[2].Name }; var counters = new[] { matchupData[matchupData.Length - 1].Name, matchupData[matchupData.Length - 2].Name, matchupData[matchupData.Length - 3].Name }; //get runes data var runesJArray = data["runes"]["mostGames"]["runes"] as JArray; var runes = string.Join("\n", runesJArray.OrderBy(jt => int.Parse(jt["number"].ToString())).Select(jt => jt["number"].ToString() + "x" + jt["name"])); // get masteries data var masteries = (data["masteries"]["mostGames"]["masteries"] as JArray); //get skill order data<API_KEY> var orderArr = (data["skills"]["mostGames"]["order"] as JArray); var img = Image.FromFile("data/lol/bg.png"); using (var g = Graphics.FromImage(img)) { g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; //g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; const int margin = 5; const int imageSize = 75; var normalFont = new Font("Monaco", 8, FontStyle.Regular); var smallFont = new Font("Monaco", 7, FontStyle.Regular); //draw champ image var champName = data["key"].ToString().Replace(" ", ""); g.DrawImage(GetImage(champName), new Rectangle(margin, margin, imageSize, imageSize)); //draw champ name if (champName == "MonkeyKing") champName = "Wukong"; g.DrawString($"{champName}", new Font("Times New Roman", 24, FontStyle.Regular), Brushes.WhiteSmoke, margin + imageSize + margin, margin); //draw champ surname //draw skill order float orderFormula = 120 / orderArr.Count; const float orderVerticalSpacing = 10; for (var i = 0; i < orderArr.Count; i++) { var orderX = margin + margin + imageSize + orderFormula * i + i; float orderY = margin + 35; var spellName = orderArr[i].ToString().ToLowerInvariant(); switch (spellName) { case "w": orderY += orderVerticalSpacing; break; case "e": orderY += orderVerticalSpacing * 2; break; case "r": orderY += orderVerticalSpacing * 3; break; default: break; } g.DrawString(spellName.ToUpperInvariant(), new Font("Monaco", 7), Brushes.LimeGreen, orderX, orderY); } //draw roles g.DrawString("Roles: " + string.Join(", ", roles), normalFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin); //draw average stats g.DrawString( $@" Average Stats Kills: {general["kills"]} CS: {general["minionsKilled"]} Deaths: {general["deaths"]} Win: {general["winPercent"]}% Assists: {general["assists"]} Ban: {general["banRate"]}% ", normalFont, Brushes.WhiteSmoke, img.Width - 150, margin); //draw masteries g.DrawString($"Masteries: {string.Join(" / ", masteries?.Select(jt => jt["total"]))}", normalFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin + 20); //draw runes g.DrawString($"{runes}", smallFont, Brushes.WhiteSmoke, margin, margin + imageSize + margin + 40); //draw counters g.DrawString($"Best against", smallFont, Brushes.WhiteSmoke, margin, img.Height - imageSize + margin); var smallImgSize = 50; for (var i = 0; i < counters.Length; i++) { g.DrawImage(GetImage(counters[i]), new Rectangle(i * (smallImgSize + margin) + margin, img.Height - smallImgSize - margin, smallImgSize, smallImgSize)); } //draw countered by g.DrawString($"Worst against", smallFont, Brushes.WhiteSmoke, img.Width - 3 * (smallImgSize + margin), img.Height - imageSize + margin); for (var i = 0; i < countered.Length; i++) { var j = countered.Length - i; g.DrawImage(GetImage(countered[i]), new Rectangle(img.Width - (j * (smallImgSize + margin) + margin), img.Height - smallImgSize - margin, smallImgSize, smallImgSize)); } //draw item build g.DrawString("Popular build", normalFont, Brushes.WhiteSmoke, img.Width - (3 * (smallImgSize + margin) + margin), 77); for (var i = 0; i < 6; i++) { var inverseI = 5 - i; var j = inverseI % 3 + 1; var k = inverseI / 3; g.DrawImage(GetImage(items[i], GetImageType.Item), new Rectangle(img.Width - (j * (smallImgSize + margin) + margin), 92 + k * (smallImgSize + margin), smallImgSize, smallImgSize)); } } var cachedChamp = new CachedChampion { AddedAt = DateTime.Now, ImageStream = img.ToStream(System.Drawing.Imaging.ImageFormat.Png), Name = name.ToLower() + "_" + resolvedRole }; CachedChampionImages.Add(cachedChamp.Name, cachedChamp); await e.Channel.SendFile(data["title"] + "_stats.png", cachedChamp.ImageStream); } catch (Exception ex) { Console.WriteLine(ex); await e.Channel.SendMessage("💢 Failed retreiving data for that champion."); } }); cgb.CreateCommand(Module.Prefix + "lolban") .Description("Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time.") .Do(async e => { var showCount = 6; //http://api.champion.gg/stats/champs/mostBanned?api_key=YOUR_API_TOKEN&page=1&limit=2 try { var data = JObject.Parse( await Classes .SearchHelper .GetResponseStringAsync($"http://api.champion.gg/stats/champs/mostBanned?" + $"api_key={NadekoBot.Creds.LOLAPIKey}&page=1&" + $"limit={showCount}"))["data"] as JArray; var sb = new StringBuilder(); sb.AppendLine($"**Showing {showCount} top banned champions.**"); sb.AppendLine($"`{trashTalk[new Random().Next(0, trashTalk.Length)]}`"); for (var i = 0; i < data.Count; i++) { if (i % 2 == 0 && i != 0) sb.AppendLine(); sb.Append($"`{i + 1}.` **{data[i]["name"]}** "); //sb.AppendLine($" ({data[i]["general"]["banRate"]}%)"); } await e.Channel.SendMessage(sb.ToString()); } catch (Exception) { await e.Channel.SendMessage($":anger: Fail: Champion.gg didsabled ban data until next patch. Sorry for the inconvenience."); } }); }
public override void Install(ModuleManager manager) { manager.CreateCommands("", cgb => { cgb.AddCheck(PermissionChecker.Instance); commands.ForEach(cmd => cmd.Init(cgb)); cgb.CreateCommand(Prefix + "attack") .Description("Attacks a target with the given move") .Parameter("move", ParameterType.Required) .Parameter("target", ParameterType.Unparsed) .Do(async e => { var move = e.GetArg("move"); var targetStr = e.GetArg("target")?.Trim(); if (string.IsNullOrWhiteSpace(targetStr)) return; var target = e.Server.FindUsers(targetStr).FirstOrDefault(); if (target == null) { await e.Channel.SendMessage("No such person."); return; } else if (target == e.User) { await e.Channel.SendMessage("You can't attack yourself."); return; } // Checking stats first, then move //Set up the userstats PokeStats userStats; userStats = Stats.GetOrAdd(e.User.Id, new PokeStats()); //Check if able to move //User not able if HP < 0, has made more than 4 attacks if (userStats.Hp < 0) { await e.Channel.SendMessage($"{e.User.Mention} has fainted and was not able to move!"); return; } if (userStats.MovesMade >= 5) { await e.Channel.SendMessage($"{e.User.Mention} has used too many moves in a row and was not able to move!"); return; } if (userStats.LastAttacked.Contains(target.Id)) { await e.Channel.SendMessage($"{e.User.Mention} can't attack again without retaliation!"); return; } //get target stats PokeStats targetStats; targetStats = Stats.GetOrAdd(target.Id, new PokeStats()); //If target's HP is below 0, no use attacking if (targetStats.Hp <= 0) { await e.Channel.SendMessage($"{target.Mention} has already fainted!"); return; } //Check whether move can be used PokemonType userType = GetPokeType(e.User.Id); var enabledMoves = userType.Moves; if (!enabledMoves.Contains(move.ToLowerInvariant())) { await e.Channel.SendMessage($"{e.User.Mention} was not able to use **{move}**, use `{Prefix}ml` to see moves you can use"); return; } //get target type PokemonType targetType = GetPokeType(target.Id); //generate damage int damage = GetDamage(userType, targetType); //apply damage to target targetStats.Hp -= damage; var response = $"{e.User.Mention} used **{move}**{userType.Icon} on {target.Mention}{targetType.Icon} for **{damage}** damage"; //Damage type if (damage < 40) { response += "\nIt's not effective.."; } else if (damage > 60) { response += "\nIt's super effective!"; } else { response += "\nIt's somewhat effective"; } //check fainted if (targetStats.Hp <= 0) { response += $"\n**{target.Name}** has fainted!"; } else { response += $"\n**{target.Name}** has {targetStats.Hp} HP remaining"; } //update other stats userStats.LastAttacked.Add(target.Id); userStats.MovesMade++; targetStats.MovesMade = 0; if (targetStats.LastAttacked.Contains(e.User.Id)) { targetStats.LastAttacked.Remove(e.User.Id); } //update dictionary //This can stay the same right? Stats[e.User.Id] = userStats; Stats[target.Id] = targetStats; await e.Channel.SendMessage(response); }); cgb.CreateCommand(Prefix + "ml") .Alias("movelist") .Description("Lists the moves you are able to use") .Do(async e => { var userType = GetPokeType(e.User.Id); var movesList = userType.Moves; var str = $"**Moves for `{userType.Name}` type.**"; foreach (string m in movesList) { str += $"\n{userType.Icon}{m}"; } await e.Channel.SendMessage(str); }); cgb.CreateCommand(Prefix + "heal") .Description($"Heals someone. Revives those that fainted. Costs a {NadekoBot.Config.CurrencyName} \n**Usage**:{Prefix}revive @someone") .Parameter("target", ParameterType.Unparsed) .Do(async e => { var targetStr = e.GetArg("target")?.Trim(); if (string.IsNullOrWhiteSpace(targetStr)) return; var usr = e.Server.FindUsers(targetStr).FirstOrDefault(); if (usr == null) { await e.Channel.SendMessage("No such person."); return; } if (Stats.ContainsKey(usr.Id)) { var targetStats = Stats[usr.Id]; int HP = targetStats.Hp; if (targetStats.Hp == targetStats.MaxHp) { await e.Channel.SendMessage($"{usr.Name} already has full HP!"); return; } //Payment~ var amount = 1; var pts = Classes.DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0; if (pts < amount) { await e.Channel.SendMessage($"{e.User.Mention} you don't have enough {NadekoBot.Config.CurrencyName}s! \nYou still need {amount - pts} {NadekoBot.Config.CurrencySign} to be able to do this!"); return; } var target = (usr.Id == e.User.Id) ? "yourself" : usr.Name; FlowersHandler.RemoveFlowers(e.User, $"Poke-Heal {target}", amount); //healing targetStats.Hp = targetStats.MaxHp; if (HP < 0) { //Could heal only for half HP? Stats[usr.Id].Hp = (targetStats.MaxHp / 2); await e.Channel.SendMessage($"{e.User.Name} revived {usr.Name} with one {NadekoBot.Config.CurrencySign}"); return; } var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.Config.CurrencyName[0]); await e.Channel.SendMessage($"{e.User.Name} healed {usr.Name} for {targetStats.MaxHp - HP} HP with {(vowelFirst ? "an" : "a")} {NadekoBot.Config.CurrencySign}"); return; } else { await e.Channel.SendMessage($"{usr.Name} already has full HP!"); } }); cgb.CreateCommand(Prefix + "type") .Description($"Get the poketype of the target.\n**Usage**: {Prefix}type @someone") .Parameter("target", ParameterType.Unparsed) .Do(async e => { var usrStr = e.GetArg("target")?.Trim(); if (string.IsNullOrWhiteSpace(usrStr)) return; var usr = e.Server.FindUsers(usrStr).FirstOrDefault(); if (usr == null) { await e.Channel.SendMessage("No such person."); return; } var pType = GetPokeType(usr.Id); await e.Channel.SendMessage($"Type of {usr.Name} is **{pType.Name.ToLowerInvariant()}**{pType.Icon}"); }); cgb.CreateCommand(Prefix + "settype") .Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}.\n**Usage**: {Prefix}settype fire") .Parameter("targetType", ParameterType.Unparsed) .Do(async e => { var targetTypeStr = e.GetArg("targetType")?.ToUpperInvariant(); if (string.IsNullOrWhiteSpace(targetTypeStr)) return; var targetType = stringToPokemonType(targetTypeStr); if (targetType == null) { await e.Channel.SendMessage("Invalid type specified. Type must be one of:\nNORMAL, FIRE, WATER, ELECTRIC, GRASS, ICE, FIGHTING, POISON, GROUND, FLYING, PSYCHIC, BUG, ROCK, GHOST, DRAGON, DARK, STEEL"); return; } if (targetType == GetPokeType(e.User.Id)) { await e.Channel.SendMessage($"Your type is already {targetType.Name.ToLowerInvariant()}{targetType.Icon}"); return; } //Payment~ var amount = 1; var pts = DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0; if (pts < amount) { await e.Channel.SendMessage($"{e.User.Mention} you don't have enough {NadekoBot.Config.CurrencyName}s! \nYou still need {amount - pts} {NadekoBot.Config.CurrencySign} to be able to do this!"); return; } FlowersHandler.RemoveFlowers(e.User, $"set usertype to {targetTypeStr}", amount); //Actually changing the type here var preTypes = DbHandler.Instance.GetAllRows<UserPokeTypes>(); Dictionary<long, int> Dict = preTypes.ToDictionary(x => x.UserId, y => y.Id.Value); if (Dict.ContainsKey((long)e.User.Id)) { //delete previous type DbHandler.Instance.Delete<UserPokeTypes>(Dict[(long)e.User.Id]); } DbHandler.Instance.InsertData(new UserPokeTypes { UserId = (long)e.User.Id, type = targetType.Name }); //Now for the response await e.Channel.SendMessage($"Set type of {e.User.Mention} to {targetTypeStr}{targetType.Icon} for a {NadekoBot.Config.CurrencySign}"); }); }); }