From d96039d20c6c6334ad5bacc3dc8749d379fe4821 Mon Sep 17 00:00:00 2001
From: Toastie <toastie@toastiet0ast.com>
Date: Sat, 29 Mar 2025 20:43:32 +1300
Subject: [PATCH] These were meant to be pushed in
 0a1797700c15de85ae9e285991c70f0507444929 but git had other ideas

---
 ...ner.cs => 20250327001912_init.Designer.cs} | 202 ++++++++++++------
 ...8080459_init.cs => 20250327001912_init.cs} |  64 +++++-
 ...ner.cs => 20250327001909_init.Designer.cs} | 151 +++++++++----
 ...8080413_init.cs => 20250327001909_init.cs} |  64 +++++-
 src/EllieBot/data/commandlist.json            | 117 +++++++++-
 src/EllieBot/data/fish.yml                    |  40 ++++
 6 files changed, 517 insertions(+), 121 deletions(-)
 rename src/EllieBot/Migrations/PostgreSql/{20250328080459_init.Designer.cs => 20250327001912_init.Designer.cs} (97%)
 rename src/EllieBot/Migrations/PostgreSql/{20250328080459_init.cs => 20250327001912_init.cs} (97%)
 rename src/EllieBot/Migrations/Sqlite/{20250328080413_init.Designer.cs => 20250327001909_init.Designer.cs} (98%)
 rename src/EllieBot/Migrations/Sqlite/{20250328080413_init.cs => 20250327001909_init.cs} (97%)

diff --git a/src/EllieBot/Migrations/PostgreSql/20250328080459_init.Designer.cs b/src/EllieBot/Migrations/PostgreSql/20250327001912_init.Designer.cs
similarity index 97%
rename from src/EllieBot/Migrations/PostgreSql/20250328080459_init.Designer.cs
rename to src/EllieBot/Migrations/PostgreSql/20250327001912_init.Designer.cs
index fb946c4..58d9941 100644
--- a/src/EllieBot/Migrations/PostgreSql/20250328080459_init.Designer.cs
+++ b/src/EllieBot/Migrations/PostgreSql/20250327001912_init.Designer.cs
@@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
 namespace EllieBot.Migrations.PostgreSql
 {
     [DbContext(typeof(PostgreSqlContext))]
-    [Migration("20250328080459_init")]
+    [Migration("20250327001912_init")]
     partial class init
     {
         /// <inheritdoc />
@@ -867,57 +867,6 @@ namespace EllieBot.Migrations.PostgreSql
                     b.ToTable("discorduser", (string)null);
                 });
 
-            modelBuilder.Entity("EllieBot.Db.Models.EllieExpression", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("integer")
-                        .HasColumnName("id");
-
-                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
-
-                    b.Property<bool>("AllowTarget")
-                        .HasColumnType("boolean")
-                        .HasColumnName("allowtarget");
-
-                    b.Property<bool>("AutoDeleteTrigger")
-                        .HasColumnType("boolean")
-                        .HasColumnName("autodeletetrigger");
-
-                    b.Property<bool>("ContainsAnywhere")
-                        .HasColumnType("boolean")
-                        .HasColumnName("containsanywhere");
-
-                    b.Property<DateTime?>("DateAdded")
-                        .HasColumnType("timestamp without time zone")
-                        .HasColumnName("dateadded");
-
-                    b.Property<bool>("DmResponse")
-                        .HasColumnType("boolean")
-                        .HasColumnName("dmresponse");
-
-                    b.Property<decimal?>("GuildId")
-                        .HasColumnType("numeric(20,0)")
-                        .HasColumnName("guildid");
-
-                    b.Property<string>("Reactions")
-                        .HasColumnType("text")
-                        .HasColumnName("reactions");
-
-                    b.Property<string>("Response")
-                        .HasColumnType("text")
-                        .HasColumnName("response");
-
-                    b.Property<string>("Trigger")
-                        .HasColumnType("text")
-                        .HasColumnName("trigger");
-
-                    b.HasKey("Id")
-                        .HasName("pk_expressions");
-
-                    b.ToTable("expressions", (string)null);
-                });
-
             modelBuilder.Entity("EllieBot.Db.Models.FeedSub", b =>
                 {
                     b.Property<int>("Id")
@@ -1862,6 +1811,57 @@ namespace EllieBot.Migrations.PostgreSql
                     b.ToTable("ncpixel", (string)null);
                 });
 
+            modelBuilder.Entity("EllieBot.Db.Models.EllieExpression", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+
+                    b.Property<bool>("AllowTarget")
+                        .HasColumnType("boolean")
+                        .HasColumnName("allowtarget");
+
+                    b.Property<bool>("AutoDeleteTrigger")
+                        .HasColumnType("boolean")
+                        .HasColumnName("autodeletetrigger");
+
+                    b.Property<bool>("ContainsAnywhere")
+                        .HasColumnType("boolean")
+                        .HasColumnName("containsanywhere");
+
+                    b.Property<DateTime?>("DateAdded")
+                        .HasColumnType("timestamp without time zone")
+                        .HasColumnName("dateadded");
+
+                    b.Property<bool>("DmResponse")
+                        .HasColumnType("boolean")
+                        .HasColumnName("dmresponse");
+
+                    b.Property<decimal?>("GuildId")
+                        .HasColumnType("numeric(20,0)")
+                        .HasColumnName("guildid");
+
+                    b.Property<string>("Reactions")
+                        .HasColumnType("text")
+                        .HasColumnName("reactions");
+
+                    b.Property<string>("Response")
+                        .HasColumnType("text")
+                        .HasColumnName("response");
+
+                    b.Property<string>("Trigger")
+                        .HasColumnType("text")
+                        .HasColumnName("trigger");
+
+                    b.HasKey("Id")
+                        .HasName("pk_expressions");
+
+                    b.ToTable("expressions", (string)null);
+                });
+
             modelBuilder.Entity("EllieBot.Db.Models.Notify", b =>
                 {
                     b.Property<int>("Id")
@@ -2988,6 +2988,52 @@ namespace EllieBot.Migrations.PostgreSql
                     b.ToTable("unroletimer", (string)null);
                 });
 
+            modelBuilder.Entity("EllieBot.Db.Models.UserQuest", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+
+                    b.Property<DateTime>("DateAssigned")
+                        .HasColumnType("timestamp without time zone")
+                        .HasColumnName("dateassigned");
+
+                    b.Property<bool>("IsCompleted")
+                        .HasColumnType("boolean")
+                        .HasColumnName("iscompleted");
+
+                    b.Property<int>("Progress")
+                        .HasColumnType("integer")
+                        .HasColumnName("progress");
+
+                    b.Property<int>("QuestId")
+                        .HasColumnType("integer")
+                        .HasColumnName("questid");
+
+                    b.Property<int>("QuestNumber")
+                        .HasColumnType("integer")
+                        .HasColumnName("questnumber");
+
+                    b.Property<decimal>("UserId")
+                        .HasColumnType("numeric(20,0)")
+                        .HasColumnName("userid");
+
+                    b.HasKey("Id")
+                        .HasName("pk_userquest");
+
+                    b.HasIndex("UserId")
+                        .HasDatabaseName("ix_userquest_userid");
+
+                    b.HasIndex("UserId", "QuestNumber", "DateAssigned")
+                        .IsUnique()
+                        .HasDatabaseName("ix_userquest_userid_questnumber_dateassigned");
+
+                    b.ToTable("userquest", (string)null);
+                });
+
             modelBuilder.Entity("EllieBot.Db.Models.UserXpStats", b =>
                 {
                     b.Property<int>("Id")
@@ -3470,6 +3516,48 @@ namespace EllieBot.Migrations.PostgreSql
                     b.ToTable("xpshopowneditem", (string)null);
                 });
 
+            modelBuilder.Entity("EllieBot.Modules.Games.Fish.Db.UserFishItem", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("integer")
+                        .HasColumnName("id");
+
+                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+
+                    b.Property<DateTime?>("ExpiresAt")
+                        .HasColumnType("timestamp without time zone")
+                        .HasColumnName("expiresat");
+
+                    b.Property<bool>("IsEquipped")
+                        .HasColumnType("boolean")
+                        .HasColumnName("isequipped");
+
+                    b.Property<int>("ItemId")
+                        .HasColumnType("integer")
+                        .HasColumnName("itemid");
+
+                    b.Property<int>("ItemType")
+                        .HasColumnType("integer")
+                        .HasColumnName("itemtype");
+
+                    b.Property<decimal>("UserId")
+                        .HasColumnType("numeric(20,0)")
+                        .HasColumnName("userid");
+
+                    b.Property<int?>("UsesLeft")
+                        .HasColumnType("integer")
+                        .HasColumnName("usesleft");
+
+                    b.HasKey("Id")
+                        .HasName("pk_userfishitem");
+
+                    b.HasIndex("UserId")
+                        .HasDatabaseName("ix_userfishitem_userid");
+
+                    b.ToTable("userfishitem", (string)null);
+                });
+
             modelBuilder.Entity("EllieBot.Modules.Games.FishCatch", b =>
                 {
                     b.Property<int>("Id")
@@ -3513,14 +3601,6 @@ namespace EllieBot.Migrations.PostgreSql
 
                     NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
 
-                    b.Property<int?>("Bait")
-                        .HasColumnType("integer")
-                        .HasColumnName("bait");
-
-                    b.Property<int?>("Pole")
-                        .HasColumnType("integer")
-                        .HasColumnName("pole");
-
                     b.Property<int>("Skill")
                         .HasColumnType("integer")
                         .HasColumnName("skill");
@@ -4184,4 +4264,4 @@ namespace EllieBot.Migrations.PostgreSql
 #pragma warning restore 612, 618
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/EllieBot/Migrations/PostgreSql/20250328080459_init.cs b/src/EllieBot/Migrations/PostgreSql/20250327001912_init.cs
similarity index 97%
rename from src/EllieBot/Migrations/PostgreSql/20250328080459_init.cs
rename to src/EllieBot/Migrations/PostgreSql/20250327001912_init.cs
index 8ec83bd..cb668f2 100644
--- a/src/EllieBot/Migrations/PostgreSql/20250328080459_init.cs
+++ b/src/EllieBot/Migrations/PostgreSql/20250327001912_init.cs
@@ -1109,6 +1109,24 @@ namespace EllieBot.Migrations.PostgreSql
                     table.PrimaryKey("pk_userbetstats", x => x.id);
                 });
 
+            migrationBuilder.CreateTable(
+                name: "userfishitem",
+                columns: table => new
+                {
+                    id = table.Column<int>(type: "integer", nullable: false)
+                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+                    userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
+                    itemtype = table.Column<int>(type: "integer", nullable: false),
+                    itemid = table.Column<int>(type: "integer", nullable: false),
+                    isequipped = table.Column<bool>(type: "boolean", nullable: false),
+                    usesleft = table.Column<int>(type: "integer", nullable: true),
+                    expiresat = table.Column<DateTime>(type: "timestamp without time zone", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("pk_userfishitem", x => x.id);
+                });
+
             migrationBuilder.CreateTable(
                 name: "userfishstats",
                 columns: table => new
@@ -1116,15 +1134,31 @@ namespace EllieBot.Migrations.PostgreSql
                     id = table.Column<int>(type: "integer", nullable: false)
                         .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
                     userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
-                    skill = table.Column<int>(type: "integer", nullable: false),
-                    pole = table.Column<int>(type: "integer", nullable: true),
-                    bait = table.Column<int>(type: "integer", nullable: true)
+                    skill = table.Column<int>(type: "integer", nullable: false)
                 },
                 constraints: table =>
                 {
                     table.PrimaryKey("pk_userfishstats", x => x.id);
                 });
 
+            migrationBuilder.CreateTable(
+                name: "userquest",
+                columns: table => new
+                {
+                    id = table.Column<int>(type: "integer", nullable: false)
+                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+                    questnumber = table.Column<int>(type: "integer", nullable: false),
+                    userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
+                    questid = table.Column<int>(type: "integer", nullable: false),
+                    progress = table.Column<int>(type: "integer", nullable: false),
+                    iscompleted = table.Column<bool>(type: "boolean", nullable: false),
+                    dateassigned = table.Column<DateTime>(type: "timestamp without time zone", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("pk_userquest", x => x.id);
+                });
+
             migrationBuilder.CreateTable(
                 name: "userrole",
                 columns: table => new
@@ -2233,12 +2267,28 @@ namespace EllieBot.Migrations.PostgreSql
                 columns: new[] { "userid", "game" },
                 unique: true);
 
+            migrationBuilder.CreateIndex(
+                name: "ix_userfishitem_userid",
+                table: "userfishitem",
+                column: "userid");
+
             migrationBuilder.CreateIndex(
                 name: "ix_userfishstats_userid",
                 table: "userfishstats",
                 column: "userid",
                 unique: true);
 
+            migrationBuilder.CreateIndex(
+                name: "ix_userquest_userid",
+                table: "userquest",
+                column: "userid");
+
+            migrationBuilder.CreateIndex(
+                name: "ix_userquest_userid_questnumber_dateassigned",
+                table: "userquest",
+                columns: new[] { "userid", "questnumber", "dateassigned" },
+                unique: true);
+
             migrationBuilder.CreateIndex(
                 name: "ix_userrole_guildid",
                 table: "userrole",
@@ -2621,9 +2671,15 @@ namespace EllieBot.Migrations.PostgreSql
             migrationBuilder.DropTable(
                 name: "userbetstats");
 
+            migrationBuilder.DropTable(
+                name: "userfishitem");
+
             migrationBuilder.DropTable(
                 name: "userfishstats");
 
+            migrationBuilder.DropTable(
+                name: "userquest");
+
             migrationBuilder.DropTable(
                 name: "userrole");
 
@@ -2703,4 +2759,4 @@ namespace EllieBot.Migrations.PostgreSql
                 name: "discorduser");
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/EllieBot/Migrations/Sqlite/20250328080413_init.Designer.cs b/src/EllieBot/Migrations/Sqlite/20250327001909_init.Designer.cs
similarity index 98%
rename from src/EllieBot/Migrations/Sqlite/20250328080413_init.Designer.cs
rename to src/EllieBot/Migrations/Sqlite/20250327001909_init.Designer.cs
index 93bcd31..8bde593 100644
--- a/src/EllieBot/Migrations/Sqlite/20250328080413_init.Designer.cs
+++ b/src/EllieBot/Migrations/Sqlite/20250327001909_init.Designer.cs
@@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
 namespace EllieBot.Migrations.Sqlite
 {
     [DbContext(typeof(SqliteContext))]
-    [Migration("20250328080413_init")]
+    [Migration("20250327001909_init")]
     partial class init
     {
         /// <inheritdoc />
@@ -649,44 +649,6 @@ namespace EllieBot.Migrations.Sqlite
                     b.ToTable("DiscordUser");
                 });
 
-            modelBuilder.Entity("EllieBot.Db.Models.EllieExpression", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("INTEGER");
-
-                    b.Property<bool>("AllowTarget")
-                        .HasColumnType("INTEGER");
-
-                    b.Property<bool>("AutoDeleteTrigger")
-                        .HasColumnType("INTEGER");
-
-                    b.Property<bool>("ContainsAnywhere")
-                        .HasColumnType("INTEGER");
-
-                    b.Property<DateTime?>("DateAdded")
-                        .HasColumnType("TEXT");
-
-                    b.Property<bool>("DmResponse")
-                        .HasColumnType("INTEGER");
-
-                    b.Property<ulong?>("GuildId")
-                        .HasColumnType("INTEGER");
-
-                    b.Property<string>("Reactions")
-                        .HasColumnType("TEXT");
-
-                    b.Property<string>("Response")
-                        .HasColumnType("TEXT");
-
-                    b.Property<string>("Trigger")
-                        .HasColumnType("TEXT");
-
-                    b.HasKey("Id");
-
-                    b.ToTable("Expressions");
-                });
-
             modelBuilder.Entity("EllieBot.Db.Models.FeedSub", b =>
                 {
                     b.Property<int>("Id")
@@ -1391,6 +1353,44 @@ namespace EllieBot.Migrations.Sqlite
                     b.ToTable("NCPixel");
                 });
 
+            modelBuilder.Entity("EllieBot.Db.Models.EllieExpression", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("INTEGER");
+
+                    b.Property<bool>("AllowTarget")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<bool>("AutoDeleteTrigger")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<bool>("ContainsAnywhere")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<DateTime?>("DateAdded")
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("DmResponse")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<ulong?>("GuildId")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("Reactions")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Response")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Trigger")
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("Expressions");
+                });
+
             modelBuilder.Entity("EllieBot.Db.Models.Notify", b =>
                 {
                     b.Property<int>("Id")
@@ -2227,6 +2227,40 @@ namespace EllieBot.Migrations.Sqlite
                     b.ToTable("UnroleTimer");
                 });
 
+            modelBuilder.Entity("EllieBot.Db.Models.UserQuest", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("INTEGER");
+
+                    b.Property<DateTime>("DateAssigned")
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsCompleted")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<int>("Progress")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<int>("QuestId")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<int>("QuestNumber")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<ulong>("UserId")
+                        .HasColumnType("INTEGER");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.HasIndex("UserId", "QuestNumber", "DateAssigned")
+                        .IsUnique();
+
+                    b.ToTable("UserQuest");
+                });
+
             modelBuilder.Entity("EllieBot.Db.Models.UserXpStats", b =>
                 {
                     b.Property<int>("Id")
@@ -2582,6 +2616,37 @@ namespace EllieBot.Migrations.Sqlite
                     b.ToTable("XpShopOwnedItem");
                 });
 
+            modelBuilder.Entity("EllieBot.Modules.Games.Fish.Db.UserFishItem", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("INTEGER");
+
+                    b.Property<DateTime?>("ExpiresAt")
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsEquipped")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<int>("ItemId")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<int>("ItemType")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<ulong>("UserId")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<int?>("UsesLeft")
+                        .HasColumnType("INTEGER");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("UserFishItem");
+                });
+
             modelBuilder.Entity("EllieBot.Modules.Games.FishCatch", b =>
                 {
                     b.Property<int>("Id")
@@ -2613,12 +2678,6 @@ namespace EllieBot.Migrations.Sqlite
                         .ValueGeneratedOnAdd()
                         .HasColumnType("INTEGER");
 
-                    b.Property<int?>("Bait")
-                        .HasColumnType("INTEGER");
-
-                    b.Property<int?>("Pole")
-                        .HasColumnType("INTEGER");
-
                     b.Property<int>("Skill")
                         .HasColumnType("INTEGER");
 
@@ -3181,4 +3240,4 @@ namespace EllieBot.Migrations.Sqlite
 #pragma warning restore 612, 618
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/EllieBot/Migrations/Sqlite/20250328080413_init.cs b/src/EllieBot/Migrations/Sqlite/20250327001909_init.cs
similarity index 97%
rename from src/EllieBot/Migrations/Sqlite/20250328080413_init.cs
rename to src/EllieBot/Migrations/Sqlite/20250327001909_init.cs
index a3e5477..a84a645 100644
--- a/src/EllieBot/Migrations/Sqlite/20250328080413_init.cs
+++ b/src/EllieBot/Migrations/Sqlite/20250327001909_init.cs
@@ -1111,6 +1111,24 @@ namespace EllieBot.Migrations.Sqlite
                     table.PrimaryKey("PK_UserBetStats", x => x.Id);
                 });
 
+            migrationBuilder.CreateTable(
+                name: "UserFishItem",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "INTEGER", nullable: false)
+                        .Annotation("Sqlite:Autoincrement", true),
+                    UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
+                    ItemType = table.Column<int>(type: "INTEGER", nullable: false),
+                    ItemId = table.Column<int>(type: "INTEGER", nullable: false),
+                    IsEquipped = table.Column<bool>(type: "INTEGER", nullable: false),
+                    UsesLeft = table.Column<int>(type: "INTEGER", nullable: true),
+                    ExpiresAt = table.Column<DateTime>(type: "TEXT", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_UserFishItem", x => x.Id);
+                });
+
             migrationBuilder.CreateTable(
                 name: "UserFishStats",
                 columns: table => new
@@ -1118,15 +1136,31 @@ namespace EllieBot.Migrations.Sqlite
                     Id = table.Column<int>(type: "INTEGER", nullable: false)
                         .Annotation("Sqlite:Autoincrement", true),
                     UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
-                    Skill = table.Column<int>(type: "INTEGER", nullable: false),
-                    Pole = table.Column<int>(type: "INTEGER", nullable: true),
-                    Bait = table.Column<int>(type: "INTEGER", nullable: true)
+                    Skill = table.Column<int>(type: "INTEGER", nullable: false)
                 },
                 constraints: table =>
                 {
                     table.PrimaryKey("PK_UserFishStats", x => x.Id);
                 });
 
+            migrationBuilder.CreateTable(
+                name: "UserQuest",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "INTEGER", nullable: false)
+                        .Annotation("Sqlite:Autoincrement", true),
+                    QuestNumber = table.Column<int>(type: "INTEGER", nullable: false),
+                    UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
+                    QuestId = table.Column<int>(type: "INTEGER", nullable: false),
+                    Progress = table.Column<int>(type: "INTEGER", nullable: false),
+                    IsCompleted = table.Column<bool>(type: "INTEGER", nullable: false),
+                    DateAssigned = table.Column<DateTime>(type: "TEXT", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_UserQuest", x => x.Id);
+                });
+
             migrationBuilder.CreateTable(
                 name: "UserRole",
                 columns: table => new
@@ -2235,12 +2269,28 @@ namespace EllieBot.Migrations.Sqlite
                 columns: new[] { "UserId", "Game" },
                 unique: true);
 
+            migrationBuilder.CreateIndex(
+                name: "IX_UserFishItem_UserId",
+                table: "UserFishItem",
+                column: "UserId");
+
             migrationBuilder.CreateIndex(
                 name: "IX_UserFishStats_UserId",
                 table: "UserFishStats",
                 column: "UserId",
                 unique: true);
 
+            migrationBuilder.CreateIndex(
+                name: "IX_UserQuest_UserId",
+                table: "UserQuest",
+                column: "UserId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_UserQuest_UserId_QuestNumber_DateAssigned",
+                table: "UserQuest",
+                columns: new[] { "UserId", "QuestNumber", "DateAssigned" },
+                unique: true);
+
             migrationBuilder.CreateIndex(
                 name: "IX_UserRole_GuildId",
                 table: "UserRole",
@@ -2623,9 +2673,15 @@ namespace EllieBot.Migrations.Sqlite
             migrationBuilder.DropTable(
                 name: "UserBetStats");
 
+            migrationBuilder.DropTable(
+                name: "UserFishItem");
+
             migrationBuilder.DropTable(
                 name: "UserFishStats");
 
+            migrationBuilder.DropTable(
+                name: "UserQuest");
+
             migrationBuilder.DropTable(
                 name: "UserRole");
 
@@ -2705,4 +2761,4 @@ namespace EllieBot.Migrations.Sqlite
                 name: "DiscordUser");
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/EllieBot/data/commandlist.json b/src/EllieBot/data/commandlist.json
index 2e67cf1..4a7a257 100644
--- a/src/EllieBot/data/commandlist.json
+++ b/src/EllieBot/data/commandlist.json
@@ -4114,7 +4114,7 @@
       "Usage": [
         ".fish"
       ],
-      "Submodule": "FishCommands",
+      "Submodule": "FishingCommands",
       "Module": "Games",
       "Options": null,
       "Requirements": []
@@ -4129,7 +4129,7 @@
       "Usage": [
         ".fishspot"
       ],
-      "Submodule": "FishCommands",
+      "Submodule": "FishingCommands",
       "Module": "Games",
       "Options": null,
       "Requirements": []
@@ -4145,7 +4145,84 @@
       "Usage": [
         ".fishlist"
       ],
-      "Submodule": "FishCommands",
+      "Submodule": "FishingCommands",
+      "Module": "Games",
+      "Options": null,
+      "Requirements": []
+    },
+    {
+      "Aliases": [
+        ".fishshop",
+        ".fishop"
+      ],
+      "Description": "Opens the fish shop.\nLists all fish items available for sale",
+      "Usage": [
+        ".fishshop"
+      ],
+      "Submodule": "FishItemCommands",
+      "Module": "Games",
+      "Options": null,
+      "Requirements": []
+    },
+    {
+      "Aliases": [
+        ".fishbuy",
+        ".fibuy"
+      ],
+      "Description": "Purchase a fishing item with the specified id.\nAfter purchase the item will appear in your inventory where you can use/equip it.",
+      "Usage": [
+        ".fishbuy 1"
+      ],
+      "Submodule": "FishItemCommands",
+      "Module": "Games",
+      "Options": null,
+      "Requirements": []
+    },
+    {
+      "Aliases": [
+        ".fishuse",
+        ".fiuse",
+        ".fiequip",
+        ".fieq",
+        ".fiquip"
+      ],
+      "Description": "Use a fishing item in your inventory.\nYou can unequip it later, unless its a potion.",
+      "Usage": [
+        ".fishuse 1"
+      ],
+      "Submodule": "FishItemCommands",
+      "Module": "Games",
+      "Options": null,
+      "Requirements": []
+    },
+    {
+      "Aliases": [
+        ".fishunequip",
+        ".fiuneq",
+        ".fiunequip",
+        ".fiunuse",
+        ".fishunuse"
+      ],
+      "Description": "Unequips an item by specifying its index in your inventory.\nYou can use it again later.\nYou can't unequip potions.",
+      "Usage": [
+        ".fishunequip 1"
+      ],
+      "Submodule": "FishItemCommands",
+      "Module": "Games",
+      "Options": null,
+      "Requirements": []
+    },
+    {
+      "Aliases": [
+        ".fishinv",
+        ".finv",
+        ".fiinv"
+      ],
+      "Description": "Opens your fish inventory.\nYour inventory contains all items you've purchased but not spent.",
+      "Usage": [
+        ".fishinv"
+      ],
+      "Submodule": "FishItemCommands",
       "Module": "Games",
       "Options": null,
       "Requirements": []
@@ -5238,6 +5315,19 @@
       "Module": "Owner",
       "Options": null,
       "Requirements": []
+    },
+    {
+      "Aliases": [
+        ".massping"
+      ],
+      "Description": "Mass pings all users in the server.\nRun again to cancel.",
+      "Usage": [
+        ".massping"
+      ],
+      "Submodule": "Owner",
+      "Module": "Owner",
+      "Options": null,
+      "Requirements": []
     }
   ],
   "Permissions": [
@@ -5825,6 +5915,23 @@
       ]
     }
   ],
+  "QuestCommands": [
+    {
+      "Aliases": [
+        ".questlog",
+        ".qlog",
+        ".myquests"
+      ],
+      "Description": "Shows your active quests and progress.",
+      "Usage": [
+        ".questlog"
+      ],
+      "Submodule": "QuestCommands",
+      "Module": "QuestCommands",
+      "Options": null,
+      "Requirements": []
+    }
+  ],
   "Searches": [
     {
       "Aliases": [
@@ -7534,7 +7641,6 @@
         ".quoteprint",
         ".qp",
         ".qup",
-        "...",
         ".qprint"
       ],
       "Description": "Prints a random quote with a specified name.",
@@ -7599,8 +7705,7 @@
         ".quoteadd",
         ".qa",
         ".qadd",
-        ".quadd",
-        ".."
+        ".quadd"
       ],
       "Description": "Adds a new quote with the specified name and message.",
       "Usage": [
diff --git a/src/EllieBot/data/fish.yml b/src/EllieBot/data/fish.yml
index e07fee1..e04be6a 100644
--- a/src/EllieBot/data/fish.yml
+++ b/src/EllieBot/data/fish.yml
@@ -42,3 +42,43 @@ trash:
     condition: 
     image: https://cdn.nadeko.bot/fish/plasticbag.png
     emoji: <:plasticbag:1328520895454515211>
+items:
+  - id: 1
+    itemType: Pole
+    name: "Wooden Rod"
+    description: "Better than catching it with bare hands."
+    price: 1000
+    fishMultiplier: 1.2
+
+  - id: 11
+    itemType: Pole
+    name: Magnet on a Stick
+    description: "Attracts all trash, not just metal."
+    price: 3000
+    fishMultiplier: 0.9
+    trashMultiplier: 2
+
+  - id: 21
+    itemType: Bait
+    name: "Corn"
+    description: "Just some cooked corn."
+    price: 100
+    uses: 100
+    rareMultiplier: 1.1
+
+  - id: 31
+    itemType: Potion
+    name: "A Cup of Tea"
+    description: "Helps you focus."
+    price: 12000
+    durationMinutes: 30
+    maxStarMultiplier: 1.1
+    fishingSpeedMultiplier: 1.01
+
+  - id: 41
+    itemType: Boat
+    name: "Canoe"
+    description: "Lets you fish a little faster."
+    price: 3000
+    fishingSpeedMultiplier: 1.201
+    maxStarMultiplier: 1.1
\ No newline at end of file