Merge pull request #26 from Kwoth/dev

Poké
This commit is contained in:
samvaio 2016-12-05 12:21:24 +05:30 committed by GitHub
commit 1c5cdbba03
16 changed files with 2228 additions and 4 deletions

View File

@ -0,0 +1,802 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
using NadekoBot.Modules.Music.Classes;
namespace NadekoBot.Migrations
{
[DbContext(typeof(NadekoContext))]
[Migration("20161127233843_PokeGame")]
partial class PokeGame
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.1.0-rtm-22752");
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<ulong>("ItemId");
b.Property<int>("Type");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("BlacklistItem");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("BufferSize");
b.Property<float>("CurrencyGenerationChance");
b.Property<int>("CurrencyGenerationCooldown");
b.Property<string>("CurrencyName");
b.Property<string>("CurrencyPluralName");
b.Property<string>("CurrencySign");
b.Property<string>("DMHelpString");
b.Property<bool>("ForwardMessages");
b.Property<bool>("ForwardToAllOwners");
b.Property<string>("HelpString");
b.Property<int>("MigrationVersion");
b.Property<string>("RemindMessageFormat");
b.Property<bool>("RotatingStatuses");
b.HasKey("Id");
b.ToTable("BotConfig");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("BaseDestroyed");
b.Property<string>("CallUser");
b.Property<int>("ClashWarId");
b.Property<int?>("SequenceNumber");
b.Property<int>("Stars");
b.Property<DateTime>("TimeAdded");
b.HasKey("Id");
b.HasIndex("ClashWarId");
b.ToTable("ClashCallers");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<string>("EnemyClan");
b.Property<ulong>("GuildId");
b.Property<int>("Size");
b.Property<DateTime>("StartedAt");
b.Property<int>("WarState");
b.HasKey("Id");
b.ToTable("ClashOfClans");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("CommandName");
b.Property<int?>("GuildConfigId");
b.Property<int>("Seconds");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("CommandCooldown");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("InternalTrigger");
b.Property<decimal>("Modifier");
b.Property<string>("UnitType");
b.HasKey("Id");
b.ToTable("ConversionUnits");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("Amount");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("Currency");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("Amount");
b.Property<string>("Reason");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.ToTable("CurrencyTransactions");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong?>("GuildId");
b.Property<bool>("IsRegex");
b.Property<bool>("OwnerOnly");
b.Property<string>("Response");
b.Property<string>("Trigger");
b.HasKey("Id");
b.ToTable("CustomReactions");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Amount");
b.Property<string>("Name");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("Donators");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Text");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("EightBallResponses");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.Property<int?>("GuildConfigId1");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.HasIndex("GuildConfigId1");
b.ToTable("FilterChannelId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("GuildConfigId");
b.Property<string>("Word");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("FilteredWord");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.Property<ulong>("GuildId");
b.Property<int>("Type");
b.Property<string>("Username");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("FollowedStream");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("GCChannelId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("AutoAssignRoleId");
b.Property<bool>("AutoDeleteByeMessages");
b.Property<int>("AutoDeleteByeMessagesTimer");
b.Property<bool>("AutoDeleteGreetMessages");
b.Property<int>("AutoDeleteGreetMessagesTimer");
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
b.Property<ulong>("ByeMessageChannelId");
b.Property<string>("ChannelByeMessageText");
b.Property<string>("ChannelGreetMessageText");
b.Property<bool>("CleverbotEnabled");
b.Property<float>("DefaultMusicVolume");
b.Property<bool>("DeleteMessageOnCommand");
b.Property<string>("DmGreetMessageText");
b.Property<bool>("ExclusiveSelfAssignedRoles");
b.Property<bool>("FilterInvites");
b.Property<bool>("FilterWords");
b.Property<ulong>("GreetMessageChannelId");
b.Property<ulong>("GuildId");
b.Property<int?>("LogSettingId");
b.Property<string>("MuteRoleName");
b.Property<string>("PermissionRole");
b.Property<int?>("RootPermissionId");
b.Property<bool>("SendChannelByeMessage");
b.Property<bool>("SendChannelGreetMessage");
b.Property<bool>("SendDmGreetMessage");
b.Property<bool>("VerbosePermissions");
b.Property<bool>("VoicePlusTextEnabled");
b.HasKey("Id");
b.HasIndex("GuildId")
.IsUnique();
b.HasIndex("LogSettingId");
b.HasIndex("RootPermissionId");
b.ToTable("GuildConfigs");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("LogSettingId");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredLogChannels");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("LogSettingId");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredVoicePresenceCHannels");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("ChannelCreated");
b.Property<bool>("ChannelDestroyed");
b.Property<ulong>("ChannelId");
b.Property<bool>("ChannelUpdated");
b.Property<bool>("IsLogging");
b.Property<bool>("LogUserPresence");
b.Property<bool>("LogVoicePresence");
b.Property<bool>("MessageDeleted");
b.Property<bool>("MessageUpdated");
b.Property<bool>("UserBanned");
b.Property<bool>("UserJoined");
b.Property<bool>("UserLeft");
b.Property<ulong>("UserPresenceChannelId");
b.Property<bool>("UserUnbanned");
b.Property<bool>("UserUpdated");
b.Property<ulong>("VoicePresenceChannelId");
b.HasKey("Id");
b.ToTable("LogSettings");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("ModuleName");
b.Property<string>("Prefix");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("ModulePrefixes");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Author");
b.Property<ulong>("AuthorId");
b.Property<string>("Name");
b.HasKey("Id");
b.ToTable("MusicPlaylists");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("NextId");
b.Property<int>("PrimaryTarget");
b.Property<ulong>("PrimaryTargetId");
b.Property<int>("SecondaryTarget");
b.Property<string>("SecondaryTargetName");
b.Property<bool>("State");
b.HasKey("Id");
b.HasIndex("NextId")
.IsUnique();
b.ToTable("Permission");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Status");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("PlayingStatus");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("MusicPlaylistId");
b.Property<string>("Provider");
b.Property<int>("ProviderType");
b.Property<string>("Query");
b.Property<string>("Title");
b.Property<string>("Uri");
b.HasKey("Id");
b.HasIndex("MusicPlaylistId");
b.ToTable("PlaylistSong");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("AuthorId");
b.Property<string>("AuthorName")
.IsRequired();
b.Property<ulong>("GuildId");
b.Property<string>("Keyword")
.IsRequired();
b.Property<string>("Text")
.IsRequired();
b.HasKey("Id");
b.ToTable("Quotes");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Icon");
b.Property<string>("Name");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("RaceAnimals");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<bool>("IsPrivate");
b.Property<string>("Message");
b.Property<ulong>("ServerId");
b.Property<ulong>("UserId");
b.Property<DateTime>("When");
b.HasKey("Id");
b.ToTable("Reminders");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<ulong>("GuildId");
b.Property<TimeSpan>("Interval");
b.Property<string>("Message");
b.HasKey("Id");
b.HasIndex("ChannelId")
.IsUnique();
b.ToTable("Repeaters");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("GuildId");
b.Property<ulong>("RoleId");
b.HasKey("Id");
b.HasIndex("GuildId", "RoleId")
.IsUnique();
b.ToTable("SelfAssignableRoles");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("UserId");
b.Property<string>("type");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("PokeGame");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("Blacklist")
.HasForeignKey("BotConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar")
.WithMany("Bases")
.HasForeignKey("ClashWarId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("CommandCooldowns")
.HasForeignKey("GuildConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("EightBallResponses")
.HasForeignKey("BotConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("FilterInvitesChannelIds")
.HasForeignKey("GuildConfigId");
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("FilterWordsChannelIds")
.HasForeignKey("GuildConfigId1");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("FilteredWords")
.HasForeignKey("GuildConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("FollowedStreams")
.HasForeignKey("GuildConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("GenerateCurrencyChannelIds")
.HasForeignKey("GuildConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
.WithMany()
.HasForeignKey("LogSettingId");
b.HasOne("NadekoBot.Services.Database.Models.Permission", "RootPermission")
.WithMany()
.HasForeignKey("RootPermissionId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
.WithMany("IgnoredChannels")
.HasForeignKey("LogSettingId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
.WithMany("IgnoredVoicePresenceChannelIds")
.HasForeignKey("LogSettingId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("ModulePrefixes")
.HasForeignKey("BotConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.Permission", "Next")
.WithOne("Previous")
.HasForeignKey("NadekoBot.Services.Database.Models.Permission", "NextId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("RotatingStatusMessages")
.HasForeignKey("BotConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.MusicPlaylist")
.WithMany("Songs")
.HasForeignKey("MusicPlaylistId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
.WithMany("RaceAnimals")
.HasForeignKey("BotConfigId");
});
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace NadekoBot.Migrations
{
public partial class PokeGame : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "PokeGame",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<ulong>(nullable: false),
type = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PokeGame", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_PokeGame_UserId",
table: "PokeGame",
column: "UserId",
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "PokeGame");
}
}
}

View File

@ -658,6 +658,23 @@ namespace NadekoBot.Migrations
b.ToTable("SelfAssignableRoles");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("UserId");
b.Property<string>("type");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("PokeGame");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")

View File

@ -0,0 +1,15 @@
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>();
}
}

View File

@ -0,0 +1,375 @@
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using System.Linq;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using Discord;
using NLog;
using System;
using Newtonsoft.Json;
using System.IO;
using System.Collections.Concurrent;
using static NadekoBot.Modules.Gambling.Gambling;
namespace NadekoBot.Modules.Pokemon
{
[NadekoModule("Pokemon", ">")]
public partial class Pokemon : DiscordModule
{
private static List<PokemonType> PokemonTypes = new List<PokemonType>();
private static ConcurrentDictionary<ulong, PokeStats> Stats = new ConcurrentDictionary<ulong, PokeStats>();
public const string PokemonTypesFile = "data/pokemon_types.json";
private Logger _pokelog { get; }
public Pokemon(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client)
{
_pokelog = LogManager.GetCurrentClassLogger();
if (File.Exists(PokemonTypesFile))
{
PokemonTypes = JsonConvert.DeserializeObject<List<PokemonType>>(File.ReadAllText(PokemonTypesFile));
}
else
{
_pokelog.Warn(PokemonTypesFile + " is missing. Pokemon types not loaded.");
}
}
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)
{
Dictionary<ulong, string> setTypes;
using (var uow = DbHandler.UnitOfWork())
{
setTypes = uow.PokeGame.GetAll().ToDictionary(x => x.UserId, y => y.type);
}
if (setTypes.ContainsKey(id))
{
return StringToPokemonType(setTypes[id]);
}
int count = PokemonTypes.Count;
int remainder = Math.Abs((int)(id % (ulong)count));
return PokemonTypes[remainder];
}
private PokemonType StringToPokemonType(string v)
{
var str = v?.ToUpperInvariant();
var list = PokemonTypes;
foreach (PokemonType p in list)
{
if (str == p.Name)
{
return p;
}
}
return null;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Attack(IUserMessage umsg, string move, IGuildUser targetUser = null)
{
var channel = (ITextChannel)umsg.Channel;
IGuildUser user = (IGuildUser)umsg.Author;
if (string.IsNullOrWhiteSpace(move)) {
return;
}
if (targetUser == null)
{
await channel.SendMessageAsync("No such person.").ConfigureAwait(false);
return;
}
else if (targetUser == user)
{
await channel.SendMessageAsync("You can't attack yourself.").ConfigureAwait(false);
return;
}
// Checking stats first, then move
//Set up the userstats
PokeStats userStats;
userStats = Stats.GetOrAdd(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 channel.SendMessageAsync($"{user.Mention} has fainted and was not able to move!").ConfigureAwait(false);
return;
}
if (userStats.MovesMade >= 5)
{
await channel.SendMessageAsync($"{user.Mention} has used too many moves in a row and was not able to move!").ConfigureAwait(false);
return;
}
if (userStats.LastAttacked.Contains(targetUser.Id))
{
await channel.SendMessageAsync($"{user.Mention} can't attack again without retaliation!").ConfigureAwait(false);
return;
}
//get target stats
PokeStats targetStats;
targetStats = Stats.GetOrAdd(targetUser.Id, new PokeStats());
//If target's HP is below 0, no use attacking
if (targetStats.Hp <= 0)
{
await channel.SendMessageAsync($"{targetUser.Mention} has already fainted!").ConfigureAwait(false);
return;
}
//Check whether move can be used
PokemonType userType = GetPokeType(user.Id);
var enabledMoves = userType.Moves;
if (!enabledMoves.Contains(move.ToLowerInvariant()))
{
await channel.SendMessageAsync($"{user.Mention} is not able to use **{move}**. Type {NadekoBot.ModulePrefixes[typeof(Pokemon).Name]}ml to see moves").ConfigureAwait(false);
return;
}
//get target type
PokemonType targetType = GetPokeType(targetUser.Id);
//generate damage
int damage = GetDamage(userType, targetType);
//apply damage to target
targetStats.Hp -= damage;
var response = $"{user.Mention} used **{move}**{userType.Icon} on {targetUser.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**{targetUser.Mention}** has fainted!";
}
else
{
response += $"\n**{targetUser.Mention}** has {targetStats.Hp} HP remaining";
}
//update other stats
userStats.LastAttacked.Add(targetUser.Id);
userStats.MovesMade++;
targetStats.MovesMade = 0;
if (targetStats.LastAttacked.Contains(user.Id))
{
targetStats.LastAttacked.Remove(user.Id);
}
//update dictionary
//This can stay the same right?
Stats[user.Id] = userStats;
Stats[targetUser.Id] = targetStats;
await channel.SendMessageAsync(response).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Movelist(IUserMessage umsg)
{
var channel = (ITextChannel)umsg.Channel;
IGuildUser user = (IGuildUser)umsg.Author;
var userType = GetPokeType(user.Id);
var movesList = userType.Moves;
var str = $"**Moves for `{userType.Name}` type.**";
foreach (string m in movesList)
{
str += $"\n{userType.Icon}{m}";
}
await channel.SendMessageAsync(str).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Heal(IUserMessage umsg, IGuildUser targetUser = null)
{
var channel = (ITextChannel)umsg.Channel;
IGuildUser user = (IGuildUser)umsg.Author;
if (targetUser == null) {
await channel.SendMessageAsync("No such person.").ConfigureAwait(false);
return;
}
if (Stats.ContainsKey(targetUser.Id))
{
var targetStats = Stats[targetUser.Id];
if (targetStats.Hp == targetStats.MaxHp)
{
await channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false);
return;
}
//Payment~
var amount = 1;
var target = (targetUser.Id == user.Id) ? "yourself" : targetUser.Mention;
if (amount > 0)
{
if (!await CurrencyHandler.RemoveCurrencyAsync(user, $"Poke-Heal {target}", amount, true).ConfigureAwait(false))
{
try { await channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { }
return;
}
}
//healing
targetStats.Hp = targetStats.MaxHp;
if (targetStats.Hp < 0)
{
//Could heal only for half HP?
Stats[targetUser.Id].Hp = (targetStats.MaxHp / 2);
if (target == "yourself")
{
await channel.SendMessageAsync($"You revived yourself with one {CurrencySign}").ConfigureAwait(false);
}
else
{
await channel.SendMessageAsync($"{user.Mention} revived {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false);
}
return;
}
await channel.SendMessageAsync($"{user.Mention} healed {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false);
return;
}
else
{
await channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false);
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Type(IUserMessage umsg, IGuildUser targetUser = null)
{
var channel = (ITextChannel)umsg.Channel;
IGuildUser user = (IGuildUser)umsg.Author;
if (targetUser == null)
{
return;
}
var pType = GetPokeType(targetUser.Id);
await channel.SendMessageAsync($"Type of {targetUser.Mention} is **{pType.Name.ToLowerInvariant()}**{pType.Icon}").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Settype(IUserMessage umsg, [Remainder] string typeTargeted = null)
{
var channel = (ITextChannel)umsg.Channel;
IGuildUser user = (IGuildUser)umsg.Author;
var targetType = StringToPokemonType(typeTargeted);
if (targetType == null)
{
await channel.SendTableAsync<PokemonType>("`Available types:`\n", PokemonTypes, (t) => $"{t.Icon} {t.Name,-10}").ConfigureAwait(false);
return;
}
if (targetType == GetPokeType(user.Id))
{
await channel.SendMessageAsync($"Your type is already {targetType.Name.ToLowerInvariant()}{targetType.Icon}").ConfigureAwait(false);
return;
}
//Payment~
var amount = 1;
if (amount > 0)
{
if (!await CurrencyHandler.RemoveCurrencyAsync(user, $"{user.Mention} change type to {typeTargeted}", amount, true).ConfigureAwait(false))
{
try { await channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { }
return;
}
}
//Actually changing the type here
Dictionary<ulong, string> setTypes;
using (var uow = DbHandler.UnitOfWork())
{
var pokeUsers = uow.PokeGame.GetAll();
setTypes = pokeUsers.ToDictionary(x => x.UserId, y => y.type);
var pt = new UserPokeTypes
{
UserId = user.Id,
type = targetType.Name,
};
if (!setTypes.ContainsKey(user.Id))
{
//create user in db
uow.PokeGame.Add(pt);
}
else
{
//update user in db
var pokeUserCmd = pokeUsers.Where(p => p.UserId == user.Id).FirstOrDefault();
pokeUserCmd.type = targetType.Name;
uow.PokeGame.Update(pokeUserCmd);
}
await uow.CompleteAsync();
}
//Now for the response
await channel.SendMessageAsync($"Set type of {user.Mention} to {typeTargeted}{targetType.Icon} for a {CurrencySign}").ConfigureAwait(false);
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Pokemon
{
public class PokemonType
{
public PokemonType(string n, string i, string[] m, List<PokemonMultiplier> multi)
{
Name = n;
Icon = i;
Moves = m;
Multipliers = multi;
}
public string Name { get; set; }
public List<PokemonMultiplier> Multipliers { get; set; }
public string Icon { get; set; }
public string[] Moves { get; set; }
}
public class PokemonMultiplier
{
public PokemonMultiplier(string t, double m)
{
Type = t;
Multiplication = m;
}
public string Type { get; set; }
public double Multiplication { get; set; }
}
}

View File

@ -491,6 +491,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to attack.
/// </summary>
public static string attack_cmd {
get {
return ResourceManager.GetString("attack_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Attacks a target with the given move. Use `{0}movelist` to see a list of moves your type can use..
/// </summary>
public static string attack_desc {
get {
return ResourceManager.GetString("attack_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}attack &quot;vine whip&quot; @someguy`.
/// </summary>
public static string attack_usage {
get {
return ResourceManager.GetString("attack_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to autoassignrole aar.
/// </summary>
@ -2894,6 +2921,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to heal.
/// </summary>
public static string heal_cmd {
get {
return ResourceManager.GetString("heal_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Heals someone. Revives those who fainted. Costs a NadekoFlower.
/// </summary>
public static string heal_desc {
get {
return ResourceManager.GetString("heal_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}heal @someone`.
/// </summary>
public static string heal_usage {
get {
return ResourceManager.GetString("heal_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to hearthstone hs.
/// </summary>
@ -4271,6 +4325,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to movelist ml.
/// </summary>
public static string movelist_cmd {
get {
return ResourceManager.GetString("movelist_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lists the moves you are able to use.
/// </summary>
public static string movelist_desc {
get {
return ResourceManager.GetString("movelist_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}ml`.
/// </summary>
public static string movelist_usage {
get {
return ResourceManager.GetString("movelist_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to moveperm mp.
/// </summary>
@ -6269,6 +6350,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to settype.
/// </summary>
public static string settype_cmd {
get {
return ResourceManager.GetString("settype_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Set your poketype. Costs a NadekoFlower. Provide no arguments to see a list of available types..
/// </summary>
public static string settype_desc {
get {
return ResourceManager.GetString("settype_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}settype fire` or `{0}settype`.
/// </summary>
public static string settype_usage {
get {
return ResourceManager.GetString("settype_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to shorten.
/// </summary>
@ -6971,6 +7079,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to type.
/// </summary>
public static string type_cmd {
get {
return ResourceManager.GetString("type_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Get the poketype of the target..
/// </summary>
public static string type_desc {
get {
return ResourceManager.GetString("type_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}type @someone`.
/// </summary>
public static string type_usage {
get {
return ResourceManager.GetString("type_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to typeadd.
/// </summary>

View File

@ -2718,4 +2718,49 @@
<data name="yodify_usage" xml:space="preserve">
<value>{0}yodify I was once an adventurer like you` or `{0}yoda my feelings hurt`</value>
</data>
<data name="attack_cmd" xml:space="preserve">
<value>attack</value>
</data>
<data name="attack_desc" xml:space="preserve">
<value>Attacks a target with the given move. Use `{0}movelist` to see a list of moves your type can use.</value>
</data>
<data name="attack_usage" xml:space="preserve">
<value>`{0}attack "vine whip" @someguy`</value>
</data>
<data name="heal_cmd" xml:space="preserve">
<value>heal</value>
</data>
<data name="heal_desc" xml:space="preserve">
<value>Heals someone. Revives those who fainted. Costs a NadekoFlower</value>
</data>
<data name="heal_usage" xml:space="preserve">
<value>`{0}heal @someone`</value>
</data>
<data name="movelist_cmd" xml:space="preserve">
<value>movelist ml</value>
</data>
<data name="movelist_desc" xml:space="preserve">
<value>Lists the moves you are able to use</value>
</data>
<data name="movelist_usage" xml:space="preserve">
<value>`{0}ml`</value>
</data>
<data name="settype_cmd" xml:space="preserve">
<value>settype</value>
</data>
<data name="settype_desc" xml:space="preserve">
<value>Set your poketype. Costs a NadekoFlower. Provide no arguments to see a list of available types.</value>
</data>
<data name="settype_usage" xml:space="preserve">
<value>`{0}settype fire` or `{0}settype`</value>
</data>
<data name="type_cmd" xml:space="preserve">
<value>type</value>
</data>
<data name="type_desc" xml:space="preserve">
<value>Get the poketype of the target.</value>
</data>
<data name="type_usage" xml:space="preserve">
<value>`{0}type @someone`</value>
</data>
</root>

View File

@ -21,6 +21,7 @@ namespace NadekoBot.Services.Database
ICurrencyRepository Currency { get; }
ICurrencyTransactionsRepository CurrencyTransactions { get; }
IMusicPlaylistRepository MusicPlaylists { get; }
IPokeGameRepository PokeGame { get; }
int Complete();
Task<int> CompleteAsync();

View File

@ -0,0 +1,15 @@
using Discord;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Services.Database.Models
{
public class UserPokeTypes : DbEntity
{
public ulong UserId { get; set; }
public string type { get; set; }
}
}

View File

@ -22,6 +22,7 @@ namespace NadekoBot.Services.Database
public DbSet<MusicPlaylist> MusicPlaylists { get; set; }
public DbSet<CustomReaction> CustomReactions { get; set; }
public DbSet<CurrencyTransaction> CurrencyTransactions { get; set; }
public DbSet<UserPokeTypes> PokeGame { get; set; }
//logging
public DbSet<LogSetting> LogSettings { get; set; }
@ -43,6 +44,7 @@ namespace NadekoBot.Services.Database
this.Database.Migrate();
EnsureSeedData();
}
//Uncomment this to db initialisation with dotnet ef migration add [module]
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// optionsBuilder.UseSqlite("Filename=./data/NadekoBot.db");
@ -69,7 +71,8 @@ namespace NadekoBot.Services.Database
new ModulePrefix() { ModuleName = "Permissions", Prefix = ";" },
new ModulePrefix() { ModuleName = "Pokemon", Prefix = ">" },
new ModulePrefix() { ModuleName = "Utility", Prefix = "." },
new ModulePrefix() { ModuleName = "CustomReactions", Prefix = "." }
new ModulePrefix() { ModuleName = "CustomReactions", Prefix = "." },
new ModulePrefix() { ModuleName = "PokeGame", Prefix = ">" }
});
bc.RaceAnimals.AddRange(new HashSet<RaceAnimal>
{
@ -216,7 +219,17 @@ namespace NadekoBot.Services.Database
.HasMany(p => p.Songs)
.WithOne()
.OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Cascade);
#endregion
#region PokeGame
var pokeGameEntity = modelBuilder.Entity<UserPokeTypes>();
pokeGameEntity
.HasIndex(pt => pt.UserId)
.IsUnique();
#endregion
}

View File

@ -0,0 +1,10 @@
using NadekoBot.Services.Database.Models;
using System.Collections.Generic;
namespace NadekoBot.Services.Database.Repositories
{
public interface IPokeGameRepository : IRepository<UserPokeTypes>
{
//List<UserPokeTypes> GetAllPokeTypes();
}
}

View File

@ -0,0 +1,23 @@
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace NadekoBot.Services.Database.Repositories.Impl
{
public class PokeGameRepository : Repository<UserPokeTypes>, IPokeGameRepository
{
public PokeGameRepository(DbContext context) : base(context)
{
}
//List<UserPokeTypes> GetAllPokeTypes()
//{
// var toReturn = _set.Include(pt => pt.UserId).ToList();
// toReturn.ForEach(pt => pt.).ToList();
// return toReturn;
//}
}
}

View File

@ -48,6 +48,9 @@ namespace NadekoBot.Services.Database
private ICustomReactionRepository _customReactions;
public ICustomReactionRepository CustomReactions => _customReactions ?? (_customReactions = new CustomReactionsRepository(_context));
private IPokeGameRepository _pokegame;
public IPokeGameRepository PokeGame => _pokegame ?? (_pokegame = new PokeGameRepository(_context));
public UnitOfWork(NadekoContext context)
{
_context = context;

View File

@ -1,9 +1,9 @@
{
"ClientId": 123123123,
"BotId": null,
"Token": "",
"Token": "MTE5Nzc3MDIxMzE5NTc3NjEw.CyXckQ.fmDOe4x1QRK_6hQYvS8drohUwNM",
"OwnerIds": [
0
105635576866156544
],
"LoLApiKey": "",
"GoogleApiKey": "",

View File

@ -0,0 +1,699 @@
[
{
"Name": "NORMAL",
"Multipliers": [
{
"Type": "ROCK",
"Multiplication": 0.5
},
{
"Type": "GHOST",
"Multiplication": 0
},
{
"Type": "STEEL",
"Multiplication": 0.5
}
],
"Moves": [
"sonic boom",
"quick attack",
"doubleslap",
"headbutt"
],
"Icon": "⭕️"
},
{
"Name": "FIRE",
"Multipliers": [
{
"Type": "FIRE",
"Multiplication": 0.5
},
{
"Type": "WATER",
"Multiplication": 0.5
},
{
"Type": "GRASS",
"Multiplication": 2
},
{
"Type": "ICE",
"Multiplication": 2
},
{
"Type": "BUG",
"Multiplication": 2
},
{
"Type": "ROCK",
"Multiplication": 0.5
},
{
"Type": "DRAGON",
"Multiplication": 0.5
},
{
"Type": "STEEL",
"Multiplication": 2
}
],
"Moves": [
"incinerate",
"ember",
"fire punch",
"fiery dance"
],
"Icon": "🔥"
},
{
"Name": "WATER",
"Multipliers": [
{
"Type": "FIRE",
"Multiplication": 2
},
{
"Type": "WATER",
"Multiplication": 0.5
},
{
"Type": "GRASS",
"Multiplication": 0.5
},
{
"Type": "GROUND",
"Multiplication": 2
},
{
"Type": "ROCK",
"Multiplication": 2
},
{
"Type": "DRAGON",
"Multiplication": 0.5
}
],
"Moves": [
"bubblebeam",
"dive",
"whirlpool",
"aqua tail"
],
"Icon": "💦"
},
{
"Name": "ELECTRIC",
"Multipliers": [
{
"Type": "WATER",
"Multiplication": 2
},
{
"Type": "ELECTRIC",
"Multiplication": 0.5
},
{
"Type": "GRASS",
"Multiplication": 0.5
},
{
"Type": "GROUND",
"Multiplication": 0
},
{
"Type": "FLYING",
"Multiplication": 2
},
{
"Type": "DRAGON",
"Multiplication": 0.5
}
],
"Moves": [
"nuzzle",
"thunderbolt",
"thundershock",
"discharge"
],
"Icon": "⚡"
},
{
"Name": "GRASS",
"Multipliers": [
{
"Type": "FIRE",
"Multiplication": 0.5
},
{
"Type": "WATER",
"Multiplication": 2
},
{
"Type": "GRASS",
"Multiplication": 0.5
},
{
"Type": "ICE",
"Multiplication": 0.5
},
{
"Type": "BUG",
"Multiplication": 0.5
},
{
"Type": "ROCK",
"Multiplication": 2
},
{
"Type": "DRAGON",
"Multiplication": 0.5
},
{
"Type": "STEEL",
"Multiplication": 0.5
},
{
"Type": "POISON",
"Multiplication": 0.5
},
{
"Type": "GROUND",
"Multiplication": 2
}
],
"Moves": [
"absorb",
"mega drain",
"vine whip",
"razor leaf"
],
"Icon": "🍃"
},
{
"Name": "ICE",
"Multipliers": [
{
"Type": "FIRE",
"Multiplication": 0.5
},
{
"Type": "WATER",
"Multiplication": 0.5
},
{
"Type": "GRASS",
"Multiplication": 2
},
{
"Type": "ICE",
"Multiplication": 0.5
},
{
"Type": "GROUND",
"Multiplication": 2
},
{
"Type": "FLYING",
"Multiplication": 2
},
{
"Type": "DRAGON",
"Multiplication": 2
},
{
"Type": "STEEL",
"Multiplication": 0.5
}
],
"Moves": [
"ice ball",
"powder snow",
"avalanche",
"icy wind"
],
"Icon": "❄"
},
{
"Name": "FIGHTING",
"Multipliers": [
{
"Type": "NORMAL",
"Multiplication": 2
},
{
"Type": "ICE",
"Multiplication": 2
},
{
"Type": "POISON",
"Multiplication": 0.5
},
{
"Type": "FLYING",
"Multiplication": 0.5
},
{
"Type": "PSYCHIC",
"Multiplication": 0.5
},
{
"Type": "BUG",
"Multiplication": 0.5
},
{
"Type": "ROCK",
"Multiplication": 2
},
{
"Type": "GHOST",
"Multiplication": 0
},
{
"Type": "DARK",
"Multiplication": 2
},
{
"Type": "STEEL",
"Multiplication": 2
},
{
"Type": "FAIRY",
"Multiplication": 0.5
}
],
"Moves": [
"low kick",
"force palm",
"mach punch",
"double kick"
],
"Icon": "✊"
},
{
"Name": "POISON",
"Multipliers": [
{
"Type": "GRASS",
"Multiplication": 2
},
{
"Type": "POISON",
"Multiplication": 0.5
},
{
"Type": "GROUND",
"Multiplication": 0.5
},
{
"Type": "ROCK",
"Multiplication": 0.5
},
{
"Type": "GHOST",
"Multiplication": 0.5
},
{
"Type": "STEEL",
"Multiplication": 0
},
{
"Type": "FAIRY",
"Multiplication": 2
}
],
"Moves": [
"acid",
"smog",
"sludge",
"poison jab"
],
"Icon": "☠"
},
{
"Name": "GROUND",
"Multipliers": [
{
"Type": "FIRE",
"Multiplication": 2
},
{
"Type": "ELECTRIC",
"Multiplication": 2
},
{
"Type": "GRASS",
"Multiplication": 0.5
},
{
"Type": "POISON",
"Multiplication": 2
},
{
"Type": "FLYING",
"Multiplication": 0
},
{
"Type": "BUG",
"Multiplication": 0.5
},
{
"Type": "ROCK",
"Multiplication": 2
},
{
"Type": "STEEL",
"Multiplication": 2
}
],
"Moves": [
"mud-slap",
"earthquake",
"bulldoze",
"dig"
],
"Icon": "🗻"
},
{
"Name": "FLYING",
"Multipliers": [
{
"Type": "ELECTRIC",
"Multiplication": 0.5
},
{
"Type": "GRASS",
"Multiplication": 2
},
{
"Type": "FIGHTING",
"Multiplication": 2
},
{
"Type": "BUG",
"Multiplication": 2
},
{
"Type": "ROCK",
"Multiplication": 0.5
},
{
"Type": "STEEL",
"Multiplication": 0.5
}
],
"Moves": [
"peck",
"pluck",
"gust",
"aerial ace"
],
"Icon": "☁"
},
{
"Name": "PSYCHIC",
"Multipliers": [
{
"Type": "FIGHTING",
"Multiplication": 2
},
{
"Type": "POISON",
"Multiplication": 2
},
{
"Type": "PSYCHIC",
"Multiplication": 0.5
},
{
"Type": "DARK",
"Multiplication": 0
},
{
"Type": "STEEL",
"Multiplication": 0.5
}
],
"Moves": [
"confusion",
"psybeam",
"psywave",
"heart stamp"
],
"Icon": "🔮"
},
{
"Name": "BUG",
"Multipliers": [
{
"Type": "FIRE",
"Multiplication": 0.5
},
{
"Type": "GRASS",
"Multiplication": 2
},
{
"Type": "FIGHTING",
"Multiplication": 0.5
},
{
"Type": "POISON",
"Multiplication": 0.5
},
{
"Type": "FLYING",
"Multiplication": 0.5
},
{
"Type": "PSYCHIC",
"Multiplication": 2
},
{
"Type": "ROCK",
"Multiplication": 0.5
},
{
"Type": "DARK",
"Multiplication": 2
},
{
"Type": "STEEL",
"Multiplication": 0.5
},
{
"Type": "FAIRY",
"Multiplication": 0.5
}
],
"Moves": [
"bug bite",
"infestation",
"x-scissors",
"twineedle"
],
"Icon": "🐛"
},
{
"Name": "ROCK",
"Multipliers": [
{
"Type": "FIRE",
"Multiplication": 2
},
{
"Type": "ICE",
"Multiplication": 2
},
{
"Type": "FIGHTING",
"Multiplication": 0.5
},
{
"Type": "GROUND",
"Multiplication": 0.5
},
{
"Type": "FLYING",
"Multiplication": 2
},
{
"Type": "BUG",
"Multiplication": 2
},
{
"Type": "STEEL",
"Multiplication": 0.5
}
],
"Moves": [
"rock throw",
"rollout",
"rock tomb",
"rock blast"
],
"Icon": "💎"
},
{
"Name": "GHOST",
"Multipliers": [
{
"Type": "NORMAL",
"Multiplication": 0
},
{
"Type": "PSYCHIC",
"Multiplication": 2
},
{
"Type": "GHOST",
"Multiplication": 2
},
{
"Type": "DARK",
"Multiplication": 0.5
}
],
"Moves": [
"astonish",
"night shade",
"lick",
"ominous wind",
"hex"
],
"Icon": "👻"
},
{
"Name": "DRAGON",
"Multipliers": [
{
"Type": "DRAGON",
"Multiplication": 2
},
{
"Type": "STEEL",
"Multiplication": 0.5
},
{
"Type": "FAIRY",
"Multiplication": 0
}
],
"Moves": [
"dragon tail",
"dragon rage",
"dragonbreath",
"twister"
],
"Icon": "🐉"
},
{
"Name": "DARK",
"Multipliers": [
{
"Type": "FIGHTING",
"Multiplication": 0.5
},
{
"Type": "PSYCHIC",
"Multiplication": 2
},
{
"Type": "GHOST",
"Multiplication": 2
},
{
"Type": "DARK",
"Multiplication": 0.5
},
{
"Type": "FAIRY",
"Multiplication": 0.5
}
],
"Moves": [
"pursuit",
"assurance",
"bite",
"faint attack"
],
"Icon": "✴"
},
{
"Name": "STEEL",
"Multipliers": [
{
"Type": "FIRE",
"Multiplication": 0.5
},
{
"Type": "WATER",
"Multiplication": 0.5
},
{
"Type": "ELECTRIC",
"Multiplication": 0.5
},
{
"Type": "ICE",
"Multiplication": 2
},
{
"Type": "ROCK",
"Multiplication": 2
},
{
"Type": "STEEL",
"Multiplication": 0.5
},
{
"Type": "FAIRY",
"Multiplication": 2
}
],
"Moves": [
"bullet punch",
"metal burst",
"gear grind",
"magnet bomb"
],
"Icon": "🔩"
},
{
"Name": "FAIRY",
"Multipliers": [
{
"Type": "FIGHTING",
"Multiplication": 2
},
{
"Type": "FIRE",
"Multiplication": 0.5
},
{
"Type": "DARK",
"Multiplication": 2
},
{
"Type": "POISON",
"Multiplication": 0.5
},
{
"Type": "STEEL",
"Multiplication": 0.5
},
{
"Type": "DRAGON",
"Multiplication": 2
}
],
"Moves": [
"fairy wind",
"draining kiss",
"dazzling gleam",
"play rough"
],
"Icon": "💫"
}
]