浏览代码

Merge branch 'Rune_Improvements'

Iñigo Valentin 5 年之前
父节点
当前提交
6b108852a5
共有 48 个文件被更改,包括 1674 次插入1063 次删除
  1. 211 183
      application/API/v3/profile/PUT.php
  2. 97 0
      application/Constant.php
  3. 22 0
      application/Controller.php
  4. 43 0
      application/action/change_game_mode.php
  5. 0 1
      application/action/login.php
  6. 32 26
      application/action/optimize_get_rune_list.php
  7. 29 172
      application/entity/Artifact.php
  8. 108 0
      application/entity/Artifact_Effect.php
  9. 82 0
      application/entity/Artifact_Stat.php
  10. 115 21
      application/entity/Run.php
  11. 55 217
      application/entity/Rune.php
  12. 131 0
      application/entity/Rune_Stat.php
  13. 26 20
      application/entity/Unit.php
  14. 41 40
      application/helper/HTML_Helper.php
  15. 31 72
      application/page/Artifacts_Page.php
  16. 1 1
      application/page/Monster_Page.php
  17. 2 2
      application/page/Monsters_Page.php
  18. 133 119
      application/page/Report_Rune_Enchantment_Page.php
  19. 4 2
      application/page/Report_Skillup_Page.php
  20. 38 32
      application/page/Runes_Page.php
  21. 二进制
      application/sw.sqlite
  22. 8 1
      application/view/artifacts.php
  23. 7 0
      application/view/catalog.php
  24. 7 0
      application/view/enchantments.php
  25. 7 0
      application/view/error.php
  26. 7 0
      application/view/fusion.php
  27. 7 0
      application/view/guild.php
  28. 7 0
      application/view/help.php
  29. 7 0
      application/view/home.php
  30. 127 53
      application/view/inc/header.php
  31. 7 1
      application/view/monster.php
  32. 7 0
      application/view/monster_info.php
  33. 7 0
      application/view/monsters.php
  34. 7 0
      application/view/optimizer.php
  35. 12 1
      application/view/optimizer_unit.php
  36. 7 0
      application/view/profile.php
  37. 7 0
      application/view/report.php
  38. 7 0
      application/view/report_rune_enchantment.php
  39. 7 0
      application/view/report_skillup.php
  40. 9 2
      application/view/runes.php
  41. 7 0
      application/view/runs.php
  42. 7 0
      application/view/stats.php
  43. 7 0
      application/view/teams.php
  44. 7 0
      install_data/install_base.sql
  45. 40 41
      install_data/install_data.sql
  46. 2 2
      public/css/monsters.css
  47. 33 0
      public/css/ui-rta.css
  48. 109 54
      public/css/ui.css

+ 211 - 183
application/API/v3/profile/PUT.php

@@ -173,7 +173,6 @@
           INSERT INTO artifact (
             uid,
             id,
-            assigned_to,
             type,
             attribute,
             archetype,
@@ -183,29 +182,10 @@
             value,
             efficiency,
             max_efficiency,
-            main_stat,
-            main_stat_value,
-            effect_1,
-            effect_1_value,
-            effect_1_enchant,
-            effect_1_grind,
-            effect_2,
-            effect_2_value,
-            effect_2_enchant,
-            effect_2_grind,
-            effect_3,
-            effect_3_value,
-            effect_3_enchant,
-            effect_3_grind,
-            effect_4,
-            effect_4_value,
-            effect_4_enchant,
-            effect_4_grind,
             locked
           ) VALUES (
             :uid,
             :id,
-            :assigned_to,
             :type,
             :attribute,
             :archetype,
@@ -215,35 +195,11 @@
             :value,
             :efficiency,
             :max_efficiency,
-            :main_stat,
-            :main_stat_value,
-            :effect_1,
-            :effect_1_value,
-            :effect_1_enchant,
-            :effect_1_grind,
-            :effect_2,
-            :effect_2_value,
-            :effect_2_enchant,
-            :effect_2_grind,
-            :effect_3,
-            :effect_3_value,
-            :effect_3_enchant,
-            :effect_3_grind,
-            :effect_4,
-            :effect_4_value,
-            :effect_4_enchant,
-            :effect_4_grind,
             :locked
           );
         ");
         $statement->bindValue(":uid", $uid, SQLITE3_INTEGER);
         $statement->bindValue(":id", $artifact->{"rid"}, SQLITE3_INTEGER);
-        if (intval($artifact->{"occupied_id"}) == 0){
-            $statement->bindValue(":assigned_to", null, SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":assigned_to", $artifact->{"occupied_id"}, SQLITE3_INTEGER);
-        }
         if (intval($artifact->{"attribute"}) == 0){
             $statement->bindValue(":attribute", null, SQLITE3_INTEGER);
         }
@@ -271,57 +227,110 @@
         $max_efficiency = 0; // Not standard formula yet
         $statement->bindValue(":efficiency", $efficiency, SQLITE3_FLOAT);
         $statement->bindValue(":max_efficiency", $max_efficiency, SQLITE3_FLOAT);
-        $statement->bindValue(":main_stat", $artifact->{"pri_effect"}[0], SQLITE3_INTEGER);
-        $statement->bindValue(":main_stat_value", $artifact->{"pri_effect"}[1], SQLITE3_INTEGER);
+        $statement->execute();
+        
+        // Main stat
+        $statement = $db->prepare("
+          INSERT INTO artifact_stat (
+            artifact,
+            stat,
+            value
+          ) VALUES (
+            :artifact,
+            :stat,
+            :value
+          );
+        ");
+        $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER);
+        $statement->bindValue(":stat", $artifact->{"pri_effect"}[0], SQLITE3_INTEGER);
+        $statement->bindValue(":value", $artifact->{"pri_effect"}[1], SQLITE3_INTEGER);
+        $statement->execute();
+        
+        // Base effect insert query
+        $effect_query = "
+          INSERT INTO artifact_effect (
+            artifact,
+            slot,
+            effect,
+            value,
+            enchant,
+            grind,
+            rolls
+          ) VALUES (
+            :artifact,
+            :slot,
+            :effect,
+            :value,
+            :enchant,
+            :grind,
+            :rolls
+          );
+        ";
+        
+        // Effect 1
         if (sizeof($artifact->{"sec_effects"}) > 0){
-            $statement->bindValue(":effect_1", $artifact->{"sec_effects"}[0][0], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_1_value", $artifact->{"sec_effects"}[0][1], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_1_enchant", $artifact->{"sec_effects"}[0][2], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_1_grind", $artifact->{"sec_effects"}[0][3], SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":effect_1", null, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_1_value", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_1_enchant", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_1_grind", 0, SQLITE3_INTEGER);
+            $statement = $db->prepare($effect_query);
+            $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", ARTIFACT_EFFECT_SLOT_ID::EFFECT_1, SQLITE3_INTEGER);
+            $statement->bindValue(":effect", $artifact->{"sec_effects"}[0][0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $artifact->{"sec_effects"}[0][1], SQLITE3_INTEGER);
+            $statement->bindValue(":grind", $artifact->{"sec_effects"}[0][2], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", $artifact->{"sec_effects"}[0][3], SQLITE3_INTEGER);
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
+        
+        // Effect 2
         if (sizeof($artifact->{"sec_effects"}) > 1){
-            $statement->bindValue(":effect_2", $artifact->{"sec_effects"}[1][0], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_2_value", $artifact->{"sec_effects"}[1][1], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_2_enchant", $artifact->{"sec_effects"}[1][2], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_2_grind", $artifact->{"sec_effects"}[1][3], SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":effect_2", null, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_2_value", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_2_enchant", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_2_grind", 0, SQLITE3_INTEGER);
+            $statement = $db->prepare($effect_query);
+            $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", ARTIFACT_EFFECT_SLOT_ID::EFFECT_2, SQLITE3_INTEGER);
+            $statement->bindValue(":effect", $artifact->{"sec_effects"}[1][0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $artifact->{"sec_effects"}[1][1], SQLITE3_INTEGER);
+            $statement->bindValue(":grind", $artifact->{"sec_effects"}[1][2], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", $artifact->{"sec_effects"}[1][3], SQLITE3_INTEGER);
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
+
+        // Effect 3
         if (sizeof($artifact->{"sec_effects"}) > 2){
-            $statement->bindValue(":effect_3", $artifact->{"sec_effects"}[2][0], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_3_value", $artifact->{"sec_effects"}[2][1], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_3_enchant", $artifact->{"sec_effects"}[2][2], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_3_grind", $artifact->{"sec_effects"}[2][3], SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":effect_3", null, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_3_value", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_3_enchant", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_3_grind", 0, SQLITE3_INTEGER);
+            $statement = $db->prepare($effect_query);
+            $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", ARTIFACT_EFFECT_SLOT_ID::EFFECT_3, SQLITE3_INTEGER);
+            $statement->bindValue(":effect", $artifact->{"sec_effects"}[2][0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $artifact->{"sec_effects"}[2][1], SQLITE3_INTEGER);
+            $statement->bindValue(":grind", $artifact->{"sec_effects"}[2][2], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", $artifact->{"sec_effects"}[2][3], SQLITE3_INTEGER);
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
+
+        // Effect 4
         if (sizeof($artifact->{"sec_effects"}) > 3){
-            $statement->bindValue(":effect_4", $artifact->{"sec_effects"}[3][0], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_4_value", $artifact->{"sec_effects"}[3][1], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_4_enchant", $artifact->{"sec_effects"}[3][2], SQLITE3_INTEGER);
-            $statement->bindValue(":effect_4_grind", $artifact->{"sec_effects"}[3][3], SQLITE3_INTEGER);
+            $statement = $db->prepare($effect_query);
+            $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", ARTIFACT_EFFECT_SLOT_ID::EFFECT_4, SQLITE3_INTEGER);
+            $statement->bindValue(":effect", $artifact->{"sec_effects"}[3][0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $artifact->{"sec_effects"}[3][1], SQLITE3_INTEGER);
+            $statement->bindValue(":grind", $artifact->{"sec_effects"}[3][2], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", $artifact->{"sec_effects"}[3][3], SQLITE3_INTEGER);
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
-        else{
-            $statement->bindValue(":effect_4", null, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_4_value", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_4_enchant", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":effect_4_grind", 0, SQLITE3_INTEGER);
+
+        // Assigned?
+        if (intval($artifact->{"occupied_id"}) != 0){
+            $statement = $db->prepare("
+              INSERT INTO unit_artifact (unit, artifact, rta)
+              VALUES (:unit, :artifact, :rta);
+            ");
+            $statement->bindValue(":unit", $artifact->{"occupied_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":artifact", $artifact->{"rid"}, SQLITE3_INTEGER);
+            $statement->bindValue(":rta", GAME_MODE_ID::NORMAL, SQLITE3_INTEGER);
+            $statement->execute();
         }
-        $statement->execute();
+        
     }
 
     /**
@@ -336,7 +345,6 @@
           INSERT INTO rune (
             uid,
             id,
-            assigned_to,
             type,
             slot,
             stars,
@@ -347,31 +355,10 @@
             value,
             efficiency,
             max_efficiency,
-            main_stat,
-            main_stat_value,
-            innate_stat,
-            innate_stat_value,
-            substat_1,
-            substat_1_value,
-            substat_1_enchant,
-            substat_1_grind,
-            substat_2,
-            substat_2_value,
-            substat_2_enchant,
-            substat_2_grind,
-            substat_3,
-            substat_3_value,
-            substat_3_enchant,
-            substat_3_grind,
-            substat_4,
-            substat_4_value,
-            substat_4_enchant,
-            substat_4_grind,
             locked
           ) VALUES (
             :uid,
             :id,
-            :assigned_to,
             :type,
             :slot,
             :stars,
@@ -382,37 +369,11 @@
             :value,
             :efficiency,
             :max_efficiency,
-            :main_stat,
-            :main_stat_value,
-            :innate_stat,
-            :innate_stat_value,
-            :substat_1,
-            :substat_1_value,
-            :substat_1_enchant,
-            :substat_1_grind,
-            :substat_2,
-            :substat_2_value,
-            :substat_2_enchant,
-            :substat_2_grind,
-            :substat_3,
-            :substat_3_value,
-            :substat_3_enchant,
-            :substat_3_grind,
-            :substat_4,
-            :substat_4_value,
-            :substat_4_enchant,
-            :substat_4_grind,
             :locked
           );
         ");
         $statement->bindValue(":uid", $uid, SQLITE3_INTEGER);
         $statement->bindValue(":id", $rune->{"rune_id"}, SQLITE3_INTEGER);
-        if (intval($rune->{"occupied_id"}) == 0){
-            $statement->bindValue(":assigned_to", null, SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":assigned_to", $rune->{"occupied_id"}, SQLITE3_INTEGER);
-        }
         $statement->bindValue(":type", $rune->{"set_id"}, SQLITE3_INTEGER);
         $statement->bindValue(":slot", $rune->{"slot_no"}, SQLITE3_INTEGER);
         $statement->bindValue(":value", $rune->{"sell_value"}, SQLITE3_INTEGER);
@@ -456,65 +417,97 @@
         $max_efficiency = calculate_maximum_efficiency($rune);
         $statement->bindValue(":efficiency", $efficiency, SQLITE3_FLOAT);
         $statement->bindValue(":max_efficiency", $max_efficiency, SQLITE3_FLOAT);
-        $statement->bindValue(":main_stat", $rune->{"pri_eff"}[0], SQLITE3_INTEGER);
-        $statement->bindValue(":main_stat_value", $rune->{"pri_eff"}[1], SQLITE3_INTEGER);
+        $statement->execute();
+
+        $stat_statement = "
+          INSERT INTO rune_stat (rune, slot, stat, value, enchant, grind, rolls)
+          VALUES (:rune, :slot, :stat, :value, :enchant, :grind, :rolls);
+        ";
+
+        // Main stat
+        $statement = $db->prepare($stat_statement);
+        $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER);
+        $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::MAIN, SQLITE3_INTEGER);
+        $statement->bindValue(":stat", $rune->{"pri_eff"}[0], SQLITE3_INTEGER);
+        $statement->bindValue(":value", $rune->{"pri_eff"}[1], SQLITE3_INTEGER);
+        $statement->bindValue(":enchant", 0, SQLITE3_INTEGER);
+        $statement->bindValue(":grind", 0, SQLITE3_INTEGER);
+        $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+        $statement->execute();
+
+        // Innate stat
         if ($rune->{"prefix_eff"}[0] > 0){
-            $statement->bindValue(":innate_stat", $rune->{"prefix_eff"}[0], SQLITE3_INTEGER);
-            $statement->bindValue(":innate_stat_value", $rune->{"prefix_eff"}[1], SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":innate_stat", null, SQLITE3_INTEGER);
-            $statement->bindValue(":innate_stat_value", 0, SQLITE3_INTEGER);
+            // Main stat
+            $statement = $db->prepare($stat_statement);
+            $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::INNATE, SQLITE3_INTEGER);
+            $statement->bindValue(":stat", $rune->{"prefix_eff"}[0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $rune->{"prefix_eff"}[1], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", 0, SQLITE3_INTEGER);
+            $statement->bindValue(":grind", 0, SQLITE3_INTEGER);
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
         if (sizeof($rune->{"sec_eff"}) > 0){
-            $statement->bindValue(":substat_1", $rune->{"sec_eff"}[0][0], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_1_value", $rune->{"sec_eff"}[0][1], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_1_enchant", $rune->{"sec_eff"}[0][2], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_1_grind", $rune->{"sec_eff"}[0][3], SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":substat_1", null, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_1_value", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_1_enchant", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_1_grind", 0, SQLITE3_INTEGER);
+            $statement = $db->prepare($stat_statement);
+            $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::SUBSTAT_1, SQLITE3_INTEGER);
+            $statement->bindValue(":stat", $rune->{"sec_eff"}[0][0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $rune->{"sec_eff"}[0][1], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", $rune->{"sec_eff"}[0][2], SQLITE3_INTEGER);
+            $statement->bindValue(":grind", $rune->{"sec_eff"}[0][3], SQLITE3_INTEGER);
+            // TODO: Calculate rolls
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
         if (sizeof($rune->{"sec_eff"}) > 1){
-            $statement->bindValue(":substat_2", $rune->{"sec_eff"}[1][0], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_2_value", $rune->{"sec_eff"}[1][1], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_2_enchant", $rune->{"sec_eff"}[1][2], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_2_grind", $rune->{"sec_eff"}[1][3], SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":substat_2", null, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_2_value", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_2_enchant", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_2_grind", 0, SQLITE3_INTEGER);
+            $statement = $db->prepare($stat_statement);
+            $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::SUBSTAT_2, SQLITE3_INTEGER);
+            $statement->bindValue(":stat", $rune->{"sec_eff"}[1][0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $rune->{"sec_eff"}[1][1], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", $rune->{"sec_eff"}[1][2], SQLITE3_INTEGER);
+            $statement->bindValue(":grind", $rune->{"sec_eff"}[1][3], SQLITE3_INTEGER);
+            // TODO: Calculate rolls
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
         if (sizeof($rune->{"sec_eff"}) > 2){
-            $statement->bindValue(":substat_3", $rune->{"sec_eff"}[2][0], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_3_value", $rune->{"sec_eff"}[2][1], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_3_enchant", $rune->{"sec_eff"}[2][2], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_3_grind", $rune->{"sec_eff"}[2][3], SQLITE3_INTEGER);
-        }
-        else{
-            $statement->bindValue(":substat_3", null, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_3_value", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_3_enchant", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_3_grind", 0, SQLITE3_INTEGER);
+            $statement = $db->prepare($stat_statement);
+            $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::SUBSTAT_3, SQLITE3_INTEGER);
+            $statement->bindValue(":stat", $rune->{"sec_eff"}[2][0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $rune->{"sec_eff"}[2][1], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", $rune->{"sec_eff"}[2][2], SQLITE3_INTEGER);
+            $statement->bindValue(":grind", $rune->{"sec_eff"}[2][3], SQLITE3_INTEGER);
+            // TODO: Calculate rolls
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
         if (sizeof($rune->{"sec_eff"}) > 3){
-            $statement->bindValue(":substat_4", $rune->{"sec_eff"}[3][0], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_4_value", $rune->{"sec_eff"}[3][1], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_4_enchant", $rune->{"sec_eff"}[3][2], SQLITE3_INTEGER);
-            $statement->bindValue(":substat_4_grind", $rune->{"sec_eff"}[3][3], SQLITE3_INTEGER);
+            $statement = $db->prepare($stat_statement);
+            $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":slot", RUNE_STAT_SLOT_ID::SUBSTAT_4, SQLITE3_INTEGER);
+            $statement->bindValue(":stat", $rune->{"sec_eff"}[3][0], SQLITE3_INTEGER);
+            $statement->bindValue(":value", $rune->{"sec_eff"}[3][1], SQLITE3_INTEGER);
+            $statement->bindValue(":enchant", $rune->{"sec_eff"}[3][2], SQLITE3_INTEGER);
+            $statement->bindValue(":grind", $rune->{"sec_eff"}[3][3], SQLITE3_INTEGER);
+            // TODO: Calculate rolls
+            $statement->bindValue(":rolls", 0, SQLITE3_INTEGER);
+            $statement->execute();
         }
-        else{
-            $statement->bindValue(":substat_4", null, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_4_value", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_4_enchant", 0, SQLITE3_INTEGER);
-            $statement->bindValue(":substat_4_grind", 0, SQLITE3_INTEGER);
+
+        // Assigned?
+        if (intval($rune->{"occupied_id"}) != 0){
+            $statement = $db->prepare("
+              INSERT INTO unit_rune (unit, rune, rta)
+              VALUES (:unit, :rune, :rta);
+            ");
+            $statement->bindValue(":unit", $rune->{"occupied_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":rune", $rune->{"rune_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":rta", GAME_MODE_ID::NORMAL, SQLITE3_INTEGER);
+            $statement->execute();
         }
-        $statement->execute();
     }
 
     /**
@@ -543,6 +536,21 @@
         $statement = $db->prepare("DELETE FROM unit_skill WHERE unit IN (SELECT id FROM unit WHERE uid = :uid);");
         $statement->bindValue(":uid", $uid, SQLITE3_INTEGER);
         $statement->execute();
+        $statement = $db->prepare("DELETE FROM unit_rune WHERE unit IN (SELECT id FROM unit WHERE uid = :uid);");
+        $statement->bindValue(":uid", $uid, SQLITE3_INTEGER);
+        $statement->execute();
+        $statement = $db->prepare("DELETE FROM rune_stat WHERE rune IN (SELECT id FROM rune WHERE uid = :uid);");
+        $statement->bindValue(":uid", $uid, SQLITE3_INTEGER);
+        $statement->execute();
+        $statement = $db->prepare("DELETE FROM unit_artifact WHERE unit IN (SELECT id FROM unit WHERE uid = :uid);");
+        $statement->bindValue(":uid", $uid, SQLITE3_INTEGER);
+        $statement->execute();
+        $statement = $db->prepare("DELETE FROM artifact_stat WHERE artifact IN (SELECT id FROM artifact WHERE uid = :uid);");
+        $statement->bindValue(":uid", $uid, SQLITE3_INTEGER);
+        $statement->execute();
+        $statement = $db->prepare("DELETE FROM artifact_effect WHERE artifact IN (SELECT id FROM artifact WHERE uid = :uid);");
+        $statement->bindValue(":uid", $uid, SQLITE3_INTEGER);
+        $statement->execute();
         $tables_to_clear = [
             "scenario",
             "defense",
@@ -876,7 +884,7 @@
             }
         }
 
-        // Parse invetory
+        // Parse inventory
         foreach ($json->{"inventory_info"} as $item){
             $statement = $db->prepare("
               INSERT INTO inventory (
@@ -968,6 +976,16 @@
                 parse_rune($uid, $rune, $rune_lock_list);
             }
         }
+        foreach ($json->{"world_arena_rune_equip_list"} as $rta_rune){
+            $statement = $db->prepare("
+              INSERT INTO unit_rune (unit, rune, rta)
+              VALUES (:unit, :rune, :rta);
+            ");
+            $statement->bindValue(":unit", $rta_rune->{"occupied_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":rune", $rta_rune->{"rune_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":rta", GAME_MODE_ID::RTA, SQLITE3_INTEGER);
+            $statement->execute();
+        }
 
         // Parse artifacts
         foreach ($json->{"artifacts"} as $artifact){
@@ -978,6 +996,16 @@
                 parse_artifact($uid, $artifact);
             }
         }
+        foreach ($json->{"world_arena_artifact_equip_list"} as $rta_artifact){
+            $statement = $db->prepare("
+              INSERT INTO unit_artifact (unit, artifact, rta)
+              VALUES (:unit, :artifact, :rta);
+            ");
+            $statement->bindValue(":unit", $rta_artifact->{"occupied_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":artifact", $rta_artifact->{"artifact_id"}, SQLITE3_INTEGER);
+            $statement->bindValue(":rta", GAME_MODE_ID::RTA, SQLITE3_INTEGER);
+            $statement->execute();
+        }
 
         // Parse enchantments
         foreach ($json->{"rune_craft_item_list"} as $item){

+ 97 - 0
application/Constant.php

@@ -1433,6 +1433,103 @@
         const TOLERANCE = 23;
     };
 
+
+    /**
+     * Rune stat slot constants.
+     *
+     * Includes all the stat slots a rune can have.
+     *
+     * @category Data
+     */
+    final class RUNE_STAT_SLOT_ID{
+
+        /**
+         * Main stat.
+         */
+        const MAIN = -1;
+
+        /**
+         * Innate stat.
+         */
+        const INNATE = 0;
+
+        /**
+         * Substat 1.
+         */
+        const SUBSTAT_1 = 1;
+
+        /**
+         * Substat 2.
+         */
+        const SUBSTAT_2 = 2;
+
+        /**
+         * Substat 3.
+         */
+        const SUBSTAT_3 = 3;
+
+        /**
+         * Substat 4.
+         */
+        const SUBSTAT_4 = 4;
+
+    }
+
+
+    /**
+     * Artifact effectslot constants.
+     *
+     * Includes all the effect slots an artifact can have.
+     *
+     * @category Data
+     */
+    final class ARTIFACT_EFFECT_SLOT_ID{
+
+        /**
+         * Effect 1.
+         */
+        const EFFECT_1 = 1;
+
+        /**
+         * Effect 2.
+         */
+        const EFFECT_2 = 2;
+
+        /**
+         * Effect 3.
+         */
+        const EFFECT_3 = 3;
+
+        /**
+         * Effect 4.
+         */
+        const EFFECT_4 = 4;
+
+    }
+
+
+    /**
+     * Application modes.
+     *
+     * Modes to use RTA configurations or normal configuration.
+     *
+     * @category Data
+     */
+    final class GAME_MODE_ID{
+
+        /**
+         * Normal mode.
+         */
+        const NORMAL = 0;
+
+        /**
+         * RTA mode.
+         */
+        const RTA = 1;
+
+    }
+
+
     /**
      * Rune stat constants.
      *

+ 22 - 0
application/Controller.php

@@ -24,6 +24,11 @@
      */
     $UID = 0;
 
+    /**
+     * @global int $MODE.
+     */
+    $MODE = GAME_MODE_ID::NORMAL;
+
     /**
      * @global resource $DB.
      */
@@ -53,6 +58,7 @@
         public function __construct($params){
 
             global $UID;
+            global $MODE;
             global $db;
 
             $page = null;
@@ -99,6 +105,11 @@
             // Not redirecting to page, just execute a function
             elseif (count($pars) > 1 && strtoupper($pars[0]) == "ACTION"){
                 switch (strtoupper($pars[1])){
+                    case "CHANGE_GAME_MODE":
+                        require_once(PATH::ACTION . "change_game_mode.php");
+                        action();
+                        return;
+                        break;
                     case "LOGIN":
                         require_once(PATH::ACTION . "login.php");
                         action();
@@ -216,6 +227,17 @@
                 return;
             }
 
+            // Get game mode
+            $statement = $db->prepare("SELECT mode FROM player WHERE uid = :uid;");
+            $statement->bindValue(":uid", $UID);
+            $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
+            if ($r && $r["mode"] == GAME_MODE_ID::RTA){
+                $MODE = GAME_MODE_ID::RTA;
+            }
+            else{
+                $MODE = GAME_MODE_ID::NORMAL;
+            }
+
             // Select the model to load.
             array_shift($pars); // Remove first one, should be UID
             if (sizeof($pars) == 0){

+ 43 - 0
application/action/change_game_mode.php

@@ -0,0 +1,43 @@
+<?php
+
+    /**
+     * File for the team score modification.
+     *
+     * Implements an action function to be called from the {@see Controller}.
+     * 
+     * @category Action
+     */
+
+    /**
+     * Sets the score for a team.
+     *
+     * Reads the POST parameters looking for the following KEYS:
+     *  uid
+     *  team
+     *  score
+     * Validates the data and sets the score.
+     * 
+     * @return int 0 on success, negative values on error.
+     * @category Action
+     * @global resource Database connection.
+     */
+    function action(){
+        global $db;
+        $player = filter_input(INPUT_GET, "uid");
+        $mode = filter_input(INPUT_GET, "mode");
+        if (mode != GAME_MODE_ID::NORMAL && mode != GAME_MODE_ID::RTA){
+            return 400;
+        }
+        $statement = $db->prepare("
+          UPDATE player
+          SET mode = :mode
+          WHERE uid = :uid;
+        ");
+        $statement->bindValue(":mode", $mode, SQLITE3_INTEGER);
+        $statement->bindValue(":uid", $player, SQLITE3_INTEGER);
+        $statement->execute();
+        header("HTTP/1.1 201 OK");
+        die();
+        return 201;
+    }
+?>

+ 0 - 1
application/action/login.php

@@ -52,7 +52,6 @@
         $statement->execute();
         $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
         if (!$r){
-            error_log("REDIRECT TO:" . URL::BASE);
             header("Location: " . URL::BASE);
             exit();
             die();

+ 32 - 26
application/action/optimize_get_rune_list.php

@@ -26,6 +26,7 @@
     function action(){
 
         global $db;
+        global $MODE;
 
         // Increase max execution time.
         set_time_limit(60);
@@ -92,18 +93,18 @@
             slot,
             level,
             stars,
-            main_stat,
-            main_stat_value,
-            innate_stat,
-            innate_stat_value,
-            substat_1,
-            substat_1_value + substat_1_grind AS substat_1_value,
-            substat_2,
-            substat_2_value + substat_2_grind AS substat_2_value,
-            substat_3,
-            substat_3_value + substat_3_grind AS substat_3_value,
-            substat_4,
-            substat_4_value + substat_4_grind AS substat_4_value
+            (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::MAIN . " ) AS main_stat,
+            (SELECT value FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::MAIN . " ) AS main_stat_value,
+            (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::INNATE . " ) AS innate_stat,
+            (SELECT value FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::INNATE . " ) AS innate_stat_value,
+            (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_1 . " ) AS substat_1,
+            (SELECT value + grind FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_1 . " ) AS substat_1_value,
+            (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_2 . " ) AS substat_2,
+            (SELECT value + grind FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_2 . " ) AS substat_2_value,
+            (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_3 . " ) AS substat_3,
+            (SELECT value + grind FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_3 . " ) AS substat_3_value,
+            (SELECT stat FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_4 . " ) AS substat_4,
+            (SELECT value + grind FROM rune_stat WHERE rune = rune.id AND slot = " . RUNE_STAT_SLOT_ID::SUBSTAT_4 . " ) AS substat_4_value
           FROM rune
           WHERE
             uid = :uid AND
@@ -117,33 +118,38 @@
             case 0: // Storage only (or itself)
                 $base_s .= "
                   (
-                    assigned_to = :unit_id OR
-                    assigned_to IS NULL
+                    rune.id IN (SELECT DISTINCT unit FROM unit_rune WHERE unit = :unit_id AND rta = $MODE)
+                    OR rune.id NOT IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = $MODE)
                   )";
                 break;
             case 1: // Units in no teams (or itself)
                 $base_s .= "
                   (
-                    assigned_to = :unit_id OR
-                    assigned_to IS NULL OR 
-                    assigned_to NOT IN (SELECT DISTINCT unit FROM team_unit)
+                    rune.id IN (SELECT DISTINCT unit FROM unit_rune WHERE unit = :unit_id AND rta = $MODE)
+                    OR rune.id NOT IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = $MODE)
+                    OR rune.id NOT IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = $MODE AND unit NOT IN (SELECT DISTINCT unit FROM team_unit))
                   )
                 ";
                 break;
             case 2: // Units in teams with 0 score (or itself)
                 $base_s .= "
                   (
-                    assigned_to = :unit_id OR
-                    assigned_to IS NULL OR 
-                    assigned_to NOT IN (SELECT DISTINCT unit FROM team_unit) OR
-                    assigned_to NOT IN (
+                    rune.id IN (SELECT DISTINCT unit FROM unit_rune WHERE unit = :unit_id AND rta = $MODE)
+                    OR rune.id NOT IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = $MODE)
+                    OR rune.id NOT IN (
                       SELECT DISTINCT unit 
-                      FROM
-                        team,
-                        team_unit
+                      FROM unit_rune 
                       WHERE
-                        team.id = team_unit.team AND
-                        team.score > 0
+                        rta = $MODE
+                        AND unit NOT IN (
+                          SELECT DISTINCT unit 
+                          FROM
+                            team,
+                            team_unit
+                          WHERE
+                            team.id = team_unit.team
+                            AND team.score > 0
+                        )
                     )
                   )
                 ";

+ 29 - 172
application/entity/Artifact.php

@@ -11,11 +11,13 @@
      * Require dependent entities if not present.
      */
     require_once(PATH::ENTITY . "Entity.php");
+    require_once(PATH::ENTITY . "Artifact_Stat.php");
+    require_once(PATH::ENTITY . "Artifact_Effect.php");
 
     /**
      * Owned artifact.
      *
-     * Represents an object from the table 'artifac'.
+     * Represents an object from the table 'artifact'.
      *
      * @category Entity
      */
@@ -31,11 +33,6 @@
          */
         public $id;
 
-        /**
-         * @var int ID of the monster the rune is assigned to.
-         */
-        public $assigned_to;
-
         /**
          * @var int Artifact type (null if element artifact).
          *
@@ -102,91 +99,21 @@
         public $max_efficiency;
 
         /**
-         * @var int Main stat of the artifact.
+         * @var Artifact_Stat Main stat of the artifact.
          *
          * @see STAT_ID
          */
-        public $main_stat;
-
-        /**
-         * @var string Main stat name (uppercase).
-         */
-        public $main_stat_name;
+        public $stat;
 
         /**
-         * @var int Main stat value of the artifact.
+         * @var \Artifact_Effect Effects of the artifact.
          */
-        public $main_stat_value;
+        public $effects = [];
 
         /**
-         * @var string Extra stat value of the artifact.
+         * @var Unit Unit the artifact is assigned to.
          */
-        public $innate_stat_value;
-
-        /**
-         * @var int Number of substats.
-         */
-        public $substats;
-
-        /**
-         * @var int Effect 1 of the artifact.
-         */
-        public $effect_1;
-
-        /**
-         * @var int Effect 1 value of the artifact.
-         */
-        public $effect_1_value;
-
-        /**
-         * @var string Effect 1 description.
-         */
-        public $effect_1_description;
-
-        /**
-         * @var int Effect 2 of the artifact.
-         */
-        public $effect_2;
-
-        /**
-         * @var int Effect 2 value of the artifact.
-         */
-        public $effect_2_value;
-
-        /**
-         * @var string Effect 2 description.
-         */
-        public $effect_2_description;
-
-        /**
-         * @var int Effect 3 of the artifact.
-         */
-        public $effect_3;
-
-        /**
-         * @var int Effect 3 value of the artifact.
-         */
-        public $effect_3_value;
-
-        /**
-         * @var string Effect 3 description.
-         */
-        public $effect_3_description;
-
-        /**
-         * @var int Effect 4 of the artifact.
-         */
-        public $effect_4;
-
-        /**
-         * @var int Effect 4 value of the artifact.
-         */
-        public $effect_4_value;
-
-        /**
-         * @var string Effect 4 description.
-         */
-        public $effect_4_description;
+        public $unit;
 
         /**
          * Constructor.
@@ -204,7 +131,6 @@
             $statement = $db->prepare("
               SELECT
                 id,
-                assigned_to,
                 type,
                 attribute,
                 archetype,
@@ -214,24 +140,7 @@
                 value,
                 efficiency,
                 max_efficiency,
-                main_stat,
-                main_stat_value,
-                effect_1,
-                effect_1_value,
-                effect_1_enchant,
-                effect_1_grind,
-                effect_2,
-                effect_2_value,
-                effect_2_enchant,
-                effect_2_grind,
-                effect_3,
-                effect_3_value,
-                effect_3_enchant,
-                effect_3_grind,
-                effect_4,
-                effect_4_value,
-                effect_4_enchant,
-                effect_4_grind
+                locked
               FROM artifact
               WHERE id = :id;
             ");
@@ -239,7 +148,6 @@
             $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
             if ($r){
                 $this->id = $r["id"];
-                $this->assigned_to = $r["assigned_to"];
                 $this->type = $r["type"];
                 $this->element = $r["attribute"];
                 $this->archetype = $r["archetype"];
@@ -249,76 +157,25 @@
                 $this->value = $r["value"];
                 $this->efficiency = $r["efficiency"];
                 $this->max_efficiency = $r["max_efficiency"];
-                $this->main_stat = $r["main_stat"];
-                $this->main_stat_value = $r["main_stat_value"];
-                $this->effect_1 = $r["effect_1"];
-                $this->effect_1_value = $r["effect_1_value"];
-                $this->effect_2 = $r["effect_2"];
-                $this->effect_2_value = $r["effect_2_value"];
-                $this->effect_3 = $r["effect_3"];
-                $this->effect_3_value = $r["effect_3_value"];
-                $this->effect_4 = $r["effect_4"];
-                $this->effect_4_value = $r["effect_4_value"];
-                $this->refresh_names();
-            }
-        }
-
-        /**
-         * Calculates name variables.
-         */
-        public function refresh_names(){
-            $this->main_stat_name = $this->stat_name($this->main_stat);
-            $this->effect_1_description = $this->effect_description($this->effect_1, $this->effect_1_value);
-            $this->effect_2_description = $this->effect_description($this->effect_2, $this->effect_2_value);
-            $this->effect_3_description = $this->effect_description($this->effect_3, $this->effect_3_value);
-            $this->effect_4_description = $this->effect_description($this->effect_4, $this->effect_4_value);
-            $this->quality_name = $this->get_quality_name($this->quality);
-            $this->original_quality_name = $this->get_quality_name($this->original_quality);
-        }
-
-        /**
-         * Gets a stat name from the mappings.
-         *
-         * @param int $stat Stat id.
-         * @return string Stat name (Uppercase)
-         */
-        private function stat_name($stat){
-            switch ($stat){
-                case ARTIFACT_STAT_ID::HP:
-                    return "HP";
-                case ARTIFACT_STAT_ID::ATK:
-                    return "ATK";
-                case ARTIFACT_STAT_ID::DEF:
-                    return "DEF";
-                default:
-                    return "";
-            }
-        }
-
-        /**
-         * Composes an effect description.
-         *
-         * @param int $effect Effect id.
-         * @param int $value Effect value.
-         * @return string Effect description, null if unavailable.
-         * @global resource Database connection.
-         */
-        private function effect_description($effect, $value){
-
-            global $db;
-
-            $statement = $db->prepare("
-              SELECT name
-              FROM k_artifact_effect
-              WHERE id = :id;
-            ");
-            $statement->bindValue(':id', $effect, SQLITE3_INTEGER);
-            $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
-            if ($r){
-                return str_replace("{}", $value, $r["name"]);
-            }
-            else{
-                return null;
+                $this->locked = $r["locked"];
+                $this->quality_name = $this->get_quality_name($this->quality);
+                $this->original_quality_name = $this->get_quality_name($this->original_quality);
+
+                // Get stat
+                $this->stat = new Artifact_Stat($this->id);
+
+                // Get effects
+                $statement = $db->prepare("
+                  SELECT slot
+                  FROM artifact_effect
+                  WHERE artifact = :artifact
+                  ORDER BY slot;
+                ");
+                $statement->bindValue(':artifact', $this->id, SQLITE3_INTEGER);
+                $q = $statement->execute();
+                while ($r = $q->fetchArray(SQLITE3_ASSOC)){
+                    array_push($this->effects, new Artifact_Effect($this->id, $r["slot"]));
+                }
             }
         }
 

+ 108 - 0
application/entity/Artifact_Effect.php

@@ -0,0 +1,108 @@
+<?php
+    /**
+     * Artifact effect entity file.
+     *
+     * Creates the entity and makes it available.
+     *
+     * @category Entity
+     */
+
+    /**
+     * Require dependent entities if not present.
+     */
+    require_once(PATH::ENTITY . "Entity.php");
+
+    /**
+     * Artifact effect.
+     *
+     * Represents an object from the table 'artifact_effect'.
+     *
+     * @category Entity
+     */
+    class Artifact_Effect extends Entity{
+
+        /**
+         * @var int Effect slot.
+         *
+         * @see ARTIFACT_EFFECT_SLOT_ID
+         */
+        public $slot;
+
+        /**
+         * @var int Effect identifier.
+         *
+         * @see ARTIFACT_EFFECT_ID
+         */
+        public $effect;
+
+        /**
+         * @var string Effect name (uppercase).
+         */
+        public $name = "";
+
+        /**
+         * @var int Effect value.
+         */
+        public $value;
+
+        /**
+         * @var int Ammount gained by effect grindstone.
+         */
+        public $grind;
+
+        /**
+         * @var int Indicates if a gem has been used.
+         */
+        public $enchant;
+
+        /**
+         * Constructor.
+         *
+         * Searches the database and retrieves the information about the
+         * artifact effect, populating it and it's items.
+         *
+         * @param int $artifact Artifact id.
+         * @param int $slot Artifact slot id.
+         * @global resource Database connection.
+         */
+        public function __construct($artifact, $slot){
+
+            global $db;
+
+            $statement = $db->prepare("
+              SELECT
+                slot,
+                effect,
+                value,
+                enchant,
+                grind
+              FROM artifact_effect
+              WHERE
+                artifact = :artifact AND
+                slot = :slot;
+            ");
+            $statement->bindValue(':artifact', $artifact, SQLITE3_INTEGER);
+            $statement->bindValue(':slot', $slot, SQLITE3_INTEGER);
+            $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
+            if ($r){
+                $this->effect = $r["effect"];
+                $this->value = $r["value"];
+                $this->enchant = $r["enchant"];
+                $this->grind = $r["grind"];
+                
+                $statement = $db->prepare("
+                  SELECT name
+                  FROM k_artifact_effect
+                  WHERE id = :id;
+                ");
+                $statement->bindValue(':id', $this->effect, SQLITE3_INTEGER);
+                $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
+                if ($r){
+                    $this->name = str_replace("{}", $this->value, $r["name"]);
+                }
+
+            }
+        }
+
+    }
+?>

+ 82 - 0
application/entity/Artifact_Stat.php

@@ -0,0 +1,82 @@
+<?php
+    /**
+     * Artifact stat entity file.
+     *
+     * Creates the entity and makes it available.
+     *
+     * @category Entity
+     */
+
+    /**
+     * Require dependent entities if not present.
+     */
+    require_once(PATH::ENTITY . "Entity.php");
+
+    /**
+     * Artifact_stat.
+     *
+     * Represents an object from the table 'artifact_stat'.
+     *
+     * @category Entity
+     */
+    class Artifact_Stat extends Entity{
+
+        /**
+         * @var int Stat of the artifact.
+         *
+         * @see ARTIFACT_STAT_ID
+         */
+        public $stat;
+
+        /**
+         * @var string Stat name (uppercase).
+         */
+        public $name = "";
+
+        /**
+         * @var int Stat value of the rune.
+         */
+        public $value;
+
+        /**
+         * Constructor.
+         *
+         * Searches the database and retrieves the information about the
+         * artifact stat, populating it and it's items.
+         *
+         * @param int $id Artifact id.
+         * @global resource Database connection.
+         */
+        public function __construct($artifact){
+
+            global $db;
+
+            $statement = $db->prepare("
+              SELECT
+                stat,
+                value
+              FROM artifact_stat
+              WHERE
+                artifact = :artifact
+            ");
+            $statement->bindValue(':artifact', $artifact, SQLITE3_INTEGER);
+            $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
+            if ($r){
+                $this->stat = $r["stat"];
+                $this->value = $r["value"];
+                switch ($this->stat){
+                    case ARTIFACT_STAT_ID::HP:
+                        $this->name = "HP";
+                        break;
+                    case ARTIFACT_STAT_ID::ATK:
+                        $this->name = "ATK";
+                        break;
+                    case ARTIFACT_STAT_ID::DEF:
+                        $this->name = "DEF";
+                        break;
+                }
+            }
+        }
+
+    }
+?>

+ 115 - 21
application/entity/Run.php

@@ -347,32 +347,57 @@
                         $rune->ancient = $r["ancient"];
                         $rune->quality = $r["quality"];
                         $rune->original_quality = $r["quality"];
+                        $rune->quality_name = $this->get_rune_quality_name($r["quality"]);
+                        $rune->original_quality_name = $this->get_rune_quality_name($r["quality"]);
                         $rune->value = $r["value"];
                         $rune->value = 0;
                         $rune->efficiency = $r["efficiency"];
                         // TODO: Calculate?
                         $rune->max_efficiency = $r["efficiency"];
-                        $rune->main_stat = $r["main_stat"];
-                        $rune->main_stat_value = $r["main_stat_value"];
-                        $rune->innate_stat = $r["innate_stat"];
-                        $rune->innate_stat_value = $r["innate_stat_value"];
-                        $rune->substat_1 = $r["substat_1"];
-                        $rune->substat_1_value = $r["substat_1_value"];
-                        $rune->substat_1_enchant = 0;
-                        $rune->substat_1_grind = 0;
-                        $rune->substat_2 = $r["substat_2"];
-                        $rune->substat_2_value = $r["substat_2_value"];
-                        $rune->substat_2_enchant = 0;
-                        $rune->substat_2_grind = 0;
-                        $rune->substat_3 = $r["substat_3"];
-                        $rune->substat_3_value = $r["substat_3_value"];
-                        $rune->substat_3_enchant = 0;
-                        $rune->substat_3_grind = 0;
-                        $rune->substat_4 = $r["substat_4"];
-                        $rune->substat_4_value = $r["substat_4_value"];
-                        $rune->substat_4_enchant = 0;
-                        $rune->substat_4_grind = 0;
-                        $rune->refresh_names();
+                        $rune->main_stat = new Rune_Stat(null, null);
+                        $rune->main_stat->slot = RUNE_STAT_SLOT_ID::MAIN;
+                        $rune->main_stat->stat = $r["main_stat"];
+                        $rune->main_stat->stat_name = $this->get_stat_name($r["main_stat"]);
+                        $rune->main_stat->value = $r["main_stat_value"];
+                        if ($r["innate_stat"] != null){
+                            $rune->innate_stat = new Rune_Stat(null, null);
+                            $rune->innate_stat->slot = RUNE_STAT_SLOT_ID::INNATE;
+                            $rune->innate_stat->stat = $r["innate_stat"];
+                            $rune->innate_stat->stat_name = $this->get_stat_name($r["innate_stat"]);
+                            $rune->innate_stat->value = $r["innate_stat_value"];
+                        }
+                        if ($r["substat_1"] != null){
+                            $substat = new Rune_Stat(null, null);
+                            $substat->slot = RUNE_STAT_SLOT_ID::SUBSTAT_1;
+                            $substat->stat = $r["substat_1"];
+                            $substat->stat_name = $this->get_stat_name($r["substat_1"]);
+                            $substat->value = $r["substat_1_value"];
+                            array_push($rune->substats, $substat);
+                        }
+                        if ($r["substat_2"] != null){
+                            $substat = new Rune_Stat(null, null);
+                            $substat->slot = RUNE_STAT_SLOT_ID::SUBSTAT_2;
+                            $substat->stat = $r["substat_2"];
+                            $substat->stat_name = $this->get_stat_name($r["substat_2"]);
+                            $substat->value = $r["substat_2_value"];
+                            array_push($rune->substats, $substat);
+                        }
+                        if ($r["substat_3"] != null){
+                            $substat = new Rune_Stat(null, null);
+                            $substat->slot = RUNE_STAT_SLOT_ID::SUBSTAT_3;
+                            $substat->stat = $r["substat_3"];
+                            $substat->stat_name = $this->get_stat_name($r["substat_3"]);
+                            $substat->value = $r["substat_3_value"];
+                            array_push($rune->substats, $substat);
+                        }
+                        if ($r["substat_4"] != null){
+                            $substat = new Rune_Stat(null, null);
+                            $substat->slot = RUNE_STAT_SLOT_ID::SUBSTAT_4;
+                            $substat->stat = $r["substat_4"];
+                            $substat->stat_name = $this->get_stat_name($r["substat_4"]);
+                            $substat->value = $r["substat_4_value"];
+                            array_push($rune->substats, $substat);
+                        }
                     }
                     array_push($this->rune, $rune);
                 }
@@ -433,5 +458,74 @@
             }
         }
 
+        /**
+         * Gets a quality name frm the mappings.
+         *
+         * @param int $quality Quality id.
+         * @return string Quality name (Uppercase)
+         */
+        private function get_rune_quality_name($quality){
+            switch ($quality){
+                case QUALITY_ID::NORMAL:
+                    return "NORMAL";
+                case QUALITY_ID::MAGIC:
+                    return "MAGIC";
+                case QUALITY_ID::RARE:
+                    return "RARE";
+                case QUALITY_ID::HERO:
+                    return "HERO";
+                case QUALITY_ID::LEGEND:
+                    return "LEGEND";
+                default:
+                    return "";
+            }
+        }
+
+        /**
+         * Gets a stat name from the mappings.
+         *
+         * @param int $stat Stat id.
+         * @return string Stat name (Uppercase)
+         */
+        private function get_stat_name($stat){
+            switch ($stat){
+                case RUNE_STAT_ID::HP:
+                    return "HP";
+                    break;
+                case RUNE_STAT_ID::HP_P:
+                    return "HP%";
+                    break;
+                case RUNE_STAT_ID::ATK:
+                    return "ATK";
+                    break;
+                case RUNE_STAT_ID::ATK_P:
+                    return "ATK%";
+                    break;
+                case RUNE_STAT_ID::DEF:
+                    return "DEF";
+                    break;
+                case RUNE_STAT_ID::DEF_P:
+                    return "DEF%";
+                    break;
+                case RUNE_STAT_ID::SPD:
+                    return "SPD";
+                    break;
+                case RUNE_STAT_ID::CRR:
+                    return "CRR";
+                    break;
+                case RUNE_STAT_ID::CRD:
+                    return "CRD";
+                    break;
+                case RUNE_STAT_ID::RES:
+                    return "RES";
+                    break;
+                case RUNE_STAT_ID::ACC:
+                    return "ACC";
+                    break;
+                default:
+                    return "";
+            }
+        }
+
     }
 ?>

+ 55 - 217
application/entity/Rune.php

@@ -12,6 +12,7 @@
      */
     require_once(PATH::ENTITY . "Entity.php");
     require_once(PATH::ENTITY . "K_Rune_Set.php");
+    require_once(PATH::ENTITY . "Rune_Stat.php");
 
     /**
      * Owned rune.
@@ -32,11 +33,6 @@
          */
         public $id;
 
-        /**
-         * @var int ID of the monster the rune is assigned to.
-         */
-        public $assigned_to;
-
         /**
          * @var K_Rune_Set Rune set.
          */
@@ -102,131 +98,36 @@
         public $max_efficiency;
 
         /**
-         * @var int Main stat of the rune.
-         *
-         * @see RUNE_STAT_ID
+         * @var int Indicates if the rune is locked.
          */
-        public $main_stat;
+        public $locked;
 
         /**
-         * @var string Main stat name (uppercase).
+         * @var Rune_Stat Main stat of the rune.
          */
-        public $main_stat_name;
-
-        /**
-         * @var int Main stat value of the rune.
-         */
-        public $main_stat_value;
+        public $main_stat;
 
         /**
-         * @var int Extra stat of the rune.
-         *
-         * @see RUNE_STAT_ID
+         * @var Rune_Stat Extra stat of the rune.
          */
         public $innate_stat;
 
         /**
-         * @var string Extra stat name (uppercase).
-         */
-        public $innate_stat_name;
-
-        /**
-         * @var string Extra stat value of the rune.
-         */
-        public $innate_stat_value;
-
-        /**
-         * @var int Number of substats.
-         */
-        public $substats;
-
-        /**
-         * @var int Substat 1 of the rune.
-         *
-         * @see RUNE_STAT_ID
-         */
-        public $substat_1;
-
-        /**
-         * @var string Substat 1 name (uppercase).
-         */
-        public $substat_1_name;
-
-        /**
-         * @var int Substat 1 value of the rune.
-         */
-        public $substat_1_value;
-
-        /**
-         * @var int Ammount gained by the substat 1 enchant.
-         */
-        public $substat_1_craft;
-
-        /**
-         * @var int Substat 2 of the rune.
-         *
-         * @see RUNE_STAT_ID
-         */
-        public $substat_2;
-
-        /**
-         * @var string Substat 2 name (uppercase).
+         * @var \Rune_Stat[] Substats of the rune.
          */
-        public $substat_2_name;
+        public $substats = [];
 
         /**
-         * @var int Substat 2 value of the rune.
-         */
-        public $substat_2_value;
-
-        /**
-         * @var int Ammount gained by the substat 2 enchant.
-         */
-        public $substat_2_craft;
-
-        /**
-         * @var int Substat 3 of the rune.
-         *
-         * @see RUNE_STAT_ID
-         */
-        public $substat_3;
-
-        /**
-         * @var string Substat 3 name (uppercase).
-         */
-        public $substat_3_name;
-
-        /**
-         * @var int Substat 3 value of the rune.
-         */
-        public $substat_3_value;
-
-        /**
-         * @var int Ammount gained by the substat 3 enchant.
-         */
-        public $substat_3_craft;
-
-        /**
-         * @var int Substat 4 of the rune.
+         * @var \Rune_Stat[] All stats.
          *
-         * @see RUNE_STAT_ID
+         * Includes main, innate and substats
          */
-        public $substat_4;
+        public $stats = [];
 
         /**
-         * @var string Substat 4 name (uppercase).
+         * @var Unit Unit the rune is assigned to.
          */
-        public $substat_4_name;
-
-        /**
-         * @var int Substat 4 value of the rune.
-         */
-        public $substat_4_value;
-
-        /**
-         * @var int Ammount gained by the substat 4 enchant.
-         */
-        public $substat_4_craft;
+        public $unit;
 
         /**
          * Constructor.
@@ -244,7 +145,6 @@
             $statement = $db->prepare("
               SELECT
                 id,
-                assigned_to,
                 type,
                 slot,
                 stars,
@@ -255,26 +155,7 @@
                 value,
                 efficiency,
                 max_efficiency,
-                main_stat,
-                main_stat_value,
-                innate_stat,
-                innate_stat_value,
-                substat_1,
-                substat_1_value,
-                substat_1_enchant,
-                substat_1_grind,
-                substat_2,
-                substat_2_value,
-                substat_2_enchant,
-                substat_2_grind,
-                substat_3,
-                substat_3_value,
-                substat_3_enchant,
-                substat_3_grind,
-                substat_4,
-                substat_4_value,
-                substat_4_enchant,
-                substat_4_grind
+                locked
               FROM rune
               WHERE id = :id;
             ");
@@ -282,7 +163,6 @@
             $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
             if ($r){
                 $this->id = $r["id"];
-                $this->assigned_to = $r["assigned_to"];
                 $this->type = new K_Rune_Set($r["type"]);
                 $this->slot = $r["slot"];
                 $this->stars = $r["stars"];
@@ -293,27 +173,34 @@
                 $this->value = $r["value"];
                 $this->efficiency = $r["efficiency"];
                 $this->max_efficiency = $r["max_efficiency"];
-                $this->main_stat = $r["main_stat"];
-                $this->main_stat_value = $r["main_stat_value"];
-                $this->innate_stat = $r["innate_stat"];
-                $this->innate_stat_value = $r["innate_stat_value"];
-                $this->substat_1 = $r["substat_1"];
-                $this->substat_1_value = $r["substat_1_value"];
-                $this->substat_1_enchant = $r["substat_1_enchant"];
-                $this->substat_1_grind = $r["substat_1_grind"];
-                $this->substat_2 = $r["substat_2"];
-                $this->substat_2_value = $r["substat_2_value"];
-                $this->substat_2_enchant = $r["substat_2_enchant"];
-                $this->substat_2_grind = $r["substat_2_grind"];
-                $this->substat_3 = $r["substat_3"];
-                $this->substat_3_value = $r["substat_3_value"];
-                $this->substat_3_enchant = $r["substat_3_enchant"];
-                $this->substat_3_grind = $r["substat_3_grind"];
-                $this->substat_4 = $r["substat_4"];
-                $this->substat_4_value = $r["substat_4_value"];
-                $this->substat_4_enchant = $r["substat_4_enchant"];
-                $this->substat_4_grind = $r["substat_4_grind"];
-                $this->refresh_names();
+                $this->locked = $r["locked"];
+
+                // Get substats
+                $statement = $db->prepare("
+                  SELECT slot
+                  FROM rune_stat
+                  WHERE rune = :rune
+                  ORDER BY slot;
+                ");
+                $statement->bindValue(':rune', $this->id, SQLITE3_INTEGER);
+                $q = $statement->execute();
+                while ($r = $q->fetchArray(SQLITE3_ASSOC)){
+                    $stat = new Rune_Stat($this->id, $r["slot"]);
+                    array_push($this->stats, $stat);
+                    switch ($r["slot"]){
+                        case RUNE_STAT_SLOT_ID::MAIN:
+                            $this->main_stat = $stat;
+                            break;
+                        case RUNE_STAT_SLOT_ID::INNATE:
+                            $this->innate_stat = $stat;
+                            break;
+                        default:
+                            array_push($this->substats, $stat);
+                            break;
+                    }
+                }
+                $this->quality_name = $this->get_quality_name($this->quality);
+                $this->original_quality_name = $this->get_quality_name($this->original_quality);
             }
         }
 
@@ -328,80 +215,31 @@
             if ($level < 0 || $level > 15){
                 return 0;
             }
-            switch ($this->main_stat){
-                    case RUNE_STAT_ID::HP:
-                        return RUNE_STAT_VALUES::HP[$this->stars][$level];
-                    case RUNE_STAT_ID::HP_P:
-                        return RUNE_STAT_VALUES::HP_P[$this->stars][$level];
-                    case RUNE_STAT_ID::ATK:
-                        return RUNE_STAT_VALUES::ATK[$this->stars][$level];
-                    case RUNE_STAT_ID::ATK_P:
-                        return RUNE_STAT_VALUES::ATK_P[$this->stars][$level];
-                    case RUNE_STAT_ID::DEF:
-                        return RUNE_STAT_VALUES::DEF[$this->stars][$level];
-                    case RUNE_STAT_ID::DEF_P:
-                        return RUNE_STAT_VALUES::DEF_P[$this->stars][$level];
-                    case RUNE_STAT_ID::SPD:
-                        return RUNE_STAT_VALUES::SPD[$this->stars][$level];
-                    case RUNE_STAT_ID::CRR:
-                        return RUNE_STAT_VALUES::CRR[$this->stars][$level];
-                    case RUNE_STAT_ID::CRD:
-                        return RUNE_STAT_VALUES::CRD[$this->stars][$level];
-                    case RUNE_STAT_ID::RES:
-                        return RUNE_STAT_VALUES::RES[$this->stars][$level];
-                    case RUNE_STAT_ID::ACC:
-                        return RUNE_STAT_VALUES::ACC[$this->stars][$level];
-                    default:
-                        return 0;
-            }
-        }
-
-        /**
-         * Calculates name variables.
-         */
-        public function refresh_names(){
-            $this->main_stat_name = $this->stat_name($this->main_stat);
-            $this->innate_stat_name = $this->stat_name($this->innate_stat);
-            $this->substat_1_name = $this->stat_name($this->substat_1);
-            $this->substat_2_name = $this->stat_name($this->substat_2);
-            $this->substat_3_name = $this->stat_name($this->substat_3);
-            $this->substat_4_name = $this->stat_name($this->substat_4);
-            $this->quality_name = $this->get_quality_name($this->quality);
-            $this->original_quality_name = $this->get_quality_name($this->original_quality);
-        }
-
-        /**
-         * Gets a stat name from the mappings.
-         *
-         * @param int $stat Stat id.
-         * @return string Stat name (Uppercase)
-         */
-        private function stat_name($stat){
-            switch ($stat){
+            switch ($this->main_stat->stat){
                 case RUNE_STAT_ID::HP:
-                    return "HP";
+                    return RUNE_STAT_VALUES::HP[$this->stars][$level];
                 case RUNE_STAT_ID::HP_P:
-                    return "HP%";
+                    return RUNE_STAT_VALUES::HP_P[$this->stars][$level];
                 case RUNE_STAT_ID::ATK:
-                    return "ATK";
+                    return RUNE_STAT_VALUES::ATK[$this->stars][$level];
                 case RUNE_STAT_ID::ATK_P:
-                    return "ATK%";
+                    return RUNE_STAT_VALUES::ATK_P[$this->stars][$level];
                 case RUNE_STAT_ID::DEF:
-                    return "DEF";
+                    return RUNE_STAT_VALUES::DEF[$this->stars][$level];
                 case RUNE_STAT_ID::DEF_P:
-                    return "DEF%";
+                    return RUNE_STAT_VALUES::DEF_P[$this->stars][$level];
                 case RUNE_STAT_ID::SPD:
-                    return "SPD";
+                    return RUNE_STAT_VALUES::SPD[$this->stars][$level];
                 case RUNE_STAT_ID::CRR:
-                    return "CRR";
+                    return RUNE_STAT_VALUES::CRR[$this->stars][$level];
                 case RUNE_STAT_ID::CRD:
-                    return "CRD";
+                    return RUNE_STAT_VALUES::CRD[$this->stars][$level];
                 case RUNE_STAT_ID::RES:
-                    return "RES";
+                    return RUNE_STAT_VALUES::RES[$this->stars][$level];
                 case RUNE_STAT_ID::ACC:
-                    return "ACC";
+                    return RUNE_STAT_VALUES::ACC[$this->stars][$level];
                 default:
-                    return "";
+                    return 0;
             }
         }
 

+ 131 - 0
application/entity/Rune_Stat.php

@@ -0,0 +1,131 @@
+<?php
+    /**
+     * Rune stat entity file.
+     *
+     * Creates the entity and makes it available.
+     *
+     * @category Entity
+     */
+
+    /**
+     * Require dependent entities if not present.
+     */
+    require_once(PATH::ENTITY . "Entity.php");
+
+    /**
+     * Rune_stat.
+     *
+     * Represents an object from the table 'rune'.
+     *
+     * @category Entity
+     */
+    class Rune_Stat extends Entity{
+
+        /**
+         * @var int Stat slot.
+         *
+         * @see RUNE_STAT_SLOT_ID
+         */
+        public $slot;
+
+        /**
+         * @var int Substat 1 of the rune.
+         *
+         * @see RUNE_STAT_ID
+         */
+        public $stat;
+
+        /**
+         * @var string Substat 1 name (uppercase).
+         */
+        public $stat_name = "";
+
+        /**
+         * @var int Substat 1 value of the rune.
+         */
+        public $value;
+
+        /**
+         * @var int Ammount gained by the substat 1 enchant.
+         */
+        public $grind;
+
+        /**
+         * @var int Indicates if a gem has been used.
+         */
+        public $enchant;
+
+        /**
+         * Constructor.
+         *
+         * Searches the database and retrieves the information about the
+         * rune, populating it and it's items.
+         *
+         * @param int $id Rune id.
+         * @global resource Database connection.
+         */
+        public function __construct($rune, $slot){
+
+            global $db;
+
+            $statement = $db->prepare("
+              SELECT
+                slot,
+                stat,
+                value,
+                enchant,
+                grind
+              FROM rune_stat
+              WHERE
+                rune = :rune AND
+                slot = :slot;
+            ");
+            $statement->bindValue(':rune', $rune, SQLITE3_INTEGER);
+            $statement->bindValue(':slot', $slot, SQLITE3_INTEGER);
+            $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
+            if ($r){
+                $this->slot = $r["slot"];
+                $this->stat = $r["stat"];
+                $this->value = $r["value"];
+                $this->enchant = $r["enchant"];
+                $this->grind = $r["grind"];
+                switch ($this->stat){
+                    case RUNE_STAT_ID::HP:
+                        $this->stat_name = "HP";
+                        break;
+                    case RUNE_STAT_ID::HP_P:
+                        $this->stat_name = "HP%";
+                        break;
+                    case RUNE_STAT_ID::ATK:
+                        $this->stat_name = "ATK";
+                        break;
+                    case RUNE_STAT_ID::ATK_P:
+                        $this->stat_name = "ATK%";
+                        break;
+                    case RUNE_STAT_ID::DEF:
+                        $this->stat_name = "DEF";
+                        break;
+                    case RUNE_STAT_ID::DEF_P:
+                        $this->stat_name = "DEF%";
+                        break;
+                    case RUNE_STAT_ID::SPD:
+                        $this->stat_name = "SPD";
+                        break;
+                    case RUNE_STAT_ID::CRR:
+                        $this->stat_name = "CRR";
+                        break;
+                    case RUNE_STAT_ID::CRD:
+                        $this->stat_name = "CRD";
+                        break;
+                    case RUNE_STAT_ID::RES:
+                        $this->stat_name = "RES";
+                        break;
+                    case RUNE_STAT_ID::ACC:
+                        $this->stat_name = "ACC";
+                        break;
+                }
+            }
+        }
+
+    }
+?>

+ 26 - 20
application/entity/Unit.php

@@ -519,62 +519,68 @@
          * Calculates the totalls and the effective stats.
          *
          * @gobal int User ID.
+         * @gobal int Game mode (Normal/RTA).
          * @global resource Database connection.
          */
         public function load_stats(){
 
             global $UID;
+            global $MODE;
             global $db;
 
             // Runes
             $this->rune = [];
             $statement = $db->prepare("
-              SELECT id
-              FROM rune
-              WHERE assigned_to = :assigned;
+              SELECT rune
+              FROM unit_rune
+              WHERE
+                unit = :unit AND
+                rta = :rta;
             ");
-            $statement->bindValue(':assigned', $this->id, SQLITE3_INTEGER);
+            $statement->bindValue(':unit', $this->id, SQLITE3_INTEGER);
+            $statement->bindValue(':rta', $MODE, SQLITE3_INTEGER);
             $q = $statement->execute();
             while ($r = $q->fetchArray(SQLITE3_ASSOC)){
-                array_push($this->rune, new Rune($r["id"]));
+                array_push($this->rune, new Rune($r["rune"]));
             }
             foreach ($this->rune as $rune){
-                $this->sum_rune_stat($rune->main_stat, $rune->main_stat_value);
-                $this->sum_rune_stat($rune->innate_stat, $rune->innate_stat_value);
-                $this->sum_rune_stat($rune->substat_1, $rune->substat_1_value + $rune->substat_1_grind);
-                $this->sum_rune_stat($rune->substat_2, $rune->substat_2_value + $rune->substat_2_grind);
-                $this->sum_rune_stat($rune->substat_3, $rune->substat_3_value + $rune->substat_3_grind);
-                $this->sum_rune_stat($rune->substat_4, $rune->substat_4_value + $rune->substat_4_grind);
+                foreach ($rune->stats as $stat){
+                    $this->sum_rune_stat($stat->stat, $stat->value + $stat->grind);
+                }
             }
             $this->rune_attack = ceil($this->rune_attack);
             $this->rune_defense = ceil($this->rune_defense);
             $this->rune_hp = ceil($this->rune_hp);
 
             // Artifacts
+            $this->artifact = [];
             $statement = $db->prepare("
-              SELECT id
-              FROM artifact
-              WHERE assigned_to = :assigned;
+              SELECT artifact
+              FROM unit_artifact
+              WHERE
+                unit = :unit AND
+                rta = :rta;
             ");
-            $statement->bindValue(':assigned', $this->id, SQLITE3_INTEGER);
+            $statement->bindValue(':unit', $this->id, SQLITE3_INTEGER);
+            $statement->bindValue(':rta', $MODE, SQLITE3_INTEGER);
             $q = $statement->execute();
             while ($r = $q->fetchArray(SQLITE3_ASSOC)){
-                $artifact = new Artifact($r["id"]);
+                $artifact = new Artifact($r["artifact"]);
                 if ($artifact->type == ARTIFACT_TYPE::ARCHETYPE){
                     $this->artifact_type = $artifact;
                 }
                 else{
                     $this->artifact_element = $artifact;
                 }
-                switch($artifact->main_stat){
+                switch($artifact->stat->stat){
                     case ARTIFACT_STAT_ID::ATK:
-                        $this->artifact_attack += $artifact->main_stat_value;
+                        $this->artifact_attack += $artifact->stat->value;
                         break;
                     case ARTIFACT_STAT_ID::DEF:
-                        $this->artifact_defense += $artifact->main_stat_value;
+                        $this->artifact_defense += $artifact->stat->value;
                         break;
                     case ARTIFACT_STAT_ID::HP:
-                        $this->artifact_hp += $artifact->main_stat_value;
+                        $this->artifact_hp += $artifact->stat->value;
                         break;
                 }
             }

+ 41 - 40
application/helper/HTML_Helper.php

@@ -225,13 +225,13 @@
             // Main stat
             $html .= "<tr class='main_stat'>\n";
             $html .= "<td class='stat'>\n";
-            if (in_array($rune->main_stat_name, array("CRR", "CRD", "RES", "ACC", "HP%", "ATK%", "DEF%"))){
-                $stat_name = str_replace("%", "", $rune->main_stat_name);
-                $stat_value = "+" . $rune->main_stat_value . "%";
+            if (in_array($rune->main_stat->stat_name, array("CRR", "CRD", "RES", "ACC", "HP%", "ATK%", "DEF%"))){
+                $stat_name = str_replace("%", "", $rune->main_stat->stat_name);
+                $stat_value = "+" . $rune->main_stat->value . "%";
             }
             else{
-                $stat_name = $rune->main_stat_name;
-                $stat_value = "+" . $rune->main_stat_value. "&nbsp;";
+                $stat_name = $rune->main_stat->stat_name;
+                $stat_value = "+" . $rune->main_stat->value. "&nbsp;";
             }
             $html .= $stat_name . "\n";
             $html .= "</td>\n";
@@ -246,17 +246,17 @@
             // Innate stat
             $html .= "<tr class='innate_stat'>\n";
             $html .= "<td class='stat'>\n";
-            if (strlen($rune->innate_stat) == 0){
+            if ($rune->innate_stat == null){
                 $stat_name = "&nbsp;";
                 $stat_value = "";
             }
-            elseif (in_array($rune->innate_stat_name, array("CRR", "CRD", "RES", "ACC", "HP%", "ATK%", "DEF%"))){
-                $stat_name = str_replace("%", "", $rune->innate_stat_name);
-                $stat_value = "+" . $rune->innate_stat_value . "%";
+            elseif (in_array($rune->innate_stat->stat_name, array("CRR", "CRD", "RES", "ACC", "HP%", "ATK%", "DEF%"))){
+                $stat_name = str_replace("%", "", $rune->innate_stat->stat_name);
+                $stat_value = "+" . $rune->innate_stat->value . "%";
             }
             else{
-                $stat_name = $rune->innate_stat_name;
-                $stat_value = "+" . $rune->innate_stat_value. "&nbsp;";;
+                $stat_name = $rune->innate_stat->stat_name;
+                $stat_value = "+" . $rune->innate_stat->value. "&nbsp;";
             }
             $html .= $stat_name . "\n";
             $html .= "</td>\n";
@@ -266,27 +266,23 @@
             $html .= "<td class='grind'>\n";
             $html .= "</td>\n";
             $html .= "</tr>\n";
-            $substats_name = array($rune->substat_1_name, $rune->substat_2_name, $rune->substat_3_name, $rune->substat_4_name);
-            $substats_value = array($rune->substat_1_value, $rune->substat_2_value, $rune->substat_3_value, $rune->substat_4_value);
-            $substats_grind = array($rune->substat_1_grind, $rune->substat_2_grind, $rune->substat_3_grind, $rune->substat_4_grind);
-            $substats_enchant = array($rune->substat_1_enchant, $rune->substat_2_enchant, $rune->substat_3_enchant, $rune->substat_4_enchant);
             for ($i = 0; $i < 4; $i ++){
-                if (strlen($substats_name[$i]) == 0){
+                if ($rune->substats[$i] == null){
                     $stat_name = "&nbsp;";
                     $stat_value = "";
                 }
-                elseif (in_array($substats_name[$i], array("CRR", "CRD", "RES", "ACC", "HP%", "ATK%", "DEF%"))){
-                    $stat_name = str_replace("%", "", $substats_name[$i]);
-                    $stat_value = "+" . $substats_value[$i] . "%";
+                elseif (in_array($rune->substats[$i]->stat_name, array("CRR", "CRD", "RES", "ACC", "HP%", "ATK%", "DEF%"))){
+                    $stat_name = str_replace("%", "", $rune->substats[$i]->stat_name);
+                    $stat_value = "+" . $rune->substats[$i]->value . "%";
                 }
                 else{
-                    $stat_name = $substats_name[$i];
-                    $stat_value = "+" . $substats_value[$i]. "&nbsp;";
+                    $stat_name = $rune->substats[$i]->stat_name;
+                    $stat_value = "+" . $rune->substats[$i]->value. "&nbsp;";
                 }
                 $grind = "";
-                if ($substats_grind[$i] > 0){
-                    $grind = "+" . $substats_grind[$i];
-                    if (in_array($substats_name[$i], array("CRR", "CRD", "RES", "ACC", "HP%", "ATK%", "DEF%"))){
+                if ($rune->substats[$i] != null && $rune->substats[$i]->grind > 0){
+                    $grind = "+" . $rune->substats[$i]->grind;
+                    if (in_array($rune->substats[$i]->stat_name, array("CRR", "CRD", "RES", "ACC", "HP%", "ATK%", "DEF%"))){
                         $grind = $grind . "%";
                     }
                 }
@@ -298,7 +294,7 @@
                 $html .= $stat_value . "\n";
                 $html .= "<td class='grind grind_$grind'>\n";
                 $html .= $grind . "\n";
-                if ($substats_enchant[$i] == 1){
+                if ($rune->substats[$i] != null && $rune->substats[$i]->enchant == 1){
                     $html .= "<img title='Enchanted' src='" . URL::IMG["RUNE"] . "enchanted.png'/>\n";
                 }
                 $html .= "</td>\n";
@@ -457,26 +453,31 @@
             // Main stat
             $html .= "<tr class='effect main_stat'>\n";
             $html .= "<td class='effect'>\n";
-            $stat_name = $artifact->main_stat_name;
-            $stat_value = "+" . $artifact->main_stat_value;
+            $stat_name = $artifact->stat->name;
+            $stat_value = "+" . $artifact->stat->value;
             $html .= $stat_name . "\n";
             $html .= $stat_value . "\n";
             $html .= "</td>\n";
             $html .= "</tr>\n";
-            $effects = array($artifact->effect_1_description, $artifact->effect_2_description, $artifact->effect_3_description, $artifact->effect_4_description);
+            //$effects = array($artifact->effect_1_description, $artifact->effect_2_description, $artifact->effect_3_description, $artifact->effect_4_description);
             for ($i = 0; $i < 4; $i ++){
                 $html .= "<tr class='effect'>\n";
                 $html .= "<td class='effect'>\n";
-                $name = $effects[$i];
-                $name = str_replace("Increasing", "Inc.", $name);
-                $name = str_replace("Decrease", "Dec.", $name);
-                $name = str_replace("Critical", "Crit.", $name);
-                $name = str_replace("Received ", "", $name);
-                $name = str_replace("Damage", "Dmg.", $name);
-                $name = str_replace("Additional", "Addl.", $name);
-                $name = str_replace("Proportional", "Rel.", $name);
-                $name = str_replace("Counterattack", "Counter", $name);
-                $name = str_replace("Dealt by Attacking Together", "Attacking Together", $name);
+                if (count($artifact->effects) <= $i){
+                    $name = "&nbsp;";
+                }
+                else{
+                    $name = $artifact->effects[$i]->name;
+                    $name = str_replace("Increasing", "Inc.", $name);
+                    $name = str_replace("Decrease", "Dec.", $name);
+                    $name = str_replace("Critical", "Crit.", $name);
+                    $name = str_replace("Received ", "", $name);
+                    $name = str_replace("Damage", "Dmg.", $name);
+                    $name = str_replace("Additional", "Addl.", $name);
+                    $name = str_replace("Proportional", "Rel.", $name);
+                    $name = str_replace("Counterattack", "Counter", $name);
+                    $name = str_replace("Dealt by Attacking Together", "Attacking Together", $name);
+                }
                 $html .= $name;
                 $html .= "</td>\n";
                 $html .= "</tr>\n";
@@ -533,8 +534,8 @@
             $html .= "<img class='enchantment_base' src='" . $base . "'/>\n";
             $html .= $icon;
             $html .= "<span class='enchantment_stat'>\n";
-            $html .= "<span class='enchantment_stat_name'>" . $stat_name . "</span>\n";
-            $html .= "<span class='enchantment_stat_value'>" . $stat_value . "</span>\n";
+            $html .= "<span class='enchantment_stat->stat_name'>" . $stat_name . "</span>\n";
+            $html .= "<span class='enchantment_stat->value'>" . $stat_value . "</span>\n";
             $html .= "</span>\n";
             if ($enchantment->amount > 0){
                 $html .= "<span class='enchantment_amount'>\n";

+ 31 - 72
application/page/Artifacts_Page.php

@@ -49,31 +49,16 @@
             global $db;
             $this->view = PATH::VIEW . "artifacts.php";
             $this->parse_filters();
-            if (!isset($_GET["custom_filter"])){
-                $s = $this->build_query();
-            }
-            else{
-                $s = $this->build_custom_query($_GET["custom_filter"]);
-            }
+            $s = $this->build_query();
             $q = $db->query($s);
             while ($r = $q->fetchArray(SQLITE3_ASSOC)){
                 $artifact = new Artifact($r["id"]);
-                if (strlen($artifact->assigned_to) > 0){
-                    $artifact->assigned_to = new Unit($artifact->assigned_to, false);
+                if ($r["unit"]){
+                    $artifact->unit = new Unit($r["unit"], false);
                 }
                 array_push($this->artifacts, $artifact);
             }
-            $s = "
-              SELECT id
-              FROM filter
-              WHERE
-                uid = '$UID' AND
-                page = 'ARTIFACTS';
-            ";
-            $q = $db->query($s);
-            while ($r = $q->fetchArray(SQLITE3_ASSOC)){
-                array_push($this->custom_filters, new Custom_Filter($r["id"]));
-            }
+    
             $this->title = "Artifacts - SWDB";
             $this->description = "Artifact inventory";
             $this->canonical = URL::BASE . "artifacts/";
@@ -127,65 +112,39 @@
         }
 
         /**
-         * Builds the query to the artifact table using the a custom filter.
+         * Builds the query to the artifact table using the selected or default
+         * filters.
          * 
-         * @param int $filter Custom filter ID.
          * @return string The query to be executed.
          * @global int Player ID.
-         * @global resource Database connection.
          */
-        private function build_custom_query($filter){
+        private function build_query(){
             global $UID;
-            global $db;
-            $s = "
-              SELECT condition
-              FROM filter
-              WHERE
-                uid = '$UID' AND
-                id = $filter;
-            ";
-            $q = $db->query($s);
-            $r = $q->fetchArray(SQLITE3_ASSOC);
-            $cond = $r["condition"];
+            global $MODE;
             $s = "
               SELECT
                 id,
-                assigned_to
+                (
+                  SELECT DISTINCT unit
+                  FROM unit_artifact
+                  WHERE
+                    artifact = artifact.id AND
+                    rta = $MODE
+                ) AS unit
               FROM artifact
-              WHERE uid = '$UID' AND (
-                $cond
-              )
-              ORDER BY slot, type, stars DESC, original_quality DESC, quality DESC, level;
+              WHERE
+                uid = '$UID' AND
+                level >= " . $this->filters["MIN_LEVEL"] . " AND 
+                level <= " . $this->filters["MAX_LEVEL"] . " AND
+                quality >= " . $this->filters["MIN_QUALITY"] . " AND
+                quality <= " . $this->filters["MAX_QUALITY"] . " AND
+                original_quality >= " . $this->filters["MIN_ORIGINAL_QUALITY"] . " AND
+                original_quality <= " . $this->filters["MAX_ORIGINAL_QUALITY"] . " AND
+                efficiency >= " . $this->filters["MIN_EFFICIENCY"] . " AND
+                efficiency <= " . $this->filters["MAX_EFFICIENCY"] . " AND
+                max_efficiency >= " . $this->filters["MIN_MAX_EFFICIENCY"] . " AND
+                max_efficiency <= " . $this->filters["MAX_MAX_EFFICIENCY"] . "
             ";
-            return $s;
-        }
-
-        /**
-         * Builds the query to the artifact table using the selected or default
-         * filters.
-         * 
-         * @return string The query to be executed.
-         * @global int Player ID.
-         */
-        private function build_query(){
-            global $UID;
-            $s =
-              "SELECT " .
-              "  id, " .
-              "  assigned_to " .
-              "FROM artifact " .
-              "WHERE " .
-              "  uid = '$UID' AND " .
-              "  level >= " . $this->filters["MIN_LEVEL"] . " AND " .
-              "  level <= " . $this->filters["MAX_LEVEL"] . " AND " .
-              "  quality >= " . $this->filters["MIN_QUALITY"] . " AND " .
-              "  quality <= " . $this->filters["MAX_QUALITY"] . " AND " .
-              "  original_quality >= " . $this->filters["MIN_ORIGINAL_QUALITY"] . " AND " .
-              "  original_quality <= " . $this->filters["MAX_ORIGINAL_QUALITY"] . " AND " .
-              "  efficiency >= " . $this->filters["MIN_EFFICIENCY"] . " AND " .
-              "  efficiency <= " . $this->filters["MAX_EFFICIENCY"] . " AND " .
-              "  max_efficiency >= " . $this->filters["MIN_MAX_EFFICIENCY"] . " AND " .
-              "  max_efficiency <= " . $this->filters["MAX_MAX_EFFICIENCY"] . " ";
             if (count($this->filters["MAIN"]) > 0){
                 $s = $s . " AND main_stat IN ( ";
                 foreach($this->filters["MAIN"] as $t){
@@ -226,16 +185,16 @@
             }
             switch ($this->filters["ASSIGNED"]){
                 case 1:
-                    $s = $s . " AND assigned_to IS NOT NULL ";
+                    $s = $s . " AND unit IS NOT NULL ";
                     break;
                 case 2:
-                    $s = $s . " AND assigned_to IS NULL ";
+                    $s = $s . " AND unit IS NULL ";
                     break;
                 case 3:
-                    $s = $s . " AND (assigned_to IS NULL OR assigned_to IN (SELECT DISTINCT id FROM unit WHERE building <> " . BUILDING_ID::MONSTER_STORAGE . ")) ";
+                    $s = $s . " AND (unit IS NULL OR unit IN (SELECT DISTINCT id FROM unit WHERE building <> " . BUILDING_ID::MONSTER_STORAGE . ")) ";
                     break;
                 case 4:
-                    $s = $s . " AND assigned_to IN (SELECT DISTINCT id FROM unit WHERE building <> " . BUILDING_ID::MONSTER_STORAGE . ") ";
+                    $s = $s . " AND unit IN (SELECT DISTINCT id FROM unit WHERE building <> " . BUILDING_ID::MONSTER_STORAGE . ") ";
                     break;
             }
             $s = $s . " ORDER BY type, attribute, archetype, level DESC, original_quality DESC;";

+ 1 - 1
application/page/Monster_Page.php

@@ -35,7 +35,7 @@
          */
         public function __construct($id){
             $this->view = PATH::VIEW . "monster.php";
-            $this->unit = new Unit($id);
+            $this->unit = new Unit($id, true);
             $this->title = $this->unit->unit->name ." - SWDB";
             $this->description = "Owned " . $this->unit->unit->name;
             $this->canonical = URL::BASE . "monster/" . $id;

+ 2 - 2
application/page/Monsters_Page.php

@@ -141,7 +141,7 @@
                 $s = $s . " AND building NOT IN (SELECT id FROM building WHERE building = " . BUILDING_ID::MONSTER_STORAGE . ") ";
             }
             if (!$this->filters["WITHOUT_RUNES"]){
-                $s = $s . " AND unit.id IN (SELECT DISTINCT assigned_to FROM rune) ";
+                $s = $s . " AND unit.id IN (SELECT DISTINCT unit FROM unit_rune) ";
             }
             if (sizeof($this->filters["EFFECT"]) > 0){
                 if ($this->filters["EFFECT_OPTION"] == "and"){
@@ -178,7 +178,7 @@
                 }
             }
             $s = $s . "
-                ORDER BY 
+                ORDER BY
                   stars DESC,
                   level DESC,
                   element = " . ELEMENT_ID::FIRE ." DESC,

+ 133 - 119
application/page/Report_Rune_Enchantment_Page.php

@@ -251,149 +251,163 @@
          */
         private function build_query(){
             global $UID;
+            global $MODE;
+
             $s = "
-                SELECT
-                  unit.id AS unit,
-                  rune.id AS rune,
-                  enchantment.id AS enchantment
-                FROM
-                  unit,
-                  k_unit,
-                  rune,
-                  enchantment,
-                  k_enchantment_type
-                WHERE
-                  unit.uid = '$UID' AND
-                  rune.uid = '$UID' AND
-                  enchantment.uid = '$UID' AND
-                  unit.id = rune.assigned_to AND
-                  unit.unit = k_unit.id AND
-                  enchantment.type = k_enchantment_type.id AND
-                  unit.stars >= " . $this->filters["RUNE_MIN_STARS"] . " AND
-                  unit.stars <= " . $this->filters["RUNE_MAX_STARS"] . " AND
-                  -- RUNE FILTERS
-                  rune.quality >= " . $this->filters["RUNE_MIN_QUALITY"] . " AND
-                  rune.quality <= " . $this->filters["RUNE_MAX_QUALITY"] . " AND
-                  rune.level >= " . $this->filters["RUNE_MIN_LEVEL"] . " AND
-                  rune.level <= " . $this->filters["RUNE_MAX_LEVEL"] . " AND
-                  rune.stars >= " . $this->filters["RUNE_MIN_STARS"] . " AND
-                  rune.stars <= " . $this->filters["RUNE_MAX_STARS"] . " AND
-                  rune.original_quality >= " . $this->filters["RUNE_MIN_ORIGINAL_QUALITY"] . " AND
-                  rune.original_quality <= " . $this->filters["RUNE_MAX_ORIGINAL_QUALITY"] . " AND
-                  rune.efficiency >= " . $this->filters["RUNE_MIN_EFFICIENCY"] . " AND
-                  rune.efficiency <= " . $this->filters["RUNE_MAX_EFFICIENCY"] . " AND
-                  rune.max_efficiency >= " . $this->filters["RUNE_MIN_MAX_EFFICIENCY"] . " AND
-                  rune.max_efficiency <= " . $this->filters["RUNE_MAX_MAX_EFFICIENCY"] . " AND
-                  (
-                    rune.type = enchantment.rune OR 
-                    k_enchantment_type.inmemorial = 1
-                  ) AND
-                  k_enchantment_type.ancient = rune.ancient AND
-                ";
+              SELECT DISTINCT
+                unit.id AS unit,
+                rune.id AS rune,
+                enchantment.id AS enchantment
+              FROM
+                unit,
+                k_unit,
+                rune,
+                unit_rune,
+                enchantment,
+                k_enchantment_type
+              WHERE 
+                unit.uid = '$UID'
+                AND rune.uid = '$UID'
+                AND enchantment.uid = '$UID'
+                AND unit.id = unit_rune.unit
+                AND rune.id = unit_rune.rune
+                AND unit_rune.rta = $MODE
+                AND unit.unit = k_unit.id
+                AND enchantment.type = k_enchantment_type.id
+                -- RUNE FILTERS
+                AND unit.stars >= " . $this->filters["RUNE_MIN_STARS"] . "
+                AND unit.stars <= " . $this->filters["RUNE_MAX_STARS"] . "
+                AND rune.quality >= " . $this->filters["RUNE_MIN_QUALITY"] . "
+                AND rune.quality <= " . $this->filters["RUNE_MAX_QUALITY"] . "
+                AND rune.level >= " . $this->filters["RUNE_MIN_LEVEL"] . "
+                AND rune.level <= " . $this->filters["RUNE_MAX_LEVEL"] . "
+                AND rune.stars >= " . $this->filters["RUNE_MIN_STARS"] . "
+                AND rune.stars <= " . $this->filters["RUNE_MAX_STARS"] . "
+                AND rune.original_quality >= " . $this->filters["RUNE_MIN_ORIGINAL_QUALITY"] . "
+                AND rune.original_quality <= " . $this->filters["RUNE_MAX_ORIGINAL_QUALITY"] . "
+                AND rune.efficiency >= " . $this->filters["RUNE_MIN_EFFICIENCY"] . "
+                AND rune.efficiency <= " . $this->filters["RUNE_MAX_EFFICIENCY"] . "
+                AND rune.max_efficiency >= " . $this->filters["RUNE_MIN_MAX_EFFICIENCY"] . "
+                AND rune.max_efficiency <= " . $this->filters["RUNE_MAX_MAX_EFFICIENCY"] . "
+                AND (
+                  rune.type = enchantment.rune
+                  OR k_enchantment_type.inmemorial = 1
+                )
+                AND k_enchantment_type.ancient = rune.ancient
+            ";
+
+            // Monster name
+            $cond = "";
             if (strlen($this->filters["MONSTER_NAME"]) > 0){
-                $s = $s . " upper(k_unit.name) LIKE upper('%" . $this->filters["MONSTER_NAME"] . "%') AND ";
+                $cond = "AND upper(k_unit.name) LIKE upper('%" . $this->filters["MONSTER_NAME"] . "%') ";
             }
+            $s .= $cond . " -- MONSTER NAME \n";
+
+            // Monsters in storage
+            $cond = "";
             if (!$this->filters["MONSTER_IN_STORAGE"]){
-                $s = $s . " unit.building <> " . BUILDING_ID::MONSTER_STORAGE . " AND ";
+                $cond = "AND unit.building <> " . BUILDING_ID::MONSTER_STORAGE . " ";
             }
+            $s .= $cond . " -- STORAGE \n";
+
+            // Rune slot
+            $cond = "";
             if (count($this->filters["RUNE_SLOT"]) > 0){
-                $s = $s . " rune.slot IN ( ";
+                $in = "(";
                 foreach($this->filters["RUNE_SLOT"] as $t){
-                    $s = $s . "$t, ";
+                    $in .= "$t, ";
                 }
-                $s = $s . "-1) AND ";
+                $in = rtrim($in, ", ") . ")";
+                $cond = "AND rune.slot IN $in";
             }
+            $s .= $cond . " -- RUNE SLOT \n";
+
+            // Nevermind the type, discard enchantments with the same stat as
+            // the main or inate substat
+            $s .= "
+              AND enchantment.stat NOT IN (
+                SELECT stat
+                FROM rune_stat
+                WHERE
+                  rune_stat.rune = rune.id
+                  AND (
+                    rune_stat.slot = " . RUNE_STAT_SLOT_ID::MAIN . "
+                    OR rune_stat.slot = " . RUNE_STAT_SLOT_ID::INNATE . "
+                  )
+              )
+            ";
+
+            // Begin type switch block
+            $s .= " AND ( -- TYPE SWITCH \n";
+
+            // Begin grindstone block
             $s .= "
-                enchantment.stat <> rune.main_stat AND
-                enchantment.stat <> rune.innate_stat AND
-                  (
-                    k_enchantment_type.gem = 1 AND
-                    (
-                      -- GEM FILTERS
-                      enchantment.quality >= " . $this->filters["GEM_MIN_QUALITY"] . " AND
+              (
+                k_enchantment_type.gem = 0
+                AND enchantment.stat IN (SELECT stat FROM rune_stat WHERE rune_stat.rune = rune.id)
+                AND enchantment.quality >= " . $this->filters["GRIND_MIN_QUALITY"] . " -- GRINDSTONE QUALITY
             ";
-            if (count($this->filters["GEM_STAT_FROM"]) > 0){
+
+            // Grindstone stat
+            $cond = "";
+            if (count($this->filters["GRIND_STAT"]) > 0){
                 $in = "(";
-                foreach($this->filters["GEM_STAT_FROM"] as $t){
-                    $in = $in . "$t, ";
+                foreach($this->filters["GRIND_STAT"] as $t){
+                    $in .= "$t, ";
                 }
-                $in = $in . "-1)";
-                $s .= " (rune.substat_1 IN $in OR rune.substat_2 IN $in OR rune.substat_3 IN $in OR rune.substat_4 IN $in) AND ";
+                $in = rtrim($in, ", ") . ")";
+                $cond = "AND enchantment.stat IN $in";
             }
+            $s .= $cond . " -- GRINDSTONE STAT \n";
+            $s .= "
+              )\n
+            ";
+
+            // Begin gem block
+            $s .= " OR (
+              k_enchantment_type.gem = 1
+              AND enchantment.stat NOT IN (SELECT stat FROM rune_stat WHERE rune_stat.rune = rune.id)
+              AND enchantment.quality >= " . $this->filters["GEM_MIN_QUALITY"] . " -- GEM QUALITY
+            ";
+
+            // Gem stat to
+            $cond = "";
             if (count($this->filters["GEM_STAT_TO"]) > 0){
                 $in = "(";
                 foreach($this->filters["GEM_STAT_TO"] as $t){
-                    $in = $in . "$t, ";
+                    $in .= "$t, ";
                 }
-                $in = $in . "-1)";
-                $s .= " enchantment.stat IN $in AND ";
+                $in = rtrim($in, ", ") . ")";
+                $cond = "AND enchantment.stat IN $in";
             }
-            $s .= "
-                      (
-                        enchantment.stat <> rune.substat_1 AND
-                        enchantment.stat <> rune.substat_2 AND
-                        enchantment.stat <> rune.substat_3 AND
-                        enchantment.stat <> rune.substat_4
-                      )
-                    )
-                  ) |
-                  (
-                    k_enchantment_type.gem = 0 AND
-                    (
-                      -- GRINDSTONE FILTERS
-            ";
-            if (count($this->filters["GRIND_STAT"]) > 0){
+            $s .= $cond . " -- GEM STAT TO \n";
+
+            // Gem stat from
+            $cond = "";
+            if (count($this->filters["GEM_STAT_FROM"]) > 0){
                 $in = "(";
-                foreach($this->filters["GRIND_STAT"] as $t){
-                    $in = $in . "$t, ";
+                foreach($this->filters["GEM_STAT_FROM"] as $t){
+                    $in .= "$t, ";
                 }
-                $in = $in . "-1)";
-                $s .= " enchantment.stat IN $in AND ";
-            }
-            $s .= "
-                      enchantment.quality >= " . $this->filters["GRIND_MIN_QUALITY"] . " AND
-                      (
-                        (
-                          enchantment.stat = rune.substat_1 AND
-                          enchantment.stat <> rune.substat_2 AND
-                          enchantment.stat <> rune.substat_3 AND
-                          enchantment.stat <> rune.substat_4 
-                        ) OR
-                        (
-                          enchantment.stat <> rune.substat_1 AND
-                          enchantment.stat = rune.substat_2 AND
-                          enchantment.stat <> rune.substat_3 AND
-                          enchantment.stat <> rune.substat_4
-                        ) OR
-                        (
-                          enchantment.stat <> rune.substat_1 AND
-                          enchantment.stat <> rune.substat_2 AND
-                          enchantment.stat = rune.substat_3 AND
-                          enchantment.stat <> rune.substat_4
-                        ) OR
-                        (
-                          enchantment.stat <> rune.substat_1 AND
-                          enchantment.stat <> rune.substat_2 AND
-                          enchantment.stat <> rune.substat_3 AND
-                          enchantment.stat = rune.substat_4
-                        )
-                      )
-                    )
+                $in = rtrim($in, ", ") . ")";
+                $cond = "
+                  AND rune.id IN(
+                    SELECT DISTINCT rune
+                    FROM rune_stat
+                    WHERE
+                      rune_stat.rune = rune.id
+                      AND stat IN $in
                   )
                 ";
+            }
+            $s .= $cond . " -- GEM STAT FROM \n";
             $s .= "
-                ORDER BY
-                  unit.stars DESC,
-                  unit.level DESC,
-                  unit.id,
-                  rune.stars DESC,
-                  rune.original_quality DESC,
-                  rune.level DESC,
-                  rune.id, 
-                  rune.slot, 
-                  enchantment.quality DESC,
-                  enchantment.stat DESC;
-                ";
+              )\n
+            ";
+
+            // End type switch block
+            $s .= " ) -- END TYPE SWITCH \n";
+
             return $s;
         }
     }

+ 4 - 2
application/page/Report_Skillup_Page.php

@@ -69,7 +69,7 @@
          * and adds them to the $filters array.
          */
         private function parse_filters(){
-            //$this->filters = FILTER::SKILLUP;
+
             if (isset($_GET["min_stars"]) && intval($_GET["min_stars"]) > 0 && intval($_GET["min_stars"]) < 7){
                 $this->filters["MIN_STARS"] = intval($_GET["min_stars"]);
             }
@@ -124,9 +124,11 @@
          *
          * @return string The query to be executed.
          * @global int Player ID.
+         * @global int Game mode.
          */
         private function build_query(){
             global $UID;
+            global $MODE;
             $s = "
               SELECT DISTINCT
                 unit.id AS id,
@@ -247,7 +249,7 @@
                 $s = $s . " AND unit.building <> " . BUILDING_ID::MONSTER_STORAGE;
             }
             if (!$this->filters["WITHOUT_RUNES"]){
-                $s = $s . " AND unit.id IN (SELECT DISTINCT assigned_to FROM rune) ";
+                $s = $s . " AND unit.id IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = $MODE) ";
             }
             if (!$this->filters["FAMILY"]){
                 $s = $s . " AND unit.unit NOT IN (SELECT id FROM k_unit m WHERE family IN (SELECT family FROM k_unit k WHERE k.family = m.family AND k.natural_stars < m.natural_stars AND k.natural_stars < " . $this->filters["MIN_NATURAL_STARS"] . ")) ";

+ 38 - 32
application/page/Runes_Page.php

@@ -68,27 +68,16 @@
             global $db;
             $this->view = PATH::VIEW . "runes.php";
             $this->parse_filters();
-                $s = $this->build_query();
-                $this->filters["GROUP"] = 1;
+            $s = $this->build_query();
+            $this->filters["GROUP"] = 1;
             $q = $db->query($s);
             while ($r = $q->fetchArray(SQLITE3_ASSOC)){
                 $rune = new Rune($r["id"]);
-                if (strlen($rune->assigned_to) > 0){
-                    $rune->assigned_to = new Unit($rune->assigned_to, false);
+                if ($r["unit"]){
+                    $rune->unit = new Unit($r["unit"], false);
                 }
                 array_push($this->runes, $rune);
             }
-            $s = "
-              SELECT id
-              FROM filter
-              WHERE
-                uid = '$UID' AND
-                page = 'RUNES';
-            ";
-            $q = $db->query($s);
-            while ($r = $q->fetchArray(SQLITE3_ASSOC)){
-                array_push($this->custom_filters, new Custom_Filter($r["id"]));
-            }
             $this->title = "Runes - SWDB";
             $this->description = "Rune inventory";
             $this->canonical = URL::BASE . "runes/";
@@ -178,11 +167,19 @@
          */
         private function build_query(){
             global $UID;
+            global $MODE;
             $s = "
               SELECT
                 id,
-                assigned_to
-              FROM rune
+                (
+                  SELECT DISTINCT unit
+                  FROM unit_rune
+                  WHERE
+                    rune = rune.id AND
+                    rta = $MODE
+                ) AS unit
+              FROM
+                rune
               WHERE
                 uid = '$UID' AND
                 stars >= " . $this->filters["MIN_STARS"] . " AND
@@ -199,11 +196,20 @@
                 max_efficiency <= " . $this->filters["MAX_MAX_EFFICIENCY"] . "
             ";
             if (count($this->filters["MAIN"]) > 0){
-                $s = $s . " AND main_stat IN ( ";
+                $values = "(";
                 foreach($this->filters["MAIN"] as $t){
-                    $s = $s . "'$t', ";
+                    $values = $values . "'$t', ";
                 }
-                $s = $s . "'DUMMY0') ";
+                $values = $values . "'DUMMY0') ";
+                $s .= "
+                  AND id IN (
+                    SELECT rune
+                    FROM rune_stat
+                    WHERE
+                      slot = " . RUNE_STAT_SLOT_ID::MAIN . " AND
+                      stat IN $values
+                  )
+                ";
             }
             if (count($this->filters["SUB"]) > 0){
                 $values = "(";
@@ -211,13 +217,13 @@
                     $values = $values . "'$t', ";
                 }
                 $values = $values . "'DUMMY0') ";
-                $s = $s . "
-                  AND ( 
-                    innate_stat IN $values OR
-                    substat_1 IN $values OR
-                    substat_2 IN $values OR
-                    substat_3 IN $values OR
-                    substat_4 IN $values
+                $s .= "
+                  AND id IN (
+                    SELECT rune
+                    FROM rune_stat
+                    WHERE
+                      slot != " . RUNE_STAT_SLOT_ID::MAIN . " AND
+                      stat IN $values
                   )
                 ";
             }
@@ -237,16 +243,16 @@
             }
             switch ($this->filters["ASSIGNED"]){
                 case 1:
-                    $s = $s . " AND assigned_to IS NOT NULL ";
+                    $s = $s . " AND unit IS NOT NULL ";
                     break;
                 case 2:
-                    $s = $s . " AND assigned_to IS NULL ";
+                    $s = $s . " AND unit IS NULL ";
                     break;
                 case 3:
-                    $s = $s . " AND (assigned_to IS NULL OR assigned_to IN (SELECT DISTINCT id FROM unit WHERE building <> " . BUILDING_ID::MONSTER_STORAGE . ")) ";
+                    $s = $s . " AND (unit IS NULL OR unit IN (SELECT DISTINCT id FROM unit WHERE building <> " . BUILDING_ID::MONSTER_STORAGE . ")) ";
                     break;
                 case 4:
-                    $s = $s . " AND assigned_to IN (SELECT DISTINCT id FROM unit WHERE building <> " . BUILDING_ID::MONSTER_STORAGE . ") ";
+                    $s = $s . " AND unit IN (SELECT DISTINCT id FROM unit WHERE building <> " . BUILDING_ID::MONSTER_STORAGE . ") ";
                     break;
             }
             $s = $s . " ORDER BY ";
@@ -254,7 +260,7 @@
                 $s = $s . " type, slot, stars DESC, original_quality DESC, quality DESC, level;";
             }
             else{
-                $s = $s . " slot, type, stars DESC, original_quality DESC, quality DESC, level, main_stat;";
+                $s = $s . " slot, type, stars DESC, original_quality DESC, quality DESC, level;";
             }
             return $s;
         }

二进制
application/sw.sqlite


+ 8 - 1
application/view/artifacts.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>artifacts.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>
@@ -298,7 +305,7 @@
 <?php
                         }
 ?>
-                        <?=HTML::artifact_table($artifact, $artifact->assigned_to)?>
+                        <?=HTML::artifact_table($artifact, $artifact->unit)?>
 <?php
                     }
 ?>

+ 7 - 0
application/view/catalog.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>catalog.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/enchantments.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>enchantments.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/error.php

@@ -17,6 +17,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>error.css'/>
         <!-- Meta tags -->
         <meta name='robots' content='noindex nofollow'/>

+ 7 - 0
application/view/fusion.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>fusion.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/guild.php

@@ -17,6 +17,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>guild.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/help.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>help.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/home.php

@@ -19,6 +19,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>home.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 127 - 53
application/view/inc/header.php

@@ -9,64 +9,138 @@
 
     /** @var int $UID User id. */
 ?>
+<script>
+    function setMode(rta){
+        if (rta === true){
+            mode = <?=GAME_MODE_ID::RTA?>;
+        }
+        else if (rta === false){
+            mode = <?=GAME_MODE_ID::NORMAL?>;
+        }
+        else{
+            return false;
+        }
+        params = '?uid=<?=$UID?>&mode=' + mode;
+        var xhttp = new XMLHttpRequest();
+        xhttp.onreadystatechange = function() {
+            if (this.readyState == 4){
+                if (this.status == 201){
+                    window.location.reload(false);
+                }
+            }
+        };
+        xhttp.open('GET', '/action/change_game_mode/' + params, true);
+        xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+        xhttp.send();
+        return true;
+    }
+</script>
 <header>
-    <div id='logo'>
-        <img id='logo_img' src='<?=URL::IMG["LOGO"]?>sw.png' alt=''/>
-        <h1 id='logo_text'>
-            <span class='large'>D</span>
-            <span class='small'>ata</span>
-            <span class='large'>B</span>
-            <span class='small'>ase</span>
-        </h1>
-    </div>
 <?php
     if ($_SESSION['session'] == true){
 ?>
         <nav id='menu'>
-            <a href='/<?=$UID?>/'>
-                Home
-            </a>
-            <a href='/<?=$UID?>/catalog/'>
-                Catalog
-            </a>
-            <a href='/<?=$UID?>/monsters/'>
-                Monsters
-            </a>
-            <a href='/<?=$UID?>/runes/'>
-                Runes
-            </a>
-            <a href='/<?=$UID?>/enchantments/'>
-                Enchantments
-            </a>
-            <a href='/<?=$UID?>/artifacts/'>
-                Artifacts
-            </a>
-            <a href='/<?=$UID?>/fusion/'>
-                Fusion
-            </a>
-            <a href='/<?=$UID?>/guild/'>
-                Guild
-            </a>
-            <a href='/<?=$UID?>/runs/'>
-                Runs
-            </a>
-            <a href='/<?=$UID?>/stats/'>
-                Stats
-            </a>
-            <a href='/<?=$UID?>/teams/'>
-                Teams
-            </a>
-            <a href='/<?=$UID?>/report/'>
-                Reports
-            </a>
-            <a href='/<?=$UID?>/optimizer/'>
-                Optimizer
-            </a>
-        </nav>
-        <nav id='profile'>
-            <a href='/<?=$UID?>/profile/'>
-                <?=$_SESSION['name']?>
-            </a>
+            <table>
+                <tr>
+                    <td rowspan='2'>
+                        <div id='logo'>
+                            <img id='logo_img' src='<?=URL::IMG["LOGO"]?>sw.png' alt=''/>
+                            <h1 id='logo_text'>
+                                <span class='large'>D</span>
+                                <span class='small'>ata</span>
+                                <span class='large'>B</span>
+                                <span class='small'>ase</span>
+                            </h1>
+                        </div>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/'>
+                            Home
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/monsters/'>
+                            Monsters
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/runes/'>
+                            Runes
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/artifacts/'>
+                            Artifacts
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/enchantments/'>
+                            Enchantments
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/teams/'>
+                            Teams
+                        </a>
+                    </td>
+                    <td class='last profile'>
+                        <a href='/<?=$UID?>/profile/'>
+                            <?=$_SESSION['name']?>
+                        </a>
+                    </td>
+                </tr>
+                <tr>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/catalog/'>
+                            Catalog
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/fusion/'>
+                            Fusion
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/guild/'>
+                            Guild
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/runs/'>
+                            Runs
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/report/'>
+                            Reports
+                        </a>
+                    </td>
+                    <td class='item'>
+                        <a href='/<?=$UID?>/optimizer/'>
+                            Optimizer
+                        </a>
+                    </td>
+                    <!--<td class='item'>
+                        <a href='/<?=$UID?>/stats/'>
+                            Stats
+                        </a>
+                    </td>-->
+                    <td class='last mode'>
+                        <div id='mode_switch'>
+                            <span class='mode'>
+                                N<span class='desktop'>ormal</span>
+                            </span>
+                            <label class='switch'>
+                                <input type="checkbox" <?=($MODE == GAME_MODE_ID::RTA ? "checked='cheecked'" : "")?> onChange='setMode(this.checked);'/>
+                                <span class="slider round"></span>
+                            </label>
+                            <span class='mode'>
+                                R<span class='desktop'>TA</span>
+                            </span>
+                        </div>
+                    </td>
+                </tr>
+            </table>
         </nav>
 <?php
     }

+ 7 - 1
application/view/monster.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>monster.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>
@@ -364,7 +371,6 @@
                     $total_value = 0;
                     $total_runes = 0;
                     $show_list = [6, 1, 2, 5, 4, 3];
-                    //foreach ($page->unit->rune as $rune){
                     foreach ($show_list as $i){
                         $rune = $page->unit->rune[$i - 1];
                         $total_efficiency += $rune->efficiency;

+ 7 - 0
application/view/monster_info.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>monster_info.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/monsters.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>monsters.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/optimizer.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>optimizer.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 12 - 1
application/view/optimizer_unit.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>optimizer.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>
@@ -426,6 +433,7 @@
                             break;
                     }
                 }
+                set_stats['hp'] = Math.floor(set_stats['hp']);
 
                 // Send the request
                 var xhttp = new XMLHttpRequest();
@@ -446,7 +454,7 @@
                 };
 
                 // DEBUG
-                //params = 'uid=8114048&unit=6441802832&limit=6&set[]=2&set[]=4&set[]=4&stat[]=4&stat[]=4&stat[]=4&source=0&tuning=2&min_defense=800';
+                //params = 'uid=8114048&unit=6441802832&limit=6&set[]=1&set[]=1&set[]=1&stat[]=2&stat[]=2&stat[]=2&source=0&tuning=2&min_defense=800';
 
 
                 // Clear result table, disable button and show spinner
@@ -570,6 +578,9 @@
                     new_stats["ACC"] += candidates[i].ACC;
                     new_stats["RES"] += candidates[i].RES;
                 }
+                new_stats["HP"] = Math.floor(new_stats["HP"]);
+                //console.log("CANDIDATES NEW HP: " + new_stats["HP"]);
+                
                 new_stats["EHP"] = Math.ceil((((new_stats["DEF"] * 3.5) + 1140) * new_stats["HP"]) / 1000);
                 new_stats["DMG"] = Math.ceil((new_stats["ATK"] * (100 - new_stats["CRR"]) / 100) + ((new_stats["ATK"] + (new_stats["ATK"] * new_stats["CRD"] / 100)) * new_stats["CRR"] / 100));
                 if (

+ 7 - 0
application/view/profile.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>profile.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/report.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>report.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/report_rune_enchantment.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>report_rune_enchantment.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/report_skillup.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>report_skillup.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 9 - 2
application/view/runes.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>runes.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>
@@ -262,7 +269,7 @@
 <?php
                                         if (($i + 1) % 2 == 0){
 ?>
-                                            </select><select multiple name='main_stat[]' class='select_sub' id='filter_sub_stat_<?=$j?>' onMouseDown='fixSubSelect(<?=$j?>, event);'>
+                                            </select><select multiple name='sub_stat[]' class='select_sub' id='filter_sub_stat_<?=$j?>' onMouseDown='fixSubSelect(<?=$j?>, event);'>
 <?php
                                             $j ++;
                                         }
@@ -419,7 +426,7 @@
 <?php
                         }
 ?>
-                        <?=HTML::rune_table($rune, $rune->assigned_to)?>
+                        <?=HTML::rune_table($rune, $rune->unit)?>
 <?php
                     }
 ?>

+ 7 - 0
application/view/runs.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>runs.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/stats.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>stats.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
application/view/teams.php

@@ -18,6 +18,13 @@
         <link rel='shortcut icon' href='<?=$page->favicon?>'/>
         <!-- CSS files -->
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
+<?php
+        if ($MODE == GAME_MODE_ID::RTA){
+?>
+            <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
+<?php
+        }
+?>
         <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>teams.css'/>
         <!-- Meta tags -->
         <link rel='canonical' href='<?=$page->canonical?>'/>

+ 7 - 0
install_data/install_base.sql

@@ -617,6 +617,13 @@ INSERT INTO k_quality VALUES(2,'Magic');
 INSERT INTO k_quality VALUES(3,'Rare');
 INSERT INTO k_quality VALUES(4,'Hero');
 INSERT INTO k_quality VALUES(5,'Legend');
+CREATE TABLE k_artifact_stat(
+    id INT NOT NULL PRIMARY KEY,
+    name TEXT UNIQUE
+);
+INSERT INTO k_artifact_stat VALUES(100,'HP');
+INSERT INTO k_artifact_stat VALUES(101,'ATK');
+INSERT INTO k_artifact_stat VALUES(102,'DEF');
 CREATE TABLE k_artifact_effect(
     id INT NOT NULL PRIMARY KEY,
     name TEXT UNIQUE

+ 40 - 41
install_data/install_data.sql

@@ -39,7 +39,8 @@ CREATE TABLE player(
     top_rank_wboss INT DEFAULT 0,
     top_rank_toan INT DEFAULT 0,
     top_rank_toah INT DEFAULT 0,
-    public INT NOT NULL DEFAULT 0 CHECK(public IN (0, 1))
+    public INT NOT NULL DEFAULT 0 CHECK(public IN (0, 1)),
+    mode INT NOT NULL CHECK(mode IN (0, 1)) DEFAULT 0
 );
 CREATE TABLE record(
     uid INT NOT NULL REFERENCES player(id),
@@ -118,7 +119,6 @@ CREATE TABLE unit_skill(
 CREATE TABLE rune(
     uid INT NOT NULL REFERENCES player(id),
     id INT PRIMARY KEY NOT NULL,
-    assigned_to INT REFERENCES unit(id),
     type INT REFERENCES k_rune_set(id),
     slot INT NOT NULL CHECK(slot BETWEEN 1 AND 6),
     stars INT NOT NULL CHECK(stars BETWEEN 1 AND 6),
@@ -129,32 +129,27 @@ CREATE TABLE rune(
     value INT NOT NULL CHECK(value > 0),
     efficiency FLOAT NOT NULL CHECK(efficiency BETWEEN 0 AND 100),
     max_efficiency FLOAT NOT NULL CHECK(max_efficiency BETWEEN 0 AND 100),
-    main_stat INT NOT NULL REFERENCES k_rune_stat(id),
-    main_stat_value INT NOT NULL CHECK(main_stat_value > 0),
-    innate_stat INT REFERENCES k_rune_stat(id),
-    innate_stat_value INT CHECK(innate_stat_value >= 0),
-    substat_1 INT REFERENCES k_rune_stat(id),
-    substat_1_value INT CHECK(substat_1_value >= 0),
-    substat_1_enchant INT CHECK(substat_1_enchant IN (0, 1)),
-    substat_1_grind INT CHECK(substat_1_grind >= 0),
-    substat_2 INT REFERENCES k_rune_stat(id),
-    substat_2_value INT CHECK(substat_2_value >= 0),
-    substat_2_enchant INT CHECK(substat_2_enchant IN (0, 1)),
-    substat_2_grind INT CHECK(substat_2_grind >= 0),
-    substat_3 INT REFERENCES k_rune_stat(id),
-    substat_3_value INT CHECK(substat_3_value >= 0),
-    substat_3_enchant INT CHECK(substat_3_enchant IN (0, 1)),
-    substat_3_grind INT CHECK(substat_3_grind >= 0),
-    substat_4 INT REFERENCES k_rune_stat(id),
-    substat_4_value INT CHECK(substat_4_value >= 0),
-    substat_4_enchant INT CHECK(substat_4_enchant IN (0, 1)),
-    substat_4_grind INT CHECK(substat_4_grind >= 0),
     locked INT NOT NULL CHECK(locked IN (0, 1))
 );
+CREATE TABLE rune_stat(
+    rune INT NOT NULL references rune(id),
+    slot INT NOT NULL CHECK(slot BETWEEN -1 AND 4),
+    stat INT NOT NULL REFERENCES k_rune_stat(id),
+    value INT NOT NULL CHECK(value >= 0),
+    enchant INT NOT NULL CHECK(enchant IN (0, 1)),
+    grind INT NOT NULL CHECK(grind >= 0),
+    rolls INT NOT NULL CHECK(rolls BETWEEN 0 AND 4),
+    PRIMARY KEY (rune, slot)
+);
+CREATE TABLE unit_rune(
+    unit INT NOT NULL REFERENCES unit(id),
+    rune INT NOT NULL REFERENCES rune(id),
+    rta INT NOT NULL DEFAULT 0 CHECK(rta IN (0, 1)),
+    PRIMARY KEY(unit, rune, rta)
+);
 CREATE TABLE artifact(
     uid INT NOT NULL REFERENCES player(id),
     id INT PRIMARY KEY NOT NULL,
-    assigned_to INT REFERENCES unit(id),
     type INT REFERENCES k_archetype(id),
     attribute INT REFERENCES k_element(id),
     archetype INT REFERENCES k_archetype(id),
@@ -164,26 +159,30 @@ CREATE TABLE artifact(
     value INT NOT NULL CHECK(value >= 0),
     efficiency FLOAT NOT NULL CHECK(efficiency BETWEEN 0 AND 100),
     max_efficiency FLOAT NOT NULL CHECK(max_efficiency BETWEEN 0 AND 100),
-    main_stat INT NOT NULL REFERENCES k_stat(id),
-    main_stat_value INT NOT NULL CHECK(main_stat_value > 0),
-    effect_1 INT REFERENCES k_artiffact_effect(id),
-    effect_1_value INT CHECK(effect_1_value >= 0),
-    effect_1_enchant INT,
-    effect_1_grind INT,
-    effect_2 INT REFERENCES k_artiffact_effect(id),
-    effect_2_value INT CHECK(effect_2_value >= 0),
-    effect_2_enchant INT,
-    effect_2_grind INT,
-    effect_3 INT REFERENCES k_artiffact_effect(id),
-    effect_3_value INT CHECK(effect_3_value >= 0),
-    effect_3_enchant INT,
-    effect_3_grind INT,
-    effect_4 INT REFERENCES k_artiffact_effect(id),
-    effect_4_value INT CHECK(effect_4_value >= 0),
-    effect_4_enchant INT,
-    effect_4_grind INT,
     locked INT NOT NULL CHECK(locked IN (0, 1))
 );
+CREATE TABLE artifact_stat(
+    artifact INT NOT NULL references artifact(id),
+    stat INT NOT NULL REFERENCES k_artifact_stat(id),
+    value INT NOT NULL CHECK(value >= 0),
+    PRIMARY KEY (artifact)
+);
+CREATE TABLE artifact_effect(
+    artifact INT NOT NULL references artifact(id),
+    slot INT NOT NULL CHECK(slot BETWEEN 1 AND 4),
+    effect INT NOT NULL REFERENCES k_artifact_effect(id),
+    value INT NOT NULL CHECK(value >= 0),
+    enchant INT NOT NULL CHECK(enchant IN (0, 1)),
+    grind INT NOT NULL CHECK(grind >= 0),
+    rolls INT NOT NULL CHECK(rolls BETWEEN 0 AND 4),
+    PRIMARY KEY (artifact, slot)
+);
+CREATE TABLE unit_artifact(
+    unit INT NOT NULL REFERENCES unit(id),
+    artifact INT NOT NULL REFERENCES artifact(id),
+    rta INT NOT NULL DEFAULT 0 CHECK(rta IN (0, 1)),
+    PRIMARY KEY(unit, artifact, rta)
+);
 CREATE TABLE inventory(
     uid INT NOT NULL REFERENCES player(id),
     id INT NOT NULL REFERENCES k_inventory(id),

+ 2 - 2
public/css/monsters.css

@@ -32,7 +32,7 @@ section#list div.monster div.monster_tooltip{
     left: 6em;
     z-index: 10;
     display: none;
-    background: #351e0b;
+    background: var(--color-monster-tooltip-background);
     border: 0.2em solid var(--ui-color-border);
     border-radius: 0.5em;
     padding: 0.5em;
@@ -64,7 +64,7 @@ section#list div.monster div.monster_tooltip table.stats{
 section#list div.monster div.monster_tooltip table.stats th{
     font-weight: bold;
     border-bottom: 0.1em solid black;
-    background-color: #150e00;
+    background-color: var(--color-monster-tooltip-header);
 }
 
 section#list div.monster div.monster_tooltip table.stats tr{

+ 33 - 0
public/css/ui-rta.css

@@ -0,0 +1,33 @@
+:root {
+    /**
+     * Header and footer.
+     */
+    --header-background: #3c6b79;
+    --ui-color-border: #7879c8;
+
+    /**
+     * Sidebar.
+     */
+    --sidebar-background: #1b4859;
+    /**
+     * Sections.
+     */
+    --section-title-background: #0f3a4f;
+    --section-background-list: #121f37;
+    --section-background-content: #395f75;
+
+    /**
+     * Input elments
+     */
+    --input-background: linear-gradient(0deg, #3f5bba 0%, #7779c6 97%, #8ec0d1 100%);
+    --input-background-disabled: linear-gradient(0deg, #603d20 0%, #64563c 97%, #685447 100%);
+    --input-background-unchecked: #283e60;
+    --input-background-checked: #8fb8d1;
+    /**
+     * Other colors
+     */
+    --color-monster-tooltip-background: #090c33;
+    --color-monster-tooltip-header: #050015;
+    --color-table-rune-background: #373662;
+    --color-table-rune-border: #211933;
+}

+ 109 - 54
public/css/ui.css

@@ -73,15 +73,22 @@
     --input-color-placeholder: #777777;
     --input-font-weight: normal;
     --input-padding: 0;
-    --input-background: linear-gradient(0deg, rgba(187,132,64,1) 0%, rgba(200,173,120,1) 97%, rgba(209,169,143,1) 100%);
-    --input-background-disabled: linear-gradient(0deg, rgba(93,61,32,1) 0%, rgba(100,86,60,1) 97%, rgba(104,84,71,1) 100%);
-    --input-background-unchecked: rgb(96, 71, 40);
-    --input-background-checked: rgba(209,169,143,1);
+    --input-background: linear-gradient(0deg, #bb8440 0%, #c8ad78 97%, #d1a98f 100%);
+    --input-background-disabled: linear-gradient(0deg, #603d20 0%, #64563c 97%, #685447 100%);
+    --input-background-unchecked: #604728;
+    --input-background-checked: #d1a98f;
     --input-border: 0;/*0.2em solid var(--ui-color-border);*/
     --input-border-radius: 0.2em;
     --input-text-shadow: 0 0 0.1em #000000;
     --input-box-shadow: 0 0 0.2em #000000;
     --input-button-padding: 0.3em 1em 0.3em 1em;
+    /**
+     * Other colors
+     */
+    --color-monster-tooltip-background: #351e0b;
+    --color-monster-tooltip-header: #150e00;
+    --color-table-rune-background: #7d6640;
+    --color-table-rune-border: #3c2929;
 }
 
 
@@ -194,17 +201,17 @@ header{
     }
 }
 header div#logo{
-    font-size: 70%;
+    font-size: 100%;
     margin: auto;
     display: inline-block;
     vertical-align: middle;
-    width: 10em;
+    width: 9em;
     text-align: center;
     float: left;
 }
 header div#logo img#logo_img{
-    max-width: 8em;
-    max-height: 4em;
+    max-width: 9em;
+    max-height: 6em;
 }
 header div#logo h1#logo_text{
     font-style: italic;
@@ -233,55 +240,46 @@ header div#logo h1#logo_text span.small{
     header div#logo h1#logo_text span.small{/*display: none;*/}
 }
 header nav#menu{
-    display: inline-block;
-    height: 2em;
-}
-@media only screen and (max-width: 788px){
-    header nav#menu{
-        display: block;
-        position: absolute;
-        left: 0em;
-        right: 7em;
-        top: 0em;
-        text-align: left;
-    }
+    display: block;
+    height: 4.5em;
 }
-header nav#menu a{
+header nav#menu table td{
     font-size: 100%;
     font-weight: bold;
     text-transform: capitalize;
     font-variant: small-caps;
-    margin: 0 -0.2em 0 0; /* -0.2 to compensate for strange space. */
     text-decoration: none;
     position: relative;
-    transition: all .4s ease-in-out;
-    color: var(--nav-color);
-    border-left: var(--nav-separator);
-    padding: 0.3em;
-    text-align: center;
-    display: inline-block;
+    padding: 0;
     vertical-align: middle;
+}
+@media screen and (max-width : 768px){
+    header nav#menu table td{
+        font-size: 85%;
+    }
+}
+header nav#menu table td.item{
+    border: var(--nav-separator);
+    text-align: center;
+}
+header nav#menu table td.last{
+    width: 100%;
+    text-align: right;
+    padding-right: 0.5em;
+}
+header nav#menu table td.item a{
+    color: var(--nav-color);
     text-shadow: var(--nav-shadow);
+    transition: all .4s ease-in-out;
+    display: block;
+    padding: 0.3em 0.1em;
 }
-header nav#menu a:last-of-type{border-right: var(--nav-separator)}
-header nav#menu a:hover{
+header nav#menu table td.item a:hover{
     background-color: var(--nav-background-hover);
     color: var(--nav-color-hover);
     text-shadow: var(--nav-shadow-hover);
 }
-@media only screen and (max-width: 768px){
-    header nav#menu a{
-        font-size: 80%;
-        padding: 0.6em 0.2em;
-        margin: 0em -0.2em;
-        display: inline-block;
-        text-align: center;
-        border-top: var(--nav-separator);
-        border-bottom: var(--nav-separator);
-        border-right: var(--nav-separator);
-    }
-}
-header nav#profile{
+header table td.profile nav#profile{
     float: right;
     margin-right: 0.5em;
     position: absolute;
@@ -289,15 +287,14 @@ header nav#profile{
     top: 0em;
 }
 @media screen and (max-width : 768px){
-    header nav#profile{
+    header table td.profile nav#profile{
         margin-right: 0.5em;
         position: absolute;
         top: 2em;
         right: 0.5em;
     }
 }
-
-header nav#profile a{
+header table td.profile a{
     border-left: 0;
     font-size: 110%;
     font-weight: bold;
@@ -314,10 +311,67 @@ header nav#profile a{
     vertical-align: middle;
     text-shadow: var(--nav-shadow);
 }
-header nav#profile a:hover{
+header table td.profile a:hover{
     color: var(--nav-color-hover);
     text-shadow: var(--nav-shadow-hover);
 }
+header table td.mode div#mode_switch{
+    display: inline-block;
+    font-size: 70%;
+}
+header table td.mode div#mode_switch label{
+    vertical-align: middle;
+}
+header table td.mode div#mode_switch .switch {
+    position: relative;
+    display: inline-block;
+    width: 2em;
+    height: 1.5em;
+}
+header table td.mode div#mode_switch .switch input {
+    opacity: 0;
+    width: 0;
+    height: 0;
+}
+header table td.mode div#mode_switch .slider {
+    position: absolute;
+    cursor: pointer;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: #755739;
+    -webkit-transition: .4s;
+    transition: .4s;
+}
+header table td.mode div#mode_switch .slider:before {
+    position: absolute;
+    content: "";
+    height: 1em;
+    width: 1em;
+    left: 0.25em;
+    bottom: 0.25em;
+    background-color: white;
+    -webkit-transition: .4s;
+    transition: .4s;
+}
+header table td.mode div#mode_switch input:checked + .slider {
+  background-color: #324b4f;
+}
+header table td.mode div#mode_switch input:focus + .slider {
+  box-shadow: 0 0 1px #2196F3;
+}
+header table td.mode div#mode_switch input:checked + .slider:before {
+  -webkit-transform: translateX(0.5em);
+  -ms-transform: translateX(0.5em);
+  transform: translateX(0.5em);
+}
+header table td.mode div#mode_switch .slider.round {
+    border-radius: 1.5em;
+}
+header table td.mode div#mode_switch .slider.round:before {
+    border-radius: 50%;
+}
 
 aside{
     grid-area: sidebar;
@@ -329,7 +383,7 @@ aside{
     overflow-y: hidden;
     text-align: left;
     border-right: var(--sidebar-border);
-    padding: 0.3em
+    padding: 0.3em;
     margin: 0;
     background: var(--sidebar-background);
 }
@@ -358,7 +412,7 @@ aside h2{
     text-transform: capitalize;
     font-variant: small-caps;
     height: 1.2em;
-    padding-top: 3em;
+    padding-top: 5em;
 }
 @media only screen and (max-width: 788px){
     aside h2{
@@ -387,6 +441,7 @@ aside form.filter input[type='submit']{
     margin: 1em auto;
     display: block;
 }
+
 main{
     grid-area: content;
     overflow-y: auto;
@@ -877,9 +932,9 @@ table.rune{
     position: relative;
     border-radius: 1em;
     margin: 0.5em;
-    background-color: #7d6640;
+    background-color: var(--color-table-rune-background);
     font-size: 90%;
-    border: 0.3em solid #3c2929;
+    border: 0.3em solid var(--color-table-rune-border);
     font-family: monospace;
 }
 table.rune td.icon{
@@ -998,9 +1053,9 @@ table.artifact{
     position: relative;
     border-radius: 1em;
     margin: 0.5em;
-    background-color: #7d6640;
+    background-color: var(--color-table-rune-background);
     font-size: 90%;
-    border: 0.3em solid #3c2929;
+    border: 0.3em solid var(--color-table-rune-border);
     font-family: monospace;
 }
 table.artifact td.icon{
@@ -1078,7 +1133,7 @@ table.artifact td.details table.table_details span.quality.quality_legend{backgr
 div.enchantment_panel{
     width: 4em;
     height: 4em;
-    border: 0.1em solid #3c2929;
+    border: 0.1em solid var(--color-table-rune-border);
     border-radius: 0.5em;
     position: relative;
     text-align: center;