Pokemon module placeholder, Dragon should PR here
This commit is contained in:
		| @@ -3,7 +3,6 @@ using Newtonsoft.Json; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| //using Manatee.Json.Serialization; | ||||
|  | ||||
| namespace NadekoBot.Classes.ClashOfClans | ||||
| { | ||||
|   | ||||
| @@ -1,17 +1,15 @@ | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes.ClashOfClans; | ||||
| using Newtonsoft.Json; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Discord; | ||||
| using NadekoBot.Services; | ||||
| using NadekoBot.Attributes; | ||||
|  | ||||
| //todo DB | ||||
| namespace NadekoBot.Modules.ClashOfClans | ||||
| { | ||||
|     [Module(",",AppendSpace = false)] | ||||
| @@ -19,8 +17,6 @@ namespace NadekoBot.Modules.ClashOfClans | ||||
|     { | ||||
|         public static ConcurrentDictionary<ulong, List<ClashWar>> ClashWars { get; set; } = new ConcurrentDictionary<ulong, List<ClashWar>>(); | ||||
|  | ||||
|         private readonly object writeLock = new object(); | ||||
|  | ||||
|         public ClashOfClansModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|         } | ||||
|   | ||||
| @@ -8,14 +8,11 @@ using System.Collections.Concurrent; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| //todo DB | ||||
| //todo Rewrite? | ||||
|  | ||||
| //todo Rewrite? Fix trivia not stopping bug | ||||
| namespace NadekoBot.Modules.Games.Commands | ||||
| { | ||||
|     public partial class GamesModule | ||||
|     { | ||||
|  | ||||
|         [Group] | ||||
|         public class TriviaCommands | ||||
|         { | ||||
|   | ||||
							
								
								
									
										26
									
								
								src/NadekoBot/Modules/Pokemon/PokemonModule.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/NadekoBot/Modules/Pokemon/PokemonModule.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| using Discord.Commands; | ||||
| using Discord; | ||||
| using NadekoBot.Attributes; | ||||
| using System.Threading.Tasks; | ||||
| using NadekoBot.Services; | ||||
|  | ||||
| namespace NadekoBot.Modules.Games.Commands | ||||
| { | ||||
|     [Module(">", AppendSpace = false)] | ||||
|     public partial class PokemonModule : DiscordModule | ||||
|     { | ||||
|         public PokemonModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         //todo Dragon should PR this in | ||||
|         [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|         [RequireContext(ContextType.Guild)] | ||||
|         public async Task Poke(IMessage imsg) | ||||
|         { | ||||
|             var channel = imsg.Channel as IGuildChannel; | ||||
|  | ||||
|  | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,15 +0,0 @@ | ||||
| using System.Collections.Generic; | ||||
|  | ||||
| namespace NadekoBot.Modules.Pokemon | ||||
| { | ||||
|     class PokeStats | ||||
|     { | ||||
|         //Health left | ||||
|         public int Hp { get; set; } = 500; | ||||
|         public int MaxHp { get; } = 500; | ||||
|         //Amount of moves made since last time attacked | ||||
|         public int MovesMade { get; set; } = 0; | ||||
|         //Last people attacked | ||||
|         public List<ulong> LastAttacked { get; set; } = new List<ulong>(); | ||||
|     } | ||||
| } | ||||
| @@ -1,339 +0,0 @@ | ||||
| using Discord.Commands; | ||||
| using Discord.Modules; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Classes.JSONModels; | ||||
| using NadekoBot.DataModels; | ||||
| using NadekoBot.Extensions; | ||||
| using NadekoBot.Modules.Permissions.Classes; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace NadekoBot.Modules.Pokemon | ||||
| { | ||||
|     class PokemonModule : DiscordModule | ||||
|     { | ||||
|         public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Pokemon; | ||||
|  | ||||
|         private ConcurrentDictionary<ulong, PokeStats> Stats = new ConcurrentDictionary<ulong, PokeStats>(); | ||||
|  | ||||
|         public PokemonModule() | ||||
|         { | ||||
|  | ||||
|         } | ||||
|  | ||||
|         private int GetDamage(PokemonType usertype, PokemonType targetType) | ||||
|         { | ||||
|             var rng = new Random(); | ||||
|             int damage = rng.Next(40, 60); | ||||
|             foreach (PokemonMultiplier Multiplier in usertype.Multipliers) | ||||
|             { | ||||
|                 if (Multiplier.Type == targetType.Name) | ||||
|                 { | ||||
|                     var multiplier = Multiplier.Multiplication; | ||||
|                     damage = (int)(damage * multiplier); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return damage; | ||||
|         } | ||||
|  | ||||
|         private PokemonType GetPokeType(ulong id) | ||||
|         { | ||||
|  | ||||
|             var db = DbHandler.Instance.GetAllRows<UserPokeTypes>(); | ||||
|             Dictionary<long, string> setTypes = db.ToDictionary(x => x.UserId, y => y.type); | ||||
|             if (setTypes.ContainsKey((long)id)) | ||||
|             { | ||||
|                 return stringToPokemonType(setTypes[(long)id]); | ||||
|             } | ||||
|             int count = NadekoBot.Config.PokemonTypes.Count; | ||||
|  | ||||
|             int remainder = Math.Abs((int)(id % (ulong)count)); | ||||
|  | ||||
|             return NadekoBot.Config.PokemonTypes[remainder]; | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|         private PokemonType stringToPokemonType(string v) | ||||
|         { | ||||
|             var str = v.ToUpperInvariant(); | ||||
|             var list = NadekoBot.Config.PokemonTypes; | ||||
|             foreach (PokemonType p in list) | ||||
|             { | ||||
|                 if (str == p.Name) | ||||
|                 { | ||||
|                     return p; | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         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. Use `{Prefix}movelist` to see a list of moves your type can use. | `{Prefix}attack \"vine whip\" @someguy`") | ||||
|                     .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 imsg.Channel.SendMessageAsync("No such person.").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|                         else if (target == e.User) | ||||
|                         { | ||||
|                             await imsg.Channel.SendMessageAsync("You can't attack yourself.").ConfigureAwait(false); | ||||
|                             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 imsg.Channel.SendMessageAsync($"{e.User.Mention} has fainted and was not able to move!").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|                         if (userStats.MovesMade >= 5) | ||||
|                         { | ||||
|                             await imsg.Channel.SendMessageAsync($"{e.User.Mention} has used too many moves in a row and was not able to move!").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|                         if (userStats.LastAttacked.Contains(target.Id)) | ||||
|                         { | ||||
|                             await imsg.Channel.SendMessageAsync($"{e.User.Mention} can't attack again without retaliation!").ConfigureAwait(false); | ||||
|                             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 imsg.Channel.SendMessageAsync($"{target.Mention} has already fainted!").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         //Check whether move can be used | ||||
|                         PokemonType userType = GetPokeType(e.User.Id); | ||||
|  | ||||
|                         var enabledMoves = userType.Moves; | ||||
|                         if (!enabledMoves.Contains(move.ToLowerInvariant())) | ||||
|                         { | ||||
|                             await imsg.Channel.SendMessageAsync($"{e.User.Mention} was not able to use **{move}**, use `{Prefix}ml` to see moves you can use").ConfigureAwait(false); | ||||
|                             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 imsg.Channel.SendMessageAsync(response).ConfigureAwait(false); | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "movelist") | ||||
|                     .Alias(Prefix + "ml") | ||||
|                     .Description($"Lists the moves you are able to use | `{Prefix}ml`") | ||||
|                     .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 imsg.Channel.SendMessageAsync(str).ConfigureAwait(false); | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "heal") | ||||
|                     .Description($"Heals someone. Revives those who fainted. Costs a {NadekoBot.Config.CurrencyName} | `{Prefix}heal @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 imsg.Channel.SendMessageAsync("No such person.").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|                         if (Stats.ContainsKey(usr.Id)) | ||||
|                         { | ||||
|  | ||||
|                             var targetStats = Stats[usr.Id]; | ||||
|                             int HP = targetStats.Hp; | ||||
|                             if (targetStats.Hp == targetStats.MaxHp) | ||||
|                             { | ||||
|                                 await imsg.Channel.SendMessageAsync($"{usr.Name} already has full HP!").ConfigureAwait(false); | ||||
|                                 return; | ||||
|                             } | ||||
|                             //Payment~ | ||||
|                             var amount = 1; | ||||
|                             var pts = Classes.DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0; | ||||
|                             if (pts < amount) | ||||
|                             { | ||||
|                                 await imsg.Channel.SendMessageAsync($"{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!").ConfigureAwait(false); | ||||
|                                 return; | ||||
|                             } | ||||
|                             var target = (usr.Id == e.User.Id) ? "yourself" : usr.Name; | ||||
|                             await FlowersHandler.RemoveFlowers(e.User, $"Poke-Heal {target}", amount).ConfigureAwait(false); | ||||
|                             //healing | ||||
|                             targetStats.Hp = targetStats.MaxHp; | ||||
|                             if (HP < 0) | ||||
|                             { | ||||
|                                 //Could heal only for half HP? | ||||
|                                 Stats[usr.Id].Hp = (targetStats.MaxHp / 2); | ||||
|                                 await imsg.Channel.SendMessageAsync($"{e.User.Name} revived {usr.Name} with one {NadekoBot.Config.CurrencySign}").ConfigureAwait(false); | ||||
|                                 return; | ||||
|                             } | ||||
|                             var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.Config.CurrencyName[0]); | ||||
|                             await imsg.Channel.SendMessageAsync($"{e.User.Name} healed {usr.Name} for {targetStats.MaxHp - HP} HP with {(vowelFirst ? "an" : "a")} {NadekoBot.Config.CurrencySign}").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             await imsg.Channel.SendMessageAsync($"{usr.Name} already has full HP!").ConfigureAwait(false); | ||||
|                         } | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "type") | ||||
|                     .Description($"Get the poketype of the target. | `{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 imsg.Channel.SendMessageAsync("No such person.").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|                         var pType = GetPokeType(usr.Id); | ||||
|                         await imsg.Channel.SendMessageAsync($"Type of {usr.Name} is **{pType.Name.ToLowerInvariant()}**{pType.Icon}").ConfigureAwait(false); | ||||
|  | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand(Prefix + "settype") | ||||
|                     .Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}. | `{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 imsg.Channel.SendMessageAsync("Invalid type specified. Type must be one of:\n" + string.Join(", ", NadekoBot.Config.PokemonTypes.Select(t => t.Name.ToUpperInvariant()))).ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|                         if (targetType == GetPokeType(e.User.Id)) | ||||
|                         { | ||||
|                             await imsg.Channel.SendMessageAsync($"Your type is already {targetType.Name.ToLowerInvariant()}{targetType.Icon}").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         //Payment~ | ||||
|                         var amount = 1; | ||||
|                         var pts = DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0; | ||||
|                         if (pts < amount) | ||||
|                         { | ||||
|                             await imsg.Channel.SendMessageAsync($"{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!").ConfigureAwait(false); | ||||
|                             return; | ||||
|                         } | ||||
|                         await FlowersHandler.RemoveFlowers(e.User, $"set usertype to {targetTypeStr}", amount).ConfigureAwait(false); | ||||
|                         //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.Connection.Insert(new UserPokeTypes | ||||
|                         { | ||||
|                             UserId = (long)e.User.Id, | ||||
|                             type = targetType.Name | ||||
|                         }, typeof(UserPokeTypes)); | ||||
|  | ||||
|                         //Now for the response | ||||
|  | ||||
|                         await imsg.Channel.SendMessageAsync($"Set type of {e.User.Mention} to {targetTypeStr}{targetType.Icon} for a {NadekoBot.Config.CurrencySign}").ConfigureAwait(false); | ||||
|                     }); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user