فهرست منبع

Runs are now better parsed, all reward types are considered and filters are working now. The optimizer has been optimized, and a focus option has been added. Level 20 decorations data inserted and calculated. Silver and purple monsters are now ssen in the catalog. Several minor fixes.

Iñigo Valentin 5 سال پیش
والد
کامیت
ec40acd22d

+ 4 - 4
application/API/v1/units/GET.php

@@ -133,16 +133,16 @@ function get_unit($id){
                     case STAT_ID::SPD:
                         $description .= "attack speed";
                         break;
-                    case STAT_ID::CRIT_RATE:
+                    case STAT_ID::CRR:
                         $description .= "critical rate";
                         break;
-                    case STAT_ID::CRIT_DMG:
+                    case STAT_ID::CRD:
                         $description .= "critical damage";
                         break;
-                    case STAT_ID::ACCURACY:
+                    case STAT_ID::ACC:
                         $description .= "accuracy";
                         break;
-                    case STAT_ID::RESIST:
+                    case STAT_ID::RES:
                         $description .= "resistance";
                         break;
                 }

+ 4 - 4
application/Constant.php

@@ -223,22 +223,22 @@ final class STAT_ID{
     /**
      * CRIT_RATE
      */
-    const CRIT_RATE = 5;
+    const CRR = 5;
 
     /**
      * CRIT_DMG
      */
-    const CRIT_DMG = 6;
+    const CRD = 6;
 
     /**
      * RESIST
      */
-    const RESIST = 7;
+    const RES = 7;
 
     /**
      * ACCURACY
      */
-    const ACCURACY = 8;
+    const ACC = 8;
 };
 
 /**

+ 32 - 18
application/action/optimize_get_options.php

@@ -42,8 +42,9 @@ function action(){
     }
     $unit = new Unit($unit_id, true, $player);
     $base_stats = $unit->get_base_stats();
-    $building_stats = $unit->get_base_stats();
-    $artifact_stats = $unit->get_base_stats();
+    $building_stats = $unit->get_building_stats();
+    $artifact_stats = $unit->get_artifact_stats();
+    $total_stats = $unit->get_stats();
 
     $tuning = filter_input(INPUT_POST, 'tuning');
     if ($tuning == null){
@@ -58,16 +59,16 @@ function action(){
         $set = [
             "runes" => [],
             "stats" => [
-                "atk" => $base_stats["atk"] + $building_stats["atk"] + $artifact_stats["atk"],
-                "def" => $base_stats["def"] + $building_stats["def"] + $artifact_stats["def"],
-                "hp"  => $base_stats["hp"]  + $building_stats["hp"]  + $artifact_stats["hp"],
-                "spd" => $base_stats["spd"] + $building_stats["spd"] + $artifact_stats["spd"],
-                "crr" => $base_stats["crr"] + $building_stats["crr"] + $artifact_stats["crr"],
-                "crd" => $base_stats["crd"] + $building_stats["crd"] + $artifact_stats["crd"],
-                "acc" => $base_stats["acc"] + $building_stats["acc"] + $artifact_stats["acc"],
-                "res" => $base_stats["res"] + $building_stats["res"] + $artifact_stats["res"],
-                "ehp" => 0,
-                "dmg" => 0
+                "atk" => $base_stats["atk"],
+                "def" => $base_stats["def"],
+                "hp"  => $base_stats["hp"],
+                "spd" => $base_stats["spd"],
+                "crr" => $base_stats["crr"],
+                "crd" => $base_stats["crd"],
+                "acc" => $base_stats["acc"],
+                "res" => $base_stats["res"],
+                "ehp" => $base_stats["ehp"],
+                "dmg" => $base_stats["dmg"]
             ]
         ];
         foreach ($option["runes"] as $rune_option){
@@ -82,10 +83,10 @@ function action(){
             $stat_ids = [
                 $rune->get_main_stat()->get_stat(),
                 ($rune->get_innate_stat() != null ? $rune->get_innate_stat()->get_stat() : null),
-                (sizeof($rune->get_substats() > 0 ? $rune->get_substats()[0]->get_stat() : null)),
-                (sizeof($rune->get_substats() > 1 ? $rune->get_substats()[1]->get_stat() : null)),
-                (sizeof($rune->get_substats() > 2 ? $rune->get_substats()[2]->get_stat() : null)),
-                (sizeof($rune->get_substats() > 3 ? $rune->get_substats()[3]->get_stat() : null))
+                (sizeof($rune->get_substats()) > 0 ? $rune->get_substats()[0]->get_stat() : null),
+                (sizeof($rune->get_substats()) > 1 ? $rune->get_substats()[1]->get_stat() : null),
+                (sizeof($rune->get_substats()) > 2 ? $rune->get_substats()[2]->get_stat() : null),
+                (sizeof($rune->get_substats()) > 3 ? $rune->get_substats()[3]->get_stat() : null)
             ];
             $main_value = $rune->get_main_stat()->get_value();
             switch ($tuning){
@@ -122,7 +123,7 @@ function action(){
                         $set["stats"]["atk"] += $stat_values[$i];
                         break;
                     case RUNE_STAT_ID::ATK_P:
-                        $set["stats"]["atk"] += ceil($base_stats()["atk"] * $stat_values[$i] / 100);
+                        $set["stats"]["atk"] += ceil($base_stats["atk"] * $stat_values[$i] / 100);
                         break;
                     case RUNE_STAT_ID::DEF:
                         $set["stats"]["def"] += $stat_values[$i];
@@ -164,7 +165,20 @@ function action(){
             $crd = $set["stats"]["crd"];
             $edmg = ceil(($atk * (100 - $crr) / 100) + (($atk + ($atk * $crd / 100)) * $crr / 100));
             $set["stats"]["dmg"] = $edmg;
-
+            error_log("attack before extras: " . $set["stats"]["atk"]);
+            
+            // Add artifacts and buildings
+            $set["stats"]["atk"] += ($building_stats["atk"] + $artifact_stats["atk"]);
+            $set["stats"]["def"] += ($building_stats["def"] + $artifact_stats["def"]);
+            $set["stats"]["hp"]  += ($building_stats["hp"]  + $artifact_stats["hp"]);
+            $set["stats"]["spd"] += ($building_stats["spd"] + $artifact_stats["spd"]);
+            $set["stats"]["crr"] += ($building_stats["crr"] + $artifact_stats["crr"]);
+            $set["stats"]["crd"] += ($building_stats["crd"] + $artifact_stats["crd"]);
+            $set["stats"]["acc"] += ($building_stats["acc"] + $artifact_stats["acc"]);
+            $set["stats"]["res"] += ($building_stats["res"] + $artifact_stats["res"]);
+            $set["stats"]["ehp"] += ($building_stats["ehp"] + $artifact_stats["ehp"]);
+            $set["stats"]["dmg"] += ($building_stats["dmg"] + $artifact_stats["dmg"]);
+            error_log("attack after extras: " . $set["stats"]["atk"]);
             // Add to the array
             array_push($set["runes"], $r);
 

+ 190 - 15
application/action/optimize_get_rune_list.php

@@ -64,6 +64,19 @@ function action(){
     if (sizeof($sets) < 2 || sizeof($sets) > 3){
         return -3;
     }
+    
+    $focus = [];
+    if (isset($_POST["focus_0"]) && intval($_POST["focus_0"]) > 0){
+        array_push($focus, intval($_POST["focus_0"]));
+    }
+    if (isset($_POST["focus_1"]) && intval($_POST["focus_1"]) > 0){
+        array_push($focus, intval($_POST["focus_1"]));
+    }
+    if (isset($_POST["focus_2"]) && intval($_POST["focus_2"]) > 0){
+        array_push($focus, intval($_POST["focus_2"]));
+    }
+    // Remove doubles and sort. The order will be HP, ATK, DEF, SPD, CRR, CRD, RES, ACC
+    $focus = array_unique($focus, SORT_NUMERIC);
 
     // Main stats in even slots.
     $stats = [];
@@ -117,26 +130,27 @@ function action(){
         case 0: // Storage only (or itself)
             $base_s .= "
               (
-                rune.id IN (SELECT DISTINCT unit FROM unit_rune WHERE unit = :unit_id AND rta = " . $game_mode . ")
-                OR rune.id NOT IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = " . $game_mode . ")
+                rune.id IN (SELECT DISTINCT rune FROM unit_rune WHERE unit = :unit_id AND rta = " . $game_mode . ")
+                OR
+                rune.id NOT IN (SELECT DISTINCT rune FROM unit_rune WHERE rta = " . $game_mode . ")
               )";
             break;
         case 1: // Units in no teams (or itself)
             $base_s .= "
               (
-                rune.id IN (SELECT DISTINCT unit FROM unit_rune WHERE unit = :unit_id AND rta = " . $game_mode . ")
-                OR rune.id NOT IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = " . $game_mode . ")
-                OR rune.id NOT IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = " . $game_mode . " AND unit NOT IN (SELECT DISTINCT unit FROM team_unit))
+                rune.id IN (SELECT DISTINCT rune FROM unit_rune WHERE unit = :unit_id AND rta = " . $game_mode . ")
+                OR rune.id NOT IN (SELECT DISTINCT rune FROM unit_rune WHERE rta = " . $game_mode . ")
+                OR rune.id NOT IN (SELECT DISTINCT rune FROM unit_rune WHERE rta = " . $game_mode . " AND unit NOT IN (SELECT DISTINCT unit FROM team_unit))
               )
             ";
             break;
         case 2: // Units in teams with 0 score (or itself)
             $base_s .= "
               (
-                rune.id IN (SELECT DISTINCT unit FROM unit_rune WHERE unit = :unit_id AND rta = " . $game_mode . ")
-                OR rune.id NOT IN (SELECT DISTINCT unit FROM unit_rune WHERE rta = " . $game_mode . ")
+                rune.id IN (SELECT DISTINCT rune FROM unit_rune WHERE unit = :unit_id AND rta = " . $game_mode . ")
+                OR rune.id NOT IN (SELECT DISTINCT rune FROM unit_rune WHERE rta = " . $game_mode . ")
                 OR rune.id NOT IN (
-                  SELECT DISTINCT unit 
+                  SELECT DISTINCT rune 
                   FROM unit_rune 
                   WHERE
                     rta = " . $game_mode . "
@@ -163,15 +177,172 @@ function action(){
             $base_s .= " 1 = 0 ";
     }
     $s_order = " ORDER BY stars DESC, original_quality DESC, max_efficiency DESC, efficiency DESC, level DESC";
-    $s_in = " main_stat IN (:stat_0, :stat_1, :stat_2) ";
+    //$s_in = " main_stat IN (:stat_0, :stat_1, :stat_2) ";
+    $s_main = [
+        " main_stat = :stat_0 ",
+        " main_stat = :stat_1 ",
+        " main_stat = :stat_2 ",
+    ];
+    
+    // Process focuses
+    $focus_stats = [];
+    foreach ($focus as $f){
+        switch ($f){
+            case STAT_ID::HP:
+                array_push($focus_stats, RUNE_STAT_ID::HP);
+                array_push($focus_stats, RUNE_STAT_ID::HP_P);
+                break;
+            case STAT_ID::ATK:
+                array_push($focus_stats, RUNE_STAT_ID::ATK);
+                array_push($focus_stats, RUNE_STAT_ID::ATK_P);
+                break;
+            case STAT_ID::DEF:
+                array_push($focus_stats, RUNE_STAT_ID::DEF);
+                array_push($focus_stats, RUNE_STAT_ID::DEF_P);
+                break;
+            case STAT_ID::SPD:
+                array_push($focus_stats, RUNE_STAT_ID::SPD);
+                break;
+            case STAT_ID::CRR:
+                array_push($focus_stats, RUNE_STAT_ID::CRR);
+                break;
+            case STAT_ID::CRD:
+                array_push($focus_stats, RUNE_STAT_ID::CRD);
+                break;
+            case STAT_ID::ACC:
+                array_push($focus_stats, RUNE_STAT_ID::ACC);
+                break;
+            case STAT_ID::RES:
+                array_push($focus_stats, RUNE_STAT_ID::RES);
+                break;
+        }
+    }
+
+    $focus_cond = ["", "", "", "", "", "", ""];
+    if (sizeof($focus) > 0){
+        
+        // Slot 1, no ATK flat, no DEF flat, no DEF %
+        $focus_slot = $focus_stats;
+        /*if (array_search(RUNE_STAT_ID::ATK, $focus_slot) !== false){
+            $focus_slot = array_diff($focus_slot, [RUNE_STAT_ID::ATK])//array_splice($focus_slot, array_search(RUNE_STAT_ID::ATK, $focus_slot), 1);
+        }
+        if (array_search(RUNE_STAT_ID::DEF, $focus_slot) !== false){
+            $focus_slot = array_splice($focus_slot, array_search(RUNE_STAT_ID::DEF, $focus_slot), 1);
+        }
+        if (array_search(RUNE_STAT_ID::DEF_P, $focus_slot) !== false){
+            $focus_slot = array_splice($focus_slot, array_search(RUNE_STAT_ID::DEF_P, $focus_slot), 1);
+        }*/
+        $focus_slot = array_diff($focus_slot, [RUNE_STAT_ID::ATK, RUNE_STAT_ID::DEF, RUNE_STAT_ID::DEF_P]);
+        if (sizeof($focus_slot) > 0){
+            $focus_cond[1] .= "
+              -- FOCUS 1
+              AND (
+                rune.id IN (
+                  SELECT DISTINCT rune FROM rune_stat WHERE slot != :slot_main AND stat IN
+                  (
+            ";
+            foreach ($focus_slot as $stat){
+                $focus_cond[1] .= $stat . ", ";
+            }
+            $focus_cond[1] = rtrim($focus_cond[1], ", ");
+            $focus_cond[1] .= "
+                  )
+                )
+              )  -- END FOCUS 1
+            ";
+        }
+        
+        // Slot 3, no ATK flat, no ATK %, no DEF flat.
+        $focus_slot = $focus_stats;
+        /*if (array_search(RUNE_STAT_ID::ATK, $focus_slot) !== false){
+            $focus_slot = array_splice($focus_slot, array_search(RUNE_STAT_ID::ATK, $focus_slot), 1);
+        }
+        if (array_search(RUNE_STAT_ID::ATK_P, $focus_slot) !== false){
+            $focus_slot = array_splice($focus_slot, array_search(RUNE_STAT_ID::ATK_P, $focus_slot), 1);
+        }
+        if (array_search(RUNE_STAT_ID::DEF, $focus_slot) !== false){
+            $focus_slot = array_splice($focus_slot, array_search(RUNE_STAT_ID::DEF, $focus_slot), 1);
+        }*/
+        $focus_slot = array_diff($focus_slot, [RUNE_STAT_ID::ATK, RUNE_STAT_ID::ATK_P, RUNE_STAT_ID::DEF]);
+        if (sizeof($focus_slot) > 0){
+            $focus_cond[3] .= "
+              -- FOCUS 3
+              AND (
+                rune.id IN (
+                  SELECT DISTINCT rune FROM rune_stat WHERE slot != :slot_main AND stat IN
+                  (
+            ";
+            foreach ($focus_slot as $stat){
+                $focus_cond[3] .= $stat . ", ";
+            }
+            $focus_cond[3] = rtrim($focus_cond[3], ", ");
+            $focus_cond[3] .= "
+                  )
+                )
+              )  -- END FOCUS 3
+            ";
+        }
+        
+        // Slot 5, no HP flat.
+        $focus_slot = $focus_stats;
+        /*if (array_search(RUNE_STAT_ID::HP, $focus_slot) !== false){
+            $focus_slot = array_splice($focus_slot, array_search(RUNE_STAT_ID::HP, $focus_slot), 1);
+        }*/
+        $focus_slot = array_diff($focus_slot, [RUNE_STAT_ID::HP]);
+        if (sizeof($focus_slot) > 0){
+            $focus_cond[5] .= "
+              -- FOCUS 5
+              AND (
+                rune.id IN (
+                  SELECT DISTINCT rune FROM rune_stat WHERE slot != :slot_main AND stat IN
+                  (
+            ";
+            foreach ($focus_slot as $stat){
+                $focus_cond[5] .= $stat . ", ";
+            }
+            $focus_cond[5] = rtrim($focus_cond[5], ", ");
+            $focus_cond[5] .= "
+                  )
+                )
+              ) -- END FOCUS 5
+            ";
+        }
+        
+        // TODO: Focus for even slots.
+        // Slot 2, all stat, but include main
+        // Slot 5, no HP flat.
+        $focus_slot = $focus_stats;
+        if (sizeof($focus_slot) > 0){
+            $focus_cond[2] .= "
+              -- FOCUS EVEN
+              AND (
+                rune.id IN (
+                  SELECT DISTINCT rune FROM rune_stat WHERE stat IN
+                  (
+            ";
+            foreach ($focus_slot as $stat){
+                $focus_cond[2] .= $stat . ", ";
+            }
+            $focus_cond[2] = rtrim($focus_cond[2], ", ");
+            $focus_cond[2] .= "
+                  )
+                )
+              ) -- END FOCUS EVEN
+            ";
+        }
+        
+    }
+    
+    //TODO DEBUG
+    $focus_cond[2] = "";
 
     $s = ["", "", "", "", "", "", ""];
-    $s[1] = $base_s . " AND slot = 1 " . $s_order;
-    $s[3] = $base_s . " AND slot = 3 " . $s_order;
-    $s[5] = $base_s . " AND slot = 5 " . $s_order;
-    $s[2] = $base_s . " AND slot = 2 AND " . $s_in . $s_order;
-    $s[4] = $base_s . " AND slot = 4 AND " . $s_in . $s_order;
-    $s[6] = $base_s . " AND slot = 6 AND " . $s_in . $s_order;
+    $s[1] = $base_s . " AND slot = 1 " . $focus_cond[1] . $s_order . " LIMIT :limit_odd;";
+    $s[3] = $base_s . " AND slot = 3 " . $focus_cond[3] . $s_order . " LIMIT :limit_odd;";
+    $s[5] = $base_s . " AND slot = 5 " . $focus_cond[5] . $s_order . " LIMIT :limit_odd;";
+    $s[2] = $base_s . " AND slot = 2 AND " . $s_main[0] . $focus_cond[2] . $s_order . " LIMIT :limit_even;";
+    $s[4] = $base_s . " AND slot = 4 AND " . $s_main[1] . $focus_cond[2] . $s_order . " LIMIT :limit_even;";
+    $s[6] = $base_s . " AND slot = 6 AND " . $s_main[2] . $focus_cond[2] . $s_order . " LIMIT :limit_even;";
 
     $total_candidates = 0;
     for ($i = 1; $i <= 6; $i ++){
@@ -182,6 +353,10 @@ function action(){
         $statement->bindValue(':stat_0', $stats[0], SQLITE3_TEXT);
         $statement->bindValue(':stat_1', $stats[1], SQLITE3_TEXT);
         $statement->bindValue(':stat_2', $stats[2], SQLITE3_TEXT);
+        $statement->bindValue(':slot_main', RUNE_STAT_SLOT_ID::MAIN, SQLITE3_INTEGER);
+        $statement->bindValue(':limit_even', 150, SQLITE3_INTEGER);
+        $statement->bindValue(':limit_odd', 100, SQLITE3_INTEGER);
+        //error_log($statement->getSQL(true));
         $q = $statement->execute();
         while ($r = $q->fetchArray(SQLITE3_ASSOC)){
             $rune = create_rune_array($unit, $r, $tuning);

+ 2 - 2
application/entity/Enchantment.php

@@ -189,7 +189,7 @@ class Enchantment extends Entity{
                 enchantment_type,
                 enchantment_range
               WHERE
-                run = :run AND
+                run_drop_enchantment.id = :id AND
                 run_drop_enchantment.type = enchantment_type.id AND
                 enchantment_type.gem = enchantment_range.gem AND
                 enchantment_type.gem = enchantment_range.gem AND
@@ -201,7 +201,7 @@ class Enchantment extends Entity{
             $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
             if ($r){
                 $this->player_id = get_context()->get_player()->get_id();
-                if ($r["type"] == ENCHANTMENT_TYPE_ID::ENCHANT_GEM || $r["type"] == ENCHANTMENT_TYPE_ID::INMEMORIAL_GEM){
+                if ($r["type"] == ENCHANTMENT_TYPE_ID::GEM || $r["type"] == ENCHANTMENT_TYPE_ID::INMEMORIAL_GEM){
                     $this->gem = 1;
                 }
                 else{

+ 4 - 4
application/entity/Leader_Skill.php

@@ -164,16 +164,16 @@ class Leader_Skill extends Entity{
             case STAT_ID::SPD:
                 $s .= "attack speed";
                 break;
-            case STAT_ID::CRIT_RATE:
+            case STAT_ID::CRR:
                 $s .= "critical rate";
                 break;
-            case STAT_ID::CRIT_DMG:
+            case STAT_ID::CRD:
                 $s .= "critical damage";
                 break;
-            case STAT_ID::ACCURACY:
+            case STAT_ID::ACC:
                 $s .= "accuracy";
                 break;
-            case STAT_ID::RESIST:
+            case STAT_ID::RES:
                 $s .= "resistance";
                 break;
         }

+ 1 - 1
application/entity/Run.php

@@ -312,7 +312,7 @@ class Run extends Entity{
         $q = $statement->execute();
         while ($r = $q->fetchArray(SQLITE3_ASSOC)){
             $enchantment = new Enchantment($r["id"]);
-            array_push($this->reward[enchantment], $enchantment);
+            array_push($this->reward["enchantment"], $enchantment);
         }
         $this->flag_reward = true;
     }

+ 5 - 7
application/entity/Unit.php

@@ -280,7 +280,6 @@ class Unit extends Entity{
      * @param int $id Unit identifier.
      */
     public function __construct($id){
-        $player = get_context()->get_player()->get_id();
         $statement = get_context()->get_db()->prepare("
           SELECT
             player,
@@ -310,7 +309,6 @@ class Unit extends Entity{
             id = :id;
         ");
         $statement->bindValue(':id', $id, SQLITE3_TEXT);
-        $statement->bindValue(':player', $player, SQLITE3_TEXT);
         $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
         if ($r){
             $this->player = $r["player"];
@@ -466,7 +464,7 @@ class Unit extends Entity{
         $statement->bindValue(':stat_def', STAT_ID::DEF, SQLITE3_INTEGER);
         $statement->bindValue(':stat_hp', STAT_ID::HP, SQLITE3_INTEGER);
         $statement->bindValue(':stat_spd', STAT_ID::SPD, SQLITE3_INTEGER);
-        $statement->bindValue(':stat_crd', STAT_ID::CRIT_DMG, SQLITE3_INTEGER);
+        $statement->bindValue(':stat_crd', STAT_ID::CRD, SQLITE3_INTEGER);
         $q = $statement->execute();
         while ($r = $q->fetchArray(SQLITE3_ASSOC)){
             switch($r["affected_stat"]){
@@ -479,15 +477,15 @@ class Unit extends Entity{
                 case STAT_ID::SPD:
                     $this->building_stats["spd"] += ($this->base_stats["spd"]* $r["bonus"] / 100);
                     break;
-                case STAT_ID::CRIT_DMG:
+                case STAT_ID::CRD:
                     $this->building_stats["crd"] += $r["bonus"];
                     break;
                 case STAT_ID::ATK:
                     if(strlen($r["element"]) > 0 && $r["element"] == $this->monster->get_element()){
-                        $this->building_stats["atk"] += ($this->base_stats["atk"]* $r["bonus"] / 100);
+                        $this->building_stats["atk"] += ($this->base_stats["atk"] * $r["bonus"] / 100);
                     }
-                    else{
-                        $this->building_stats["atk"] += ($this->base_stats["atk"]* $r["bonus"] / 100);
+                    elseif(strlen($r["element"]) == 0){
+                        $this->building_stats["atk"] += ($this->base_stats["atk"] * $r["bonus"] / 100);
                     }
                     break;
             }

BIN
application/key.sqlite


+ 38 - 5
application/page/Monster_Page.php

@@ -48,7 +48,7 @@ class Monster_Page extends Page{
      * @var bool Indicates a monstes that can second awaken.
      */
     private $red = false;
-
+    
     /**
      * Constructor.
      *
@@ -60,13 +60,14 @@ class Monster_Page extends Page{
         $this->view = PATH::VIEW . "monster.php";
         $title = "";
         $monster = new Monster($id);
+        $minimum_id = 0;
         if (! $monster->can_awaken()){
             // Silver star monster.
             $this->silver = true;
             $this->monster[0] = $monster;
             $this->monster[1] = null;
             $this->monster[2] = null;
-            $title = $this->monster[0]->element_name . " " . $this->monster[0]->name;
+            $title = $this->monster[0]->get_element_name() . " " . $this->monster[0]->get_name();
         }
         elseif ($monster->can_awaken() && $monster->get_awakens_to() == null && $monster->get_awakens_from() == null){
             // Default purple (Rainbowmon or King Angelmon)
@@ -74,7 +75,8 @@ class Monster_Page extends Page{
             $this->monster[0] = null;
             $this->monster[1] = $monster;
             $this->monster[2] = null;
-            $title = $this->monster[1]->name;
+            $minimum_id = 1;
+            $title = $this->monster[1]->get_name();
         }
         elseif ($monster->can_awaken() && $monster->get_awakens_to() == null && $monster->get_awakens_from() != null){
             // Normal monster, already awakened, no 2a.
@@ -82,7 +84,7 @@ class Monster_Page extends Page{
             $this->monster[1] = $monster;
             $this->monster[2] = null;
             $title = $this->monster[1]->get_name() . " - " .$this->monster[0]->get_element_name() . " " . $this->monster[0]->get_name();
-            $monster = $this->monster[0];
+            $this->family_id= $this->monster[0]->get_family();
         }
         elseif ($monster->can_awaken() && $monster->get_awakens_to() != null && $monster->get_awakens_from() == null){
             // Normal monster, not awakened, may have 2a.
@@ -95,13 +97,44 @@ class Monster_Page extends Page{
                 $this->red = true;
                 $this->monster[2] = new Monster($this->monster[1]->get_awakens_to());
             }
+            $this->family_id= $this->monster[1]->get_family();
             $title = $this->monster[1]->get_name() . " - " .$this->monster[0]->get_element_name() . " " . $this->monster[0]->get_name();
         }
+        
+        // Load the monster family
+        $statement = get_context()->get_db()->prepare("
+          SELECT id
+          FROM monster
+          WHERE
+            family = :family AND
+            id <> :id AND
+            awakens_from IS NULL
+          ORDER BY
+              natural_stars DESC,
+              element = :fire DESC,
+              element = :water DESC,
+              element = :wind DESC,
+              element = :light DESC,
+              element = :dark DESC;
+        ");
+        $statement->bindValue(":family", $this->monster[$minimum_id]->get_family(), SQLITE3_INTEGER);
+        $statement->bindValue(":id", $this->monster[$minimum_id]->get_id(), SQLITE3_INTEGER);
+        $statement->bindValue(":fire", ELEMENT_ID::FIRE, SQLITE3_INTEGER);
+        $statement->bindValue(":water", ELEMENT_ID::WATER, SQLITE3_INTEGER);
+        $statement->bindValue(":wind", ELEMENT_ID::WIND, SQLITE3_INTEGER);
+        $statement->bindValue(":light", ELEMENT_ID::LIGHT, SQLITE3_INTEGER);
+        $statement->bindValue(":dark", ELEMENT_ID::DARK, SQLITE3_INTEGER);
+        $result_set = $statement->execute();
+        while ($result = $result_set->fetchArray(SQLITE3_ASSOC)){
+            
+            array_push($this->family, new Monster($result["id"]));
+        }
 
         $this->title = $title ." - SWDB";
         $this->description = $title . " info - SWDB";
         $this->canonical = URL::BASE . "monster_info/" . $id;
     }
+    
     /**
      * Retrieves the monster line to show.
      * 
@@ -123,7 +156,7 @@ class Monster_Page extends Page{
     public function get_family(){
         return $this->family;
     }
-
+    
     /**
      * Checks if the monster is default silver (non awakeable).
      *

+ 1 - 1
application/page/Monsters_Page.php

@@ -61,7 +61,7 @@ class Monsters_Page extends Page{
         while ($result = $result_set->fetchArray(SQLITE3_ASSOC)){
             array_push($this->monsters_open, $result["monster"]);
         }
-        $this->title = "Catalog - SWDB";
+        $this->title = "Monsters - SWDB";
         $this->description = "Catalog of all monsters";
         $this->canonical = URL::BASE . "catalog/";
     }

+ 25 - 0
application/view/monster.php

@@ -75,6 +75,31 @@
                 }
 ?>
             </nav>
+            
+<?php
+            if (sizeof($page->get_family()) > 0){
+?>
+                <p>
+                    Family members:
+                </p>
+                <nav id='family'>
+                    
+<?php
+                
+                foreach ($page->get_family() as $family){
+?>
+                    <a href='/<?=get_context()->get_player()->get_id()?>/monsters/<?=$family->get_id()?>'>
+                        <div class='monster_panel'>
+                            <?=HTML::unit_panel($family)?>
+                        </div>
+                    </a>
+<?php
+                }
+?>
+                </nav>
+<?php
+            }
+?>
         </aside>
         <main>
 <?php

+ 144 - 37
application/view/optimizer_unit.php

@@ -76,6 +76,19 @@
                 "res": 0
             }
 
+            var min_stats = {
+                "atk": 0,
+                "def": 0,
+                "hp": 0,
+                "spd": 0,
+                "crr": 0,
+                "crd": 0,
+                "acc": 0,
+                "res": 0,
+                "ehp": 0,
+                "dmg": 0
+            }
+
             var base_stats = {
                 "atk": <?=$page->get_unit()->get_base_stats()["atk"]?>,
                 "def": <?=$page->get_unit()->get_base_stats()["def"]?>,
@@ -113,6 +126,9 @@
                 'RUNE_SET_<?=RUNE_SET_ID::TOLERANCE?>': 0 // TOLERANCE
             };
 
+            // Will be set once requested_sets is populated.
+            var requested_sets_json = "";
+
 <?php
             // Get current rune sets
             $sets = [];
@@ -135,6 +151,7 @@
                     $mains[($rune->get_slot() / 2) - 1] = $rune->get_main_stat();
                 }
             }
+            
 ?>
 
             /**
@@ -321,6 +338,17 @@
                     params += '&min_dmg=' + document.getElementById('min_dmg').value;
                 }
 
+                // Focus - optional
+                if (Number(document.getElementById('focus_0').value) > 0){
+                    params += '&focus_0=' + document.getElementById('focus_0').value;
+                }
+                if (Number(document.getElementById('focus_1').value) > 0){
+                    params += '&focus_1=' + document.getElementById('focus_1').value;
+                }
+                if (Number(document.getElementById('focus_2').value) > 0){
+                    params += '&focus_2=' + document.getElementById('focus_2').value;
+                }
+
                 // Clear and calculate new requested sets
                 requested_sets['RUNE_SET_<?=RUNE_SET_ID::ENERGY?>'] = 0; // ENERGY
                 requested_sets['RUNE_SET_<?=RUNE_SET_ID::GUARD?>'] = 0; // GUARD
@@ -343,6 +371,19 @@
                 requested_sets['RUNE_SET_<?=RUNE_SET_ID::ENHANCE?>'] = 0; // ENHANCE
                 requested_sets['RUNE_SET_<?=RUNE_SET_ID::ACCURACY?>'] = 0; // acc
                 requested_sets['RUNE_SET_<?=RUNE_SET_ID::TOLERANCE?>'] = 0; // TOLERANCE
+
+                // Assign min stats for faster access later
+                min_stats["ATK"] = document.getElementById('min_atk').value;
+                min_stats["DEF"] = document.getElementById('min_def').value;
+                min_stats["HP"]  = document.getElementById('min_hp').value;
+                min_stats["SPD"] = document.getElementById('min_spd').value;
+                min_stats["CRR"] = document.getElementById('min_crr').value;
+                min_stats["CRD"] = document.getElementById('min_crd').value;
+                min_stats["ACC"] = document.getElementById('min_acc').value;
+                min_stats["RES"] = document.getElementById('min_res').value;
+                min_stats["EHP"] = document.getElementById('min_ehp').value;
+                min_stats["DMG"] = document.getElementById('min_dmg').value;
+                
                 var selected_1 = document.getElementById('set_1').options[document.getElementById('set_1').selectedIndex].value;
                 var selected_2 = document.getElementById('set_2').options[document.getElementById('set_2').selectedIndex].value;
                 var selected_3 = document.getElementById('set_3').options[document.getElementById('set_3').selectedIndex].value;
@@ -381,6 +422,9 @@
                     }
                 }
 
+                requested_sets_json = JSON.stringify(requested_sets);
+                //console.log(requested_sets_json);
+
                 // Clear and calculate the new rune set stats
                 set_stats['hp'] = 0;
                 set_stats['atk'] = 0;
@@ -440,7 +484,6 @@
                     }
                 }
                 set_stats['hp'] = Math.floor(set_stats['hp']);
-
                 // Send the request
                 var xhttp = new XMLHttpRequest();
                 xhttp.onreadystatechange = function() {
@@ -474,6 +517,7 @@
                 timestamp = + new Date();
 
                 // Make the request
+                //console.log("SENDING REQUEST TO");
                 xhttp.open('POST', '/action/optimize_get_rune_list/', true);
                 xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
                 xhttp.send(params);
@@ -516,6 +560,7 @@
                     'RUNE_SET_<?=RUNE_SET_ID::TOLERANCE?>': 0 // TOLERANCE
                 };
                 for (var i = 0; i <= 5; i ++){
+                    //console.log("CANDIDATE " + i);
                     sets['RUNE_SET_' + candidates[i].TYPE] ++;
                 }
                 // TEST I think i dont need to check for valid sets, only that
@@ -555,10 +600,17 @@
                     }
                 }*/
 
+                /*console.log(sets['RUNE_SET_<?=RUNE_SET_ID::ENERGY?>']);
+                if (sets['RUNE_SET_<?=RUNE_SET_ID::ENERGY?>'] == 6){
+                    console.log("Should be valid");
+                }*/
+
                 // Its a valid set, but does it match the requested sets?
-                if (JSON.stringify(sets) !== JSON.stringify(requested_sets)){
+                if (JSON.stringify(sets) !== requested_sets_json){
+                    //console.log(JSON.stringify(sets));
                     return false;
                 }
+                //console.log("VALID SET");
 
                 // Compare with filters
                 var new_stats = {
@@ -584,21 +636,21 @@
                     new_stats["RES"] += candidates[i].RES;
                 }
                 new_stats["HP"] = Math.floor(new_stats["HP"]);
-                //console.log("CANDIDATES NEW HP: " + new_stats["HP"]);
+                //console.log("CANDIDATES NEW HP: " + new_stats["HP"] + " MINIMUM IS " + min_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 (
-                    new_stats["ATK"] >= document.getElementById('min_atk').value &&
-                    new_stats["DEF"] >= document.getElementById('min_def').value &&
-                    new_stats["HP"]  >= document.getElementById('min_hp').value &&
-                    new_stats["SPD"] >= document.getElementById('min_spd').value &&
-                    new_stats["CRR"] >= document.getElementById('min_crr').value &&
-                    new_stats["CRD"] >= document.getElementById('min_crd').value &&
-                    new_stats["ACC"] >= document.getElementById('min_acc').value &&
-                    new_stats["RES"] >= document.getElementById('min_res').value &&
-                    new_stats["EHP"] >= document.getElementById('min_ehp').value &&
-                    new_stats["DMG"] >= document.getElementById('min_dmg').value
+                    new_stats["ATK"] >= min_stats["ATK"] &&
+                    new_stats["DEF"] >= min_stats["DEF"] &&
+                    new_stats["HP"]  >= min_stats["HP"] &&
+                    new_stats["SPD"] >= min_stats["SPD"] &&
+                    new_stats["CRR"] >= min_stats["CRR"] &&
+                    new_stats["CRD"] >= min_stats["CRD"] &&
+                    new_stats["ACC"] >= min_stats["ACC"] &&
+                    new_stats["RES"] >= min_stats["RES"] &&
+                    new_stats["EHP"] >= min_stats["EHP"] &&
+                    new_stats["DMG"] >= min_stats["DMG"]
                 ){
                     return true;
                 }
@@ -612,6 +664,7 @@
              * @param content JSON received from server.
              */
             async function calculateOptimizations(content, time){
+                 //console.log("CALCULATING...")
                 var container = document.getElementById('optimizations');
                 var data = JSON.parse(content);
 
@@ -631,11 +684,24 @@
                 if (total_combinations == 0){
                     var time = ((+ new Date()) - timestamp) / 1000;
                     log('No rune combinations found (' + time + 's)');
+                    enableNewSearch(true);
                     showMessage('No results', 'No runes found matching your criteria.');
                 }
                 var time = ((+ new Date()) - timestamp) / 1000;
                 log(total_runes + ' runes found (' + total_combinations + ' combinations) (' + time + 's)');
+                log('  By slot: ' + data[1].length + ', ' + data[2].length + ', ' + data[3].length + ', ' + data[4].length + ', ' + data[5].length + ', ' + data[6].length);
                 // TODO Prevent user on high numbers
+                if (total_combinations > 10000000){
+                    showMessage('Too many combinations', total_combinations + ' combinations found, unable to process. Please focus your reuest.');
+                    enableNewSearch(true);
+                    log('Operation canceled');
+                    return;
+                }
+                if (total_combinations > 1000000 && confirm(total_combinations + " combinations found. This operation may slow your browser. Continue?") == false){
+                    enableNewSearch(true);
+                    log('Operation canceled');
+                    return;
+                }
                 var checked_combinations = 0;
 
                 // Valid combinations that match the minimum requeriments
@@ -1634,7 +1700,7 @@
                                 Min HP
                             </td>
                             <td class='value'>
-                                <input id='min_hp' type='range' value='<?=$page->get_unit()->get_stats()["hp"]?>' min='<?=$page->get_unit()->get_stats()["hp"]?>' max='50000' oninput='updateMinValue("hp", this);'>
+                                <input id='min_hp' type='range' value='<?=$page->get_unit()->get_stats()["hp"]?>' min='<?=$page->get_unit()->get_base_stats()["hp"]?>' max='50000' oninput='updateMinValue("hp", this);'>
                                 <input type='number' id='lbl_min_hp' value='<?=$page->get_unit()->get_stats()["hp"]?>' min='<?=$page->get_unit()->get_base_stats()["hp"]?>' max='50000' onChange='updateMinValue("hp", this);'></input><span class='slider_percent'> </span>
                                 <a title='Remove filter' class='filter_control a_button' onclick='removeFilter("hp");'>
                                     <img alt='Remove filter' src='<?=URL::IMG["ICON"]?>nok.png'/>
@@ -1716,15 +1782,42 @@
                             </td>
                         </tr>
                         <tr>
-                            <td class='name'>
-                                Tune optimizer for
-                            </td>
-                            <td class='value'>
-                                <select id='tuning'>
-                                    <option value='0'>Rune current levels</option>
-                                    <option value='1'>+12</option>
-                                    <option value='2'>2/4/6 +15, 1/3/5 + 12</option>
-                                    <option value='3'>+15</option>
+                            <td>
+                                Focus:
+                            </td>
+                            <td>
+                                <select id='focus_0'>
+                                    <option value='0'></option>
+                                    <option value='<?=STAT_ID::HP?>'>HP</option>
+                                    <option value='<?=STAT_ID::ATK?>'>ATK</option>
+                                    <option value='<?=STAT_ID::DEF?>'>DEF</option>
+                                    <option value='<?=STAT_ID::SPD?>'>SPD</option>
+                                    <option value='<?=STAT_ID::CRR?>'>CRR</option>
+                                    <option value='<?=STAT_ID::CRD?>'>CRD</option>
+                                    <option value='<?=STAT_ID::ACC?>'>ACC</option>
+                                    <option value='<?=STAT_ID::RES?>'>RES</option>
+                                </select>
+                                <select id='focus_1'>
+                                    <option value='0'></option>
+                                    <option value='<?=STAT_ID::HP?>'>HP</option>
+                                    <option value='<?=STAT_ID::ATK?>'>ATK</option>
+                                    <option value='<?=STAT_ID::DEF?>'>DEF</option>
+                                    <option value='<?=STAT_ID::SPD?>'>SPD</option>
+                                    <option value='<?=STAT_ID::CRR?>'>CRR</option>
+                                    <option value='<?=STAT_ID::CRD?>'>CRD</option>
+                                    <option value='<?=STAT_ID::ACC?>'>ACC</option>
+                                    <option value='<?=STAT_ID::RES?>'>RES</option>
+                                </select>
+                                <select id='focus_2'>
+                                    <option value='0'></option>
+                                    <option value='<?=STAT_ID::HP?>'>HP</option>
+                                    <option value='<?=STAT_ID::ATK?>'>ATK</option>
+                                    <option value='<?=STAT_ID::DEF?>'>DEF</option>
+                                    <option value='<?=STAT_ID::SPD?>'>SPD</option>
+                                    <option value='<?=STAT_ID::CRR?>'>CRR</option>
+                                    <option value='<?=STAT_ID::CRD?>'>CRD</option>
+                                    <option value='<?=STAT_ID::ACC?>'>ACC</option>
+                                    <option value='<?=STAT_ID::RES?>'>RES</option>
                                 </select>
                             </td>
                             <td class='empty'>
@@ -1742,13 +1835,17 @@
                                     <img alt='Reset filter' src='<?=URL::IMG["ICON"]?>edit.png'/>
                                 </a>
                             </td>
-                        </tr>
                         <tr>
-                            <td class='empty'>
-                                Max. combinations
+                            <td class='name'>
+                                Tune optimizer for
                             </td>
-                            <td class='empty'>
-                                <input id='limit' type='number' value='10' max='100' min='1'>
+                            <td class='value'>
+                                <select id='tuning'>
+                                    <option value='0'>Rune current levels</option>
+                                    <option value='1'>+12</option>
+                                    <option value='2'>2/4/6 +15, 1/3/5 + 12</option>
+                                    <option value='3'>+15</option>
+                                </select>
                             </td>
                             <td class='empty'>
                             </td>
@@ -1767,15 +1864,11 @@
                             </td>
                         </tr>
                         <tr>
-                            <td id='log' colspan='2' rowspan='4'>
-                                <div id='log_title'>
-                                    LOG
-                                    <span id='log_clear' onClick='clearLog();'>
-                                        clear
-                                    </span>
-                                </div>
-                                <div id='log_window'>
-                                </div>
+                            <td class='empty'>
+                                Max. combinations
+                            </td>
+                            <td class='empty'>
+                                <input id='limit' type='number' value='10' max='100' min='1'>
                             </td>
                             <td class='empty'>
                             </td>
@@ -1793,6 +1886,20 @@
                                 </a>
                             </td>
                         </tr>
+                        <tr>
+                            <td id='log' colspan='2' rowspan='4'>
+                                <div id='log_title'>
+                                    LOG
+                                    <span id='log_clear' onClick='clearLog();'>
+                                        clear
+                                    </span>
+                                </div>
+                                <div id='log_window'>
+                                </div>
+                            </td>
+                            <td class='empty'>
+                            </td>
+                        </tr>
                         <tr>
                             <!--<td class='empty'>
                             </td>-->

+ 2 - 2
install_data/01_CREATE_KEYS.sql

@@ -163,8 +163,8 @@ CREATE TABLE key.enchantment_range(
 
 CREATE TABLE key.decorative_level(
     decorative INT NOT NULL REFERENCES decorative(id),
-    level INT NOT NULL CHECK(level BETWEEN 1 AND 10),
-    bonus INT NOT NULL CHECK(bonus > 0),
+    level INT NOT NULL CHECK(level BETWEEN 1 AND 20),
+    bonus FLOAT NOT NULL CHECK(bonus > 0),
     cost INT NOT NULL CHECK(cost > 0),
     PRIMARY KEY(decorative, level)
 );

+ 400 - 200
install_data/03_INSERT_KEYS_FIXED.sql

@@ -495,206 +495,406 @@ INSERT INTO key.quality VALUES(2,'Magic');
 INSERT INTO key.quality VALUES(3,'Rare');
 INSERT INTO key.quality VALUES(4,'Hero');
 INSERT INTO key.quality VALUES(5,'Legend');
-INSERT INTO key.decorative_level VALUES(4,1,2,100);
-INSERT INTO key.decorative_level VALUES(4,2,4,280);
-INSERT INTO key.decorative_level VALUES(4,3,6,460);
-INSERT INTO key.decorative_level VALUES(4,4,8,640);
-INSERT INTO key.decorative_level VALUES(4,5,10,820);
-INSERT INTO key.decorative_level VALUES(4,6,12,1000);
-INSERT INTO key.decorative_level VALUES(4,7,14,1180);
-INSERT INTO key.decorative_level VALUES(4,8,16,1360);
-INSERT INTO key.decorative_level VALUES(4,9,18,1540);
-INSERT INTO key.decorative_level VALUES(4,10,20,1720);
-INSERT INTO key.decorative_level VALUES(15,1,3,120);
-INSERT INTO key.decorative_level VALUES(15,2,5,240);
-INSERT INTO key.decorative_level VALUES(15,3,7,360);
-INSERT INTO key.decorative_level VALUES(15,4,9,480);
-INSERT INTO key.decorative_level VALUES(15,5,11,600);
-INSERT INTO key.decorative_level VALUES(15,6,13,720);
-INSERT INTO key.decorative_level VALUES(15,7,15,840);
-INSERT INTO key.decorative_level VALUES(15,8,17,960);
-INSERT INTO key.decorative_level VALUES(15,9,19,1080);
-INSERT INTO key.decorative_level VALUES(15,10,21,1200);
-INSERT INTO key.decorative_level VALUES(16,1,3,120);
-INSERT INTO key.decorative_level VALUES(16,2,5,240);
-INSERT INTO key.decorative_level VALUES(16,3,7,360);
-INSERT INTO key.decorative_level VALUES(16,4,9,480);
-INSERT INTO key.decorative_level VALUES(16,5,11,600);
-INSERT INTO key.decorative_level VALUES(16,6,13,720);
-INSERT INTO key.decorative_level VALUES(16,7,15,840);
-INSERT INTO key.decorative_level VALUES(16,8,17,960);
-INSERT INTO key.decorative_level VALUES(16,9,19,1080);
-INSERT INTO key.decorative_level VALUES(16,10,21,1200);
-INSERT INTO key.decorative_level VALUES(17,1,3,120);
-INSERT INTO key.decorative_level VALUES(17,2,5,240);
-INSERT INTO key.decorative_level VALUES(17,3,7,360);
-INSERT INTO key.decorative_level VALUES(17,4,9,480);
-INSERT INTO key.decorative_level VALUES(17,5,11,600);
-INSERT INTO key.decorative_level VALUES(17,6,13,720);
-INSERT INTO key.decorative_level VALUES(17,7,15,840);
-INSERT INTO key.decorative_level VALUES(17,8,17,960);
-INSERT INTO key.decorative_level VALUES(17,9,19,1080);
-INSERT INTO key.decorative_level VALUES(17,10,21,1200);
-INSERT INTO key.decorative_level VALUES(18,1,3,120);
-INSERT INTO key.decorative_level VALUES(18,2,5,240);
-INSERT INTO key.decorative_level VALUES(18,3,7,360);
-INSERT INTO key.decorative_level VALUES(18,4,9,480);
-INSERT INTO key.decorative_level VALUES(18,5,11,600);
-INSERT INTO key.decorative_level VALUES(18,6,13,720);
-INSERT INTO key.decorative_level VALUES(18,7,15,840);
-INSERT INTO key.decorative_level VALUES(18,8,17,960);
-INSERT INTO key.decorative_level VALUES(18,9,19,1080);
-INSERT INTO key.decorative_level VALUES(18,10,21,1200);
-INSERT INTO key.decorative_level VALUES(19,1,3,120);
-INSERT INTO key.decorative_level VALUES(19,2,5,240);
-INSERT INTO key.decorative_level VALUES(19,3,7,360);
-INSERT INTO key.decorative_level VALUES(19,4,9,480);
-INSERT INTO key.decorative_level VALUES(19,5,11,600);
-INSERT INTO key.decorative_level VALUES(19,6,13,720);
-INSERT INTO key.decorative_level VALUES(19,7,15,840);
-INSERT INTO key.decorative_level VALUES(19,8,17,960);
-INSERT INTO key.decorative_level VALUES(19,9,19,1080);
-INSERT INTO key.decorative_level VALUES(19,10,21,1200);
-INSERT INTO key.decorative_level VALUES(31,1,2,120);
-INSERT INTO key.decorative_level VALUES(31,2,5,240);
-INSERT INTO key.decorative_level VALUES(31,3,7,360);
-INSERT INTO key.decorative_level VALUES(31,4,10,480);
-INSERT INTO key.decorative_level VALUES(31,5,12,600);
-INSERT INTO key.decorative_level VALUES(31,6,15,720);
-INSERT INTO key.decorative_level VALUES(31,7,17,840);
-INSERT INTO key.decorative_level VALUES(31,8,20,960);
-INSERT INTO key.decorative_level VALUES(31,9,22,1080);
-INSERT INTO key.decorative_level VALUES(31,10,25,1200);
-INSERT INTO key.decorative_level VALUES(6,1,2,240);
-INSERT INTO key.decorative_level VALUES(6,2,3,440);
-INSERT INTO key.decorative_level VALUES(6,3,5,640);
-INSERT INTO key.decorative_level VALUES(6,4,6,840);
-INSERT INTO key.decorative_level VALUES(6,5,8,1040);
-INSERT INTO key.decorative_level VALUES(6,6,9,1240);
-INSERT INTO key.decorative_level VALUES(6,7,11,1440);
-INSERT INTO key.decorative_level VALUES(6,8,12,1640);
-INSERT INTO key.decorative_level VALUES(6,9,14,1840);
-INSERT INTO key.decorative_level VALUES(6,10,15,2040);
-INSERT INTO key.decorative_level VALUES(8,1,2,200);
-INSERT INTO key.decorative_level VALUES(8,2,4,400);
-INSERT INTO key.decorative_level VALUES(8,3,6,600);
-INSERT INTO key.decorative_level VALUES(8,4,8,800);
-INSERT INTO key.decorative_level VALUES(8,5,10,1000);
-INSERT INTO key.decorative_level VALUES(8,6,12,1200);
-INSERT INTO key.decorative_level VALUES(8,7,14,1400);
-INSERT INTO key.decorative_level VALUES(8,8,16,1600);
-INSERT INTO key.decorative_level VALUES(8,9,18,1800);
-INSERT INTO key.decorative_level VALUES(8,10,20,2000);
-INSERT INTO key.decorative_level VALUES(36,1,2,280);
-INSERT INTO key.decorative_level VALUES(36,2,4,460);
-INSERT INTO key.decorative_level VALUES(36,3,6,800);
-INSERT INTO key.decorative_level VALUES(36,4,8,1250);
-INSERT INTO key.decorative_level VALUES(36,5,10,1810);
-INSERT INTO key.decorative_level VALUES(36,6,12,2320);
-INSERT INTO key.decorative_level VALUES(36,7,14,2910);
-INSERT INTO key.decorative_level VALUES(36,8,16,3590);
-INSERT INTO key.decorative_level VALUES(36,9,18,4350);
-INSERT INTO key.decorative_level VALUES(36,10,20,5200);
-INSERT INTO key.decorative_level VALUES(37,1,2,260);
-INSERT INTO key.decorative_level VALUES(37,2,5,410);
-INSERT INTO key.decorative_level VALUES(37,3,7,700);
-INSERT INTO key.decorative_level VALUES(37,4,9,1080);
-INSERT INTO key.decorative_level VALUES(37,5,12,1560);
-INSERT INTO key.decorative_level VALUES(37,6,15,1990);
-INSERT INTO key.decorative_level VALUES(37,7,17,2490);
-INSERT INTO key.decorative_level VALUES(37,8,20,3070);
-INSERT INTO key.decorative_level VALUES(37,9,22,3720);
-INSERT INTO key.decorative_level VALUES(37,10,25,4440);
-INSERT INTO key.decorative_level VALUES(38,1,2,330);
-INSERT INTO key.decorative_level VALUES(38,2,4,540);
-INSERT INTO key.decorative_level VALUES(38,3,6,930);
-INSERT INTO key.decorative_level VALUES(38,4,8,1450);
-INSERT INTO key.decorative_level VALUES(38,5,10,2100);
-INSERT INTO key.decorative_level VALUES(38,6,12,2680);
-INSERT INTO key.decorative_level VALUES(38,7,14,3360);
-INSERT INTO key.decorative_level VALUES(38,8,16,4140);
-INSERT INTO key.decorative_level VALUES(38,9,18,5020);
-INSERT INTO key.decorative_level VALUES(38,10,20,5990);
-INSERT INTO key.decorative_level VALUES(39,1,2,300);
-INSERT INTO key.decorative_level VALUES(39,2,4,460);
-INSERT INTO key.decorative_level VALUES(39,3,6,760);
-INSERT INTO key.decorative_level VALUES(39,4,8,1160);
-INSERT INTO key.decorative_level VALUES(39,5,10,1670);
-INSERT INTO key.decorative_level VALUES(39,6,12,2130);
-INSERT INTO key.decorative_level VALUES(39,7,14,2660);
-INSERT INTO key.decorative_level VALUES(39,8,16,3270);
-INSERT INTO key.decorative_level VALUES(39,9,18,3960);
-INSERT INTO key.decorative_level VALUES(39,10,20,4720);
-INSERT INTO key.decorative_level VALUES(9,1,2,150);
-INSERT INTO key.decorative_level VALUES(9,2,4,375);
-INSERT INTO key.decorative_level VALUES(9,3,6,600);
-INSERT INTO key.decorative_level VALUES(9,4,8,825);
-INSERT INTO key.decorative_level VALUES(9,5,10,1050);
-INSERT INTO key.decorative_level VALUES(9,6,12,1275);
-INSERT INTO key.decorative_level VALUES(9,7,14,1500);
-INSERT INTO key.decorative_level VALUES(9,8,16,1725);
-INSERT INTO key.decorative_level VALUES(9,9,18,1950);
-INSERT INTO key.decorative_level VALUES(9,10,20,2175);
-INSERT INTO key.decorative_level VALUES(7,1,2,80);
-INSERT INTO key.decorative_level VALUES(7,2,4,130);
-INSERT INTO key.decorative_level VALUES(7,3,6,180);
-INSERT INTO key.decorative_level VALUES(7,4,8,230);
-INSERT INTO key.decorative_level VALUES(7,5,10,280);
-INSERT INTO key.decorative_level VALUES(7,6,12,330);
-INSERT INTO key.decorative_level VALUES(7,7,14,380);
-INSERT INTO key.decorative_level VALUES(7,8,16,430);
-INSERT INTO key.decorative_level VALUES(7,9,18,480);
-INSERT INTO key.decorative_level VALUES(7,10,20,530);
-INSERT INTO key.decorative_level VALUES(34,1,1,80);
-INSERT INTO key.decorative_level VALUES(34,2,2,130);
-INSERT INTO key.decorative_level VALUES(34,3,3,180);
-INSERT INTO key.decorative_level VALUES(34,4,4,230);
-INSERT INTO key.decorative_level VALUES(34,5,5,280);
-INSERT INTO key.decorative_level VALUES(34,6,6,330);
-INSERT INTO key.decorative_level VALUES(34,7,7,380);
-INSERT INTO key.decorative_level VALUES(34,8,8,430);
-INSERT INTO key.decorative_level VALUES(34,9,9,480);
-INSERT INTO key.decorative_level VALUES(34,10,10,530);
-INSERT INTO key.decorative_level VALUES(11,1,3,50);
-INSERT INTO key.decorative_level VALUES(11,2,6,100);
-INSERT INTO key.decorative_level VALUES(11,3,9,150);
-INSERT INTO key.decorative_level VALUES(11,4,12,200);
-INSERT INTO key.decorative_level VALUES(11,5,15,250);
-INSERT INTO key.decorative_level VALUES(11,6,18,300);
-INSERT INTO key.decorative_level VALUES(11,7,21,350);
-INSERT INTO key.decorative_level VALUES(11,8,24,400);
-INSERT INTO key.decorative_level VALUES(11,9,27,450);
-INSERT INTO key.decorative_level VALUES(11,10,30,500);
-INSERT INTO key.decorative_level VALUES(5,1,5,40);
-INSERT INTO key.decorative_level VALUES(5,2,10,90);
-INSERT INTO key.decorative_level VALUES(5,3,15,140);
-INSERT INTO key.decorative_level VALUES(5,4,20,190);
-INSERT INTO key.decorative_level VALUES(5,5,25,240);
-INSERT INTO key.decorative_level VALUES(5,6,30,290);
-INSERT INTO key.decorative_level VALUES(5,7,35,340);
-INSERT INTO key.decorative_level VALUES(5,8,40,390);
-INSERT INTO key.decorative_level VALUES(5,9,45,440);
-INSERT INTO key.decorative_level VALUES(5,10,50,490);
-INSERT INTO key.decorative_level VALUES(10,1,1,30);
-INSERT INTO key.decorative_level VALUES(10,2,2,80);
-INSERT INTO key.decorative_level VALUES(10,3,3,140);
-INSERT INTO key.decorative_level VALUES(10,4,4,200);
-INSERT INTO key.decorative_level VALUES(10,5,5,260);
-INSERT INTO key.decorative_level VALUES(10,6,6,320);
-INSERT INTO key.decorative_level VALUES(10,7,7,380);
-INSERT INTO key.decorative_level VALUES(10,8,8,440);
-INSERT INTO key.decorative_level VALUES(10,9,9,500);
-INSERT INTO key.decorative_level VALUES(10,10,10,560);
-INSERT INTO key.decorative_level VALUES(35,1,200,30);
-INSERT INTO key.decorative_level VALUES(35,2,400,80);
-INSERT INTO key.decorative_level VALUES(35,3,600,130);
-INSERT INTO key.decorative_level VALUES(35,4,800,180);
-INSERT INTO key.decorative_level VALUES(35,5,1000,230);
-INSERT INTO key.decorative_level VALUES(35,6,1200,280);
-INSERT INTO key.decorative_level VALUES(35,7,1400,330);
-INSERT INTO key.decorative_level VALUES(35,8,1600,380);
-INSERT INTO key.decorative_level VALUES(35,9,1800,430);
-INSERT INTO key.decorative_level VALUES(35,10,2000,480);
+INSERT INTO key.decorative_level VALUES(4,1,1,25); -- Guardstone
+INSERT INTO key.decorative_level VALUES(4,2,2,60);
+INSERT INTO key.decorative_level VALUES(4,3,3,95);
+INSERT INTO key.decorative_level VALUES(4,4,4,130);
+INSERT INTO key.decorative_level VALUES(4,5,5,165);
+INSERT INTO key.decorative_level VALUES(4,6,6,200);
+INSERT INTO key.decorative_level VALUES(4,7,7,235);
+INSERT INTO key.decorative_level VALUES(4,8,8,270);
+INSERT INTO key.decorative_level VALUES(4,9,9,305);
+INSERT INTO key.decorative_level VALUES(4,10,10,340);
+INSERT INTO key.decorative_level VALUES(4,11,11,375);
+INSERT INTO key.decorative_level VALUES(4,12,12,410);
+INSERT INTO key.decorative_level VALUES(4,13,13,445);
+INSERT INTO key.decorative_level VALUES(4,14,14,480);
+INSERT INTO key.decorative_level VALUES(4,15,15,515);
+INSERT INTO key.decorative_level VALUES(4,16,16,550);
+INSERT INTO key.decorative_level VALUES(4,17,17,585);
+INSERT INTO key.decorative_level VALUES(4,18,18,620);
+INSERT INTO key.decorative_level VALUES(4,19,19,655);
+INSERT INTO key.decorative_level VALUES(4,20,20,690);
+INSERT INTO key.decorative_level VALUES(15,1,2,45); -- Fire Sanctuary
+INSERT INTO key.decorative_level VALUES(15,2,3,75);
+INSERT INTO key.decorative_level VALUES(15,3,4,95);
+INSERT INTO key.decorative_level VALUES(15,4,5,120);
+INSERT INTO key.decorative_level VALUES(15,5,6,145);
+INSERT INTO key.decorative_level VALUES(15,6,7,170);
+INSERT INTO key.decorative_level VALUES(15,7,8,195);
+INSERT INTO key.decorative_level VALUES(15,8,9,220);
+INSERT INTO key.decorative_level VALUES(15,9,10,245);
+INSERT INTO key.decorative_level VALUES(15,10,11,270);
+INSERT INTO key.decorative_level VALUES(15,11,12,295);
+INSERT INTO key.decorative_level VALUES(15,12,13,320);
+INSERT INTO key.decorative_level VALUES(15,13,14,345);
+INSERT INTO key.decorative_level VALUES(15,14,15,370);
+INSERT INTO key.decorative_level VALUES(15,15,16,395);
+INSERT INTO key.decorative_level VALUES(15,16,17,420);
+INSERT INTO key.decorative_level VALUES(15,17,18,445);
+INSERT INTO key.decorative_level VALUES(15,18,19,470);
+INSERT INTO key.decorative_level VALUES(15,19,20,495);
+INSERT INTO key.decorative_level VALUES(15,20,21,520);
+INSERT INTO key.decorative_level VALUES(16,1,2,45); -- Water Sanctuary
+INSERT INTO key.decorative_level VALUES(16,2,3,75);
+INSERT INTO key.decorative_level VALUES(16,3,4,95);
+INSERT INTO key.decorative_level VALUES(16,4,5,120);
+INSERT INTO key.decorative_level VALUES(16,5,6,145);
+INSERT INTO key.decorative_level VALUES(16,6,7,170);
+INSERT INTO key.decorative_level VALUES(16,7,8,195);
+INSERT INTO key.decorative_level VALUES(16,8,9,220);
+INSERT INTO key.decorative_level VALUES(16,9,10,245);
+INSERT INTO key.decorative_level VALUES(16,10,11,270);
+INSERT INTO key.decorative_level VALUES(16,11,12,295);
+INSERT INTO key.decorative_level VALUES(16,12,13,320);
+INSERT INTO key.decorative_level VALUES(16,13,14,345);
+INSERT INTO key.decorative_level VALUES(16,14,15,370);
+INSERT INTO key.decorative_level VALUES(16,15,16,395);
+INSERT INTO key.decorative_level VALUES(16,16,17,420);
+INSERT INTO key.decorative_level VALUES(16,17,18,445);
+INSERT INTO key.decorative_level VALUES(16,18,19,470);
+INSERT INTO key.decorative_level VALUES(16,19,20,495);
+INSERT INTO key.decorative_level VALUES(16,20,21,520);
+INSERT INTO key.decorative_level VALUES(17,1,2,45); -- Wind Sanctuary
+INSERT INTO key.decorative_level VALUES(17,2,3,75);
+INSERT INTO key.decorative_level VALUES(17,3,4,95);
+INSERT INTO key.decorative_level VALUES(17,4,5,120);
+INSERT INTO key.decorative_level VALUES(17,5,6,145);
+INSERT INTO key.decorative_level VALUES(17,6,7,170);
+INSERT INTO key.decorative_level VALUES(17,7,8,195);
+INSERT INTO key.decorative_level VALUES(17,8,9,220);
+INSERT INTO key.decorative_level VALUES(17,9,10,245);
+INSERT INTO key.decorative_level VALUES(17,10,11,270);
+INSERT INTO key.decorative_level VALUES(17,11,12,295);
+INSERT INTO key.decorative_level VALUES(17,12,13,320);
+INSERT INTO key.decorative_level VALUES(17,13,14,345);
+INSERT INTO key.decorative_level VALUES(17,14,15,370);
+INSERT INTO key.decorative_level VALUES(17,15,16,395);
+INSERT INTO key.decorative_level VALUES(17,16,17,420);
+INSERT INTO key.decorative_level VALUES(17,17,18,445);
+INSERT INTO key.decorative_level VALUES(17,18,19,470);
+INSERT INTO key.decorative_level VALUES(17,19,20,495);
+INSERT INTO key.decorative_level VALUES(17,20,21,520);
+INSERT INTO key.decorative_level VALUES(18,1,2,45); -- Light Sanctuary
+INSERT INTO key.decorative_level VALUES(18,2,3,75);
+INSERT INTO key.decorative_level VALUES(18,3,4,95);
+INSERT INTO key.decorative_level VALUES(18,4,5,120);
+INSERT INTO key.decorative_level VALUES(18,5,6,145);
+INSERT INTO key.decorative_level VALUES(18,6,7,170);
+INSERT INTO key.decorative_level VALUES(18,7,8,195);
+INSERT INTO key.decorative_level VALUES(18,8,9,220);
+INSERT INTO key.decorative_level VALUES(18,9,10,245);
+INSERT INTO key.decorative_level VALUES(18,10,11,270);
+INSERT INTO key.decorative_level VALUES(18,11,12,295);
+INSERT INTO key.decorative_level VALUES(18,12,13,320);
+INSERT INTO key.decorative_level VALUES(18,13,14,345);
+INSERT INTO key.decorative_level VALUES(18,14,15,370);
+INSERT INTO key.decorative_level VALUES(18,15,16,395);
+INSERT INTO key.decorative_level VALUES(18,16,17,420);
+INSERT INTO key.decorative_level VALUES(18,17,18,445);
+INSERT INTO key.decorative_level VALUES(18,18,19,470);
+INSERT INTO key.decorative_level VALUES(18,19,20,495);
+INSERT INTO key.decorative_level VALUES(18,20,21,520);
+INSERT INTO key.decorative_level VALUES(19,1,2,45); -- Dark Sanctuary
+INSERT INTO key.decorative_level VALUES(19,2,3,75);
+INSERT INTO key.decorative_level VALUES(19,3,4,95);
+INSERT INTO key.decorative_level VALUES(19,4,5,120);
+INSERT INTO key.decorative_level VALUES(19,5,6,145);
+INSERT INTO key.decorative_level VALUES(19,6,7,170);
+INSERT INTO key.decorative_level VALUES(19,7,8,195);
+INSERT INTO key.decorative_level VALUES(19,8,9,220);
+INSERT INTO key.decorative_level VALUES(19,9,10,245);
+INSERT INTO key.decorative_level VALUES(19,10,11,270);
+INSERT INTO key.decorative_level VALUES(19,11,12,295);
+INSERT INTO key.decorative_level VALUES(19,12,13,320);
+INSERT INTO key.decorative_level VALUES(19,13,14,345);
+INSERT INTO key.decorative_level VALUES(19,14,15,370);
+INSERT INTO key.decorative_level VALUES(19,15,16,395);
+INSERT INTO key.decorative_level VALUES(19,16,17,420);
+INSERT INTO key.decorative_level VALUES(19,17,18,445);
+INSERT INTO key.decorative_level VALUES(19,18,19,470);
+INSERT INTO key.decorative_level VALUES(19,19,20,495);
+INSERT INTO key.decorative_level VALUES(19,20,21,520);
+INSERT INTO key.decorative_level VALUES(31,1,1,35);  -- Fallen Ancient Guardian
+INSERT INTO key.decorative_level VALUES(31,2,2,60);
+INSERT INTO key.decorative_level VALUES(31,3,3,85);
+INSERT INTO key.decorative_level VALUES(31,4,5,110);
+INSERT INTO key.decorative_level VALUES(31,5,6,135);
+INSERT INTO key.decorative_level VALUES(31,6,7,160);
+INSERT INTO key.decorative_level VALUES(31,7,8,185);
+INSERT INTO key.decorative_level VALUES(31,8,9,210);
+INSERT INTO key.decorative_level VALUES(31,9,10,235);
+INSERT INTO key.decorative_level VALUES(31,10,12,260);
+INSERT INTO key.decorative_level VALUES(31,11,13,285);
+INSERT INTO key.decorative_level VALUES(31,12,15,310);
+INSERT INTO key.decorative_level VALUES(31,13,16,335);
+INSERT INTO key.decorative_level VALUES(31,14,17,360);
+INSERT INTO key.decorative_level VALUES(31,15,18,385);
+INSERT INTO key.decorative_level VALUES(31,16,20,410);
+INSERT INTO key.decorative_level VALUES(31,17,21,435);
+INSERT INTO key.decorative_level VALUES(31,18,22,460);
+INSERT INTO key.decorative_level VALUES(31,19,23,485);
+INSERT INTO key.decorative_level VALUES(31,20,25,510);
+INSERT INTO key.decorative_level VALUES(6,1,2,60); -- Sky tribe totem
+INSERT INTO key.decorative_level VALUES(6,2,3,100);
+INSERT INTO key.decorative_level VALUES(6,2.5,5,140);
+INSERT INTO key.decorative_level VALUES(6,4,3,180);
+INSERT INTO key.decorative_level VALUES(6,5,4,220);
+INSERT INTO key.decorative_level VALUES(6,6,5,260);
+INSERT INTO key.decorative_level VALUES(6,7,5.5,300);
+INSERT INTO key.decorative_level VALUES(6,8,6,340);
+INSERT INTO key.decorative_level VALUES(6,9,7,380);
+INSERT INTO key.decorative_level VALUES(6,10,8,420);
+INSERT INTO key.decorative_level VALUES(6,11,8.5,460);
+INSERT INTO key.decorative_level VALUES(6,12,9,500);
+INSERT INTO key.decorative_level VALUES(6,13,10,540);
+INSERT INTO key.decorative_level VALUES(6,14,11,580);
+INSERT INTO key.decorative_level VALUES(6,15,11.5,620);
+INSERT INTO key.decorative_level VALUES(6,16,12,660);
+INSERT INTO key.decorative_level VALUES(6,17,13,700);
+INSERT INTO key.decorative_level VALUES(6,18,14,740);
+INSERT INTO key.decorative_level VALUES(6,19,14.5,780);
+INSERT INTO key.decorative_level VALUES(6,20,15,820);
+INSERT INTO key.decorative_level VALUES(8,1,1,80);  -- Crystal Altar
+INSERT INTO key.decorative_level VALUES(8,2,2,120);
+INSERT INTO key.decorative_level VALUES(8,3,3,160);
+INSERT INTO key.decorative_level VALUES(8,4,4,200);
+INSERT INTO key.decorative_level VALUES(8,5,5,240);
+INSERT INTO key.decorative_level VALUES(8,6,6,280);
+INSERT INTO key.decorative_level VALUES(8,7,7,320);
+INSERT INTO key.decorative_level VALUES(8,8,8,360);
+INSERT INTO key.decorative_level VALUES(8,9,9,400);
+INSERT INTO key.decorative_level VALUES(8,10,10,440);
+INSERT INTO key.decorative_level VALUES(8,11,11,480);
+INSERT INTO key.decorative_level VALUES(8,12,12,520);
+INSERT INTO key.decorative_level VALUES(8,13,13,560);
+INSERT INTO key.decorative_level VALUES(8,14,14,600);
+INSERT INTO key.decorative_level VALUES(8,15,15,640);
+INSERT INTO key.decorative_level VALUES(8,16,16,680);
+INSERT INTO key.decorative_level VALUES(8,17,17,720);
+INSERT INTO key.decorative_level VALUES(8,18,18,760);
+INSERT INTO key.decorative_level VALUES(8,19,19,800);
+INSERT INTO key.decorative_level VALUES(8,20,20,840);
+INSERT INTO key.decorative_level VALUES(36,1,1,100); -- Flag of battle
+INSERT INTO key.decorative_level VALUES(36,2,2,130);
+INSERT INTO key.decorative_level VALUES(36,3,3,170);
+INSERT INTO key.decorative_level VALUES(36,4,4,220);
+INSERT INTO key.decorative_level VALUES(36,5,5,280);
+INSERT INTO key.decorative_level VALUES(36,6,6,350);
+INSERT INTO key.decorative_level VALUES(36,7,7,430);
+INSERT INTO key.decorative_level VALUES(36,8,8,520);
+INSERT INTO key.decorative_level VALUES(36,9,9,620);
+INSERT INTO key.decorative_level VALUES(36,10,10,730);
+INSERT INTO key.decorative_level VALUES(36,11,11,850);
+INSERT INTO key.decorative_level VALUES(36,12,12,980);
+INSERT INTO key.decorative_level VALUES(36,13,13,1120);
+INSERT INTO key.decorative_level VALUES(36,14,14,1270);
+INSERT INTO key.decorative_level VALUES(36,15,15,1430);
+INSERT INTO key.decorative_level VALUES(36,16,16,1600);
+INSERT INTO key.decorative_level VALUES(36,17,17,1780);
+INSERT INTO key.decorative_level VALUES(36,18,18,1970);
+INSERT INTO key.decorative_level VALUES(36,19,19,2170);
+INSERT INTO key.decorative_level VALUES(36,20,20,2380);
+INSERT INTO key.decorative_level VALUES(37,1,1,60); -- Flag of rage
+INSERT INTO key.decorative_level VALUES(37,2,2,80); 
+INSERT INTO key.decorative_level VALUES(37,3,3,110);
+INSERT INTO key.decorative_level VALUES(37,4,5,150);
+INSERT INTO key.decorative_level VALUES(37,5,6,200);
+INSERT INTO key.decorative_level VALUES(37,6,7,260);
+INSERT INTO key.decorative_level VALUES(37,7,8,330);
+INSERT INTO key.decorative_level VALUES(37,8,9,410);
+INSERT INTO key.decorative_level VALUES(37,9,10,500);
+INSERT INTO key.decorative_level VALUES(37,10,12,600);
+INSERT INTO key.decorative_level VALUES(37,11,13,710);
+INSERT INTO key.decorative_level VALUES(37,12,15,830);
+INSERT INTO key.decorative_level VALUES(37,13,16,960);
+INSERT INTO key.decorative_level VALUES(37,14,17,1100);
+INSERT INTO key.decorative_level VALUES(37,15,18,1250);
+INSERT INTO key.decorative_level VALUES(37,16,20,1410);
+INSERT INTO key.decorative_level VALUES(37,17,21,1580);
+INSERT INTO key.decorative_level VALUES(37,18,22,1760);
+INSERT INTO key.decorative_level VALUES(37,19,23,1950);
+INSERT INTO key.decorative_level VALUES(37,20,25,2150);
+INSERT INTO key.decorative_level VALUES(38,1,1,140); -- Flag of Hope
+INSERT INTO key.decorative_level VALUES(38,2,2,180);
+INSERT INTO key.decorative_level VALUES(38,3,3,230);
+INSERT INTO key.decorative_level VALUES(38,4,4,290);
+INSERT INTO key.decorative_level VALUES(38,5,5,360);
+INSERT INTO key.decorative_level VALUES(38,6,6,440);
+INSERT INTO key.decorative_level VALUES(38,7,7,530);
+INSERT INTO key.decorative_level VALUES(38,8,8,630);
+INSERT INTO key.decorative_level VALUES(38,9,9,740);
+INSERT INTO key.decorative_level VALUES(38,10,10,860);
+INSERT INTO key.decorative_level VALUES(38,11,11,990);
+INSERT INTO key.decorative_level VALUES(38,12,12,1130);
+INSERT INTO key.decorative_level VALUES(38,13,13,1280);
+INSERT INTO key.decorative_level VALUES(38,14,14,1440);
+INSERT INTO key.decorative_level VALUES(38,15,15,1610);
+INSERT INTO key.decorative_level VALUES(38,16,16,1790);
+INSERT INTO key.decorative_level VALUES(38,17,17,1980);
+INSERT INTO key.decorative_level VALUES(38,18,18,2180);
+INSERT INTO key.decorative_level VALUES(38,19,19,2390);
+INSERT INTO key.decorative_level VALUES(38,20,20,2610);
+INSERT INTO key.decorative_level VALUES(39,1,1,110); -- Flag of Will
+INSERT INTO key.decorative_level VALUES(39,2,2,130);
+INSERT INTO key.decorative_level VALUES(39,3,3,160);
+INSERT INTO key.decorative_level VALUES(39,4,4,200);
+INSERT INTO key.decorative_level VALUES(39,5,5,250);
+INSERT INTO key.decorative_level VALUES(39,6,6,310);
+INSERT INTO key.decorative_level VALUES(39,7,7,380);
+INSERT INTO key.decorative_level VALUES(39,8,8,460);
+INSERT INTO key.decorative_level VALUES(39,9,9,550);
+INSERT INTO key.decorative_level VALUES(39,10,10,650);
+INSERT INTO key.decorative_level VALUES(39,11,11,760);
+INSERT INTO key.decorative_level VALUES(39,12,12,880);
+INSERT INTO key.decorative_level VALUES(39,13,13,1010);
+INSERT INTO key.decorative_level VALUES(39,14,14,1150);
+INSERT INTO key.decorative_level VALUES(39,15,15,1300);
+INSERT INTO key.decorative_level VALUES(39,16,16,1460);
+INSERT INTO key.decorative_level VALUES(39,17,17,1630);
+INSERT INTO key.decorative_level VALUES(39,18,18,1810);
+INSERT INTO key.decorative_level VALUES(39,19,19,2000);
+INSERT INTO key.decorative_level VALUES(39,20,20,2200);
+INSERT INTO key.decorative_level VALUES(9,1,1,45); -- Ancient Sword
+INSERT INTO key.decorative_level VALUES(9,2,2,90);
+INSERT INTO key.decorative_level VALUES(9,3,3,135);
+INSERT INTO key.decorative_level VALUES(9,4,4,180);
+INSERT INTO key.decorative_level VALUES(9,5,5,225);
+INSERT INTO key.decorative_level VALUES(9,6,6,270);
+INSERT INTO key.decorative_level VALUES(9,7,7,315);
+INSERT INTO key.decorative_level VALUES(9,8,8,360);
+INSERT INTO key.decorative_level VALUES(9,9,9,405);
+INSERT INTO key.decorative_level VALUES(9,10,10,450);
+INSERT INTO key.decorative_level VALUES(9,11,11,495);
+INSERT INTO key.decorative_level VALUES(9,12,12,540);
+INSERT INTO key.decorative_level VALUES(9,13,13,585);
+INSERT INTO key.decorative_level VALUES(9,14,14,630);
+INSERT INTO key.decorative_level VALUES(9,15,15,675);
+INSERT INTO key.decorative_level VALUES(9,16,16,720);
+INSERT INTO key.decorative_level VALUES(9,17,17,765);
+INSERT INTO key.decorative_level VALUES(9,18,18,810);
+INSERT INTO key.decorative_level VALUES(9,19,19,855);
+INSERT INTO key.decorative_level VALUES(9,20,20,900);
+INSERT INTO key.decorative_level VALUES(7,1,1,30); -- Arcane Booste Tower
+INSERT INTO key.decorative_level VALUES(7,2,2,40);
+INSERT INTO key.decorative_level VALUES(7,3,3,50);
+INSERT INTO key.decorative_level VALUES(7,4,4,60);
+INSERT INTO key.decorative_level VALUES(7,5,5,70);
+INSERT INTO key.decorative_level VALUES(7,6,6,80);
+INSERT INTO key.decorative_level VALUES(7,7,7,90);
+INSERT INTO key.decorative_level VALUES(7,8,8,100);
+INSERT INTO key.decorative_level VALUES(7,9,9,110);
+INSERT INTO key.decorative_level VALUES(7,10,10,120);
+INSERT INTO key.decorative_level VALUES(7,11,11,130);
+INSERT INTO key.decorative_level VALUES(7,12,12,140);
+INSERT INTO key.decorative_level VALUES(7,13,13,150);
+INSERT INTO key.decorative_level VALUES(7,14,14,160);
+INSERT INTO key.decorative_level VALUES(7,15,15,170);
+INSERT INTO key.decorative_level VALUES(7,16,16,180);
+INSERT INTO key.decorative_level VALUES(7,17,17,190);
+INSERT INTO key.decorative_level VALUES(7,18,18,200);
+INSERT INTO key.decorative_level VALUES(7,19,19,210);
+INSERT INTO key.decorative_level VALUES(7,20,20,220);
+INSERT INTO key.decorative_level VALUES(34,1,0.5,30); -- Crystel Rock
+INSERT INTO key.decorative_level VALUES(34,2,1,40);
+INSERT INTO key.decorative_level VALUES(34,3,1.5,50);
+INSERT INTO key.decorative_level VALUES(34,4,2,60);
+INSERT INTO key.decorative_level VALUES(34,5,2.5,70);
+INSERT INTO key.decorative_level VALUES(34,6,3,80);
+INSERT INTO key.decorative_level VALUES(34,7,3.5,90);
+INSERT INTO key.decorative_level VALUES(34,8,4,100);
+INSERT INTO key.decorative_level VALUES(34,9,4.5,110);
+INSERT INTO key.decorative_level VALUES(34,10,5,120);
+INSERT INTO key.decorative_level VALUES(34,11,5.5,130);
+INSERT INTO key.decorative_level VALUES(34,12,6,140);
+INSERT INTO key.decorative_level VALUES(34,13,6.5,150);
+INSERT INTO key.decorative_level VALUES(34,14,7,160);
+INSERT INTO key.decorative_level VALUES(34,15,7.5,170);
+INSERT INTO key.decorative_level VALUES(34,16,8,180);
+INSERT INTO key.decorative_level VALUES(34,17,8.5,190);
+INSERT INTO key.decorative_level VALUES(34,18,9,200);
+INSERT INTO key.decorative_level VALUES(34,19,9.5,210);
+INSERT INTO key.decorative_level VALUES(34,20,10,220);
+INSERT INTO key.decorative_level VALUES(11,1,2,15); -- Mysterious Plant
+INSERT INTO key.decorative_level VALUES(11,2,3,20);
+INSERT INTO key.decorative_level VALUES(11,3,4,25);
+INSERT INTO key.decorative_level VALUES(11,4,6,30);
+INSERT INTO key.decorative_level VALUES(11,5,7,35);
+INSERT INTO key.decorative_level VALUES(11,6,9,40);
+INSERT INTO key.decorative_level VALUES(11,7,10,45);
+INSERT INTO key.decorative_level VALUES(11,8,12,50);
+INSERT INTO key.decorative_level VALUES(11,9,13,55);
+INSERT INTO key.decorative_level VALUES(11,10,15,60);
+INSERT INTO key.decorative_level VALUES(11,11,16,70);
+INSERT INTO key.decorative_level VALUES(11,12,18,80);
+INSERT INTO key.decorative_level VALUES(11,13,19,90);
+INSERT INTO key.decorative_level VALUES(11,14,21,100);
+INSERT INTO key.decorative_level VALUES(11,15,22,110);
+INSERT INTO key.decorative_level VALUES(11,16,24,120);
+INSERT INTO key.decorative_level VALUES(11,17,25,130);
+INSERT INTO key.decorative_level VALUES(11,18,27,140);
+INSERT INTO key.decorative_level VALUES(11,19,28,150);
+INSERT INTO key.decorative_level VALUES(11,20,30,160);
+INSERT INTO key.decorative_level VALUES(5,1,2,10); -- Mana Fountain
+INSERT INTO key.decorative_level VALUES(5,2,5,20);
+INSERT INTO key.decorative_level VALUES(5,3,7,30);
+INSERT INTO key.decorative_level VALUES(5,4,10,40);
+INSERT INTO key.decorative_level VALUES(5,5,12,50);
+INSERT INTO key.decorative_level VALUES(5,6,15,60);
+INSERT INTO key.decorative_level VALUES(5,7,17,70);
+INSERT INTO key.decorative_level VALUES(5,8,20,80);
+INSERT INTO key.decorative_level VALUES(5,9,22,90);
+INSERT INTO key.decorative_level VALUES(5,10,25,100);
+INSERT INTO key.decorative_level VALUES(5,11,27,110);
+INSERT INTO key.decorative_level VALUES(5,12,30,120);
+INSERT INTO key.decorative_level VALUES(5,13,32,130);
+INSERT INTO key.decorative_level VALUES(5,14,35,140);
+INSERT INTO key.decorative_level VALUES(5,15,37,150);
+INSERT INTO key.decorative_level VALUES(5,16,40,160);
+INSERT INTO key.decorative_level VALUES(5,17,42,170);
+INSERT INTO key.decorative_level VALUES(5,18,45,180);
+INSERT INTO key.decorative_level VALUES(5,19,47,190);
+INSERT INTO key.decorative_level VALUES(5,20,50,200);
+INSERT INTO key.decorative_level VALUES(10,1,1,55); -- Sanctum of energy
+INSERT INTO key.decorative_level VALUES(10,2,2,60);
+INSERT INTO key.decorative_level VALUES(10,3,3,65);
+INSERT INTO key.decorative_level VALUES(10,4,4,70);
+INSERT INTO key.decorative_level VALUES(10,5,5,75);
+INSERT INTO key.decorative_level VALUES(10,6,6,80);
+INSERT INTO key.decorative_level VALUES(10,7,7,85);
+INSERT INTO key.decorative_level VALUES(10,8,8,90);
+INSERT INTO key.decorative_level VALUES(10,9,9,95);
+INSERT INTO key.decorative_level VALUES(10,10,10,100);
+INSERT INTO key.decorative_level VALUES(10,11,11,105);
+INSERT INTO key.decorative_level VALUES(10,12,12,110);
+INSERT INTO key.decorative_level VALUES(10,13,13,115);
+INSERT INTO key.decorative_level VALUES(10,14,14,120);
+INSERT INTO key.decorative_level VALUES(10,15,15,125);
+INSERT INTO key.decorative_level VALUES(10,16,16,130);
+INSERT INTO key.decorative_level VALUES(10,17,17,135);
+INSERT INTO key.decorative_level VALUES(10,18,18,140);
+INSERT INTO key.decorative_level VALUES(10,19,19,145);
+INSERT INTO key.decorative_level VALUES(10,20,20,150);
+INSERT INTO key.decorative_level VALUES(35,1,100,10); -- Fairy tree
+INSERT INTO key.decorative_level VALUES(35,2,200,20);
+INSERT INTO key.decorative_level VALUES(35,3,300,30);
+INSERT INTO key.decorative_level VALUES(35,4,400,40);
+INSERT INTO key.decorative_level VALUES(35,5,500,50);
+INSERT INTO key.decorative_level VALUES(35,6,600,60);
+INSERT INTO key.decorative_level VALUES(35,7,700,70);
+INSERT INTO key.decorative_level VALUES(35,8,800,80);
+INSERT INTO key.decorative_level VALUES(35,9,900,90);
+INSERT INTO key.decorative_level VALUES(35,10,1000,100);
+INSERT INTO key.decorative_level VALUES(35,11,1100,110);
+INSERT INTO key.decorative_level VALUES(35,12,1200,120);
+INSERT INTO key.decorative_level VALUES(35,13,1300,130);
+INSERT INTO key.decorative_level VALUES(35,14,1400,140);
+INSERT INTO key.decorative_level VALUES(35,15,1500,150);
+INSERT INTO key.decorative_level VALUES(35,16,1600,160);
+INSERT INTO key.decorative_level VALUES(35,17,1700,170);
+INSERT INTO key.decorative_level VALUES(35,18,1800,180);
+INSERT INTO key.decorative_level VALUES(35,19,1900,190);
+INSERT INTO key.decorative_level VALUES(35,20,2000,200);
 INSERT INTO key.effect VALUES(1,'Increase ATK',1,'Attack Power is increased by 50%');
 INSERT INTO key.effect VALUES(2,'Increase DEF',1,'Defense is increased by 70%');
 INSERT INTO key.effect VALUES(3,'Increase CRI Rate',1,'Critical Hit Rate is increased by 30%');

+ 3 - 0
public/css/monster_info.css

@@ -7,6 +7,9 @@ aside div.monster_panel{
     font-size: 70%;
 }
 
+aside nav#family div.monster_panel{
+    font-size: 50%;
+}
 section h2 span.family{
     float: right;
 }

+ 2 - 1
public/css/optimizer.css

@@ -247,7 +247,8 @@ section#parameters td#log div#log_title span#log_clear{
     font-size: 90%;
 }
 section#parameters td#log div#log_window{
-    height: 6.5em;
+    padding-top: 1.5em;
+    height: 5em;
     overflow-y: scroll;
     scrollbar-width: thin;
 }