Selaa lähdekoodia

Standalone server. Better installer. Searchable catalog. CSS fixes.

Iñigo Valentin 8 vuotta sitten
vanhempi
sitoutus
ff0b40388a

+ 4 - 0
.gitignore

@@ -7,6 +7,10 @@ install-*
 install_*
 private.sql
 
+# Autogenerated files
+.php_pid
+*.log
+
 #IDE / OS files
 .kateproject.d/
 .kateproject

+ 4 - 1
application/Controller.php

@@ -50,7 +50,7 @@
 
             // Select the model to load.
             if (sizeof($pars) == 0){
-                $page = new Home_Page($db, $lang);
+                $page = new Home_Page($db);
             }
             else{
                 if (strtoupper($pars[0]) == "FUSION"){
@@ -75,6 +75,9 @@
                     elseif (strtoupper($pars[1]) == "CATALOG"){
                         $page = new Catalog_Catalog_Frame($db, $_POST);
                     }
+                    elseif (strtoupper($pars[1]) == "CATALOG_LIST"){
+                        $page = new Catalog_List_Frame($db, $_POST);
+                    }
                 }
                 elseif (strtoupper($pars[0]) == "HANDLER"){
                     if (strtoupper($pars[1]) == "MONSTER_COLLECTION"){

+ 1 - 1
application/config.php

@@ -4,7 +4,7 @@
 
     $root = get_protocol() . $_SERVER["HTTP_HOST"] . "/";
 
-    $base_dir = $_SERVER["DOCUMENT_ROOT"];
+    $base_dir = $_SERVER["DOCUMENT_ROOT"] . "/";
 
     $path = [
         "img" => [

+ 1 - 3
application/entity/Monster.php

@@ -104,9 +104,7 @@
               "SELECT " .
               "  id " .
               "FROM monster_skill " .
-              "WHERE " .
-              "  monster = $id AND" .
-              "  upgrade IS NULL " .
+              "WHERE monster = $id " .
               "ORDER BY idx; ";
             error_log($s);
             $q = $this->db->query($s);

+ 1 - 0
application/entity/Monster_Skill.php

@@ -94,6 +94,7 @@
                 $this->img = $path["img"]["skill"] . $r["img"];
                 $this->cooldown = $r["cooldown"];
                 if ($r["upgrade"] != 0){
+                    error_log("UPGRADE: " . $this->id . " -> " . $r["upgrade"]);
                     $this->upgrade = new Monster_Skill($this->db, $r["upgrade"]);
                 }
             }

+ 5 - 35
application/page/Catalog_Page.php

@@ -8,12 +8,10 @@
      */
     class Catalog_Page extends Page{
 
-
         /**
-         * List of all the monsters in the database.
+         * List of all monster types.
          */
-        public $entry = [];
-
+        public $types = [];
 
         /**
          * Constructor.
@@ -27,45 +25,17 @@
             global $root;
             parent::__construct($db);
             $this->view = $path["view"] . "catalog.php";
-            $s =
-              "SELECT id, " .
-              "  element, " .
-              "  name, " .
-              "  img, " .
-              "  img_aw, " .
-              "  stars, " .
-              "  awakeable, " .
-              "  ( " .
-              "    SELECT count(id) > 0 " .
-              "    FROM monster_collection " .
-              "    WHERE monster = monster.id " .
-              "  ) AS owned " .
-              "FROM monster " .
-              "ORDER BY " .
-              "  element, " .
-              "  stars, " .
-              "  awakeable ";
+            $s = "SELECT DISTINCT type FROM monster;";
             $q = $this->db->query($s);
-            error_log($s);
             while ($r = $q->fetchArray(SQLITE3_ASSOC)){
-                $mon = [
-                    "id" => $r["id"],
-                    "element" => $r["element"],
-                    "name" => $r["name"],
-                    "image" => $path["img"]["monster"] . $r["img"],
-                    "image_aw" => $path["img"]["monster"] . $r["img_aw"],
-                    "stars" => $r["stars"],
-                    "awakeable" => $r["awakeable"],
-                    "owned" => $r["owned"],
-                ];
-                array_push($this->entry, $mon);
+                array_push($this->types, $r["type"]);
             }
             $this->title = "Catalog - SWDB";
             $this->name = "SWDB";
             $this->description = "Catalog of all monsters";
             $this->favicon = "";
             $this->icon = "";
-            $this->canonical = $root . "/catalog/";
+            $this->canonical = $root . "catalog/";
             $this->author = $root;
         }
     }

+ 2 - 2
application/page/Collection_Page.php

@@ -40,8 +40,8 @@
             $this->description = "";
             $this->favicon = "";
             $this->icon = "";
-            $this->canonical = $root . "/collection/";
-            $this->author = $root . "/collection/";
+            $this->canonical = $root . "collection/";
+            $this->author = $root;
         }
     }
 ?>

+ 2 - 2
application/page/Fusion_Page.php

@@ -56,8 +56,8 @@
             $this->description = "";
             $this->favicon = "";
             $this->icon = "";
-            $this->canonical = $root . "/fusion/";
-            $this->author = $root . "/fusion/";
+            $this->canonical = $root . "fusion/";
+            $this->author = $root;
         }
     }
 ?>

+ 91 - 0
application/page/frame/Catalog_List_Frame.php

@@ -0,0 +1,91 @@
+<?php
+
+    require_once($path["frame"] . "Frame.php");
+
+
+    /**
+     * Catalog's page monster list.
+     */
+    class Catalog_List_Frame extends Frame{
+
+        /**
+         * List of all the monsters in the database.
+         */
+        public $entry = [];
+
+
+        /**
+         * Constructor.
+         *
+         * Retrieves the data and initializes the variables.
+         *
+         * @param SQLite3 $db Connection to the database.
+         * @param Array $params Parameters array. May contain the 'selected' parameter
+         *                      to mark a monster as selected.
+         */
+        public function __construct($db, $params){
+            global $path;
+            parent::__construct($db);
+            $this->view = $path["view"] . "frame/catalog_list.php";
+
+            $w_name = "1 = 1";
+            $w_type = "1 = 1";
+            $w_element = "1 = 1";
+            $w_min_stars = "1 = 1";
+            $w_max_stars = "1 = 1";
+            if (isset($params["name"])){
+                $w_name = "(name LIKE '%" . $params["name"] . "%' OR name_aw LIKE '%" . $params["name"] . "%')";
+            }
+            if (isset($params["type"])){
+                $w_type = "type = '" . $params["type"] . "'";
+            }
+            if (isset($params["element"])){
+                $w_element = "element = '" . $params["element"] . "'";
+            }
+            if (isset($params["minstars"]) && intval($params["minstars"]) > 0 && intval($params["minstars"]) < 7){
+                $w_min_stars = "stars >= " . $params["minstars"];
+            }
+            if (isset($params["maxstars"]) && intval($params["maxstars"]) > 0 && intval($params["maxstars"]) < 7){
+                $w_max_stars = "stars <= " . $params["maxstars"];
+            }
+            $s =
+              "SELECT id, " .
+              "  element, " .
+              "  name, " .
+              "  img, " .
+              "  img_aw, " .
+              "  stars, " .
+              "  awakeable, " .
+              "  ( " .
+              "    SELECT count(id) > 0 " .
+              "    FROM monster_collection " .
+              "    WHERE monster = monster.id " .
+              "  ) AS owned " .
+              "FROM monster " .
+              "WHERE " .
+              "  $w_name AND " .
+              "  $w_type AND " .
+              "  $w_element AND " .
+              "  $w_min_stars AND " .
+              "  $w_max_stars " .
+              "ORDER BY " .
+              "  element, " .
+              "  stars, " .
+              "  awakeable ";
+            $q = $this->db->query($s);
+            while ($r = $q->fetchArray(SQLITE3_ASSOC)){
+                $mon = [
+                    "id" => $r["id"],
+                    "element" => $r["element"],
+                    "name" => $r["name"],
+                    "image" => $path["img"]["monster"] . $r["img"],
+                    "image_aw" => $path["img"]["monster"] . $r["img_aw"],
+                    "stars" => $r["stars"],
+                    "awakeable" => $r["awakeable"],
+                    "owned" => $r["owned"],
+                ];
+                array_push($this->entry, $mon);
+            }
+        }
+    }
+?>

+ 42 - 33
application/view/catalog.php

@@ -31,7 +31,7 @@
         <meta name='twitter:url' content='<?=$page->canonical?>'/>
         <meta name='robots' content='index follow'/>
     </head>
-    <body>
+    <body onLoad='loadCatalog();'>
 <?php
         include __DIR__ . "/inc/header.php";
 ?>
@@ -40,43 +40,52 @@
                 <h3 class='section_title'>
                     Monster catalog
                 </h3>
-                <!-- TODO Filters -->
                 <div id='filters'>
-                    Element:
-                    <select>
-                        <option value=''></option>
-                </div>
-                <div id='catalog'>
-<?php
-                    foreach ($page->entry as $mon){
-                        $star_src = $path["img"]["layout"] . "icon/star.png";
-                        if ($mon["awakeable"] == 0){
-                            $monster_src = $collection->monster->image_aw;
-                            $star_src = $path["img"]["layout"] . "icon/star_silver.png";
-                        }
-                        $unowned = "";
-                        if ($mon["owned"] == 0){
-                            $unowned = "unowned";
-                        }
-?>
-                        <div class='monster <?=$unowned?>'>
-                            <a href='javascript:selectMonster(<?=$mon["id"]?>);'>
-                                <span class='stars'>
+                    <div class='filter'>
+                        Element:
+                        <br/>
+                        <select id='filter_element'>
+                            <option value=''>All</option>
+                            <option value='Fire'>Fire</option>
+                            <option value='Water'>Water</option>
+                            <option value='Wind'>Wind</option>
+                            <option value='Light'>Light</option>
+                            <option value='Dark'>Dark</option>
+                        </select>
+                    </div>
+                    <div class='filter'>
+                        Type:
+                        <br/>
+                        <select id='filter_type'>
+                            <option value=''>All</option>
 <?php
-                                    for ($i = 0; $i < $mon["stars"]; $i ++){
+                            foreach ($page->types as $t){
 ?>
-                                        <img class='star' src='<?=$star_src?>'/>
+                                <option value='<?=$t?>'><?=$t?></option>
 <?php
-                                    }
+                            }
 ?>
-                                </span>
-                                <img class='monster border_<?=$mon["element"]?>' src='<?=$mon["image"]?>'/>
-                            </a>
-                        </div>
-<?php
-                    }
-?>
-                </div> <!-- #collection -->
+                        </select>
+                    </div>
+                    <div class='filter'>
+                        Name:
+                        <br/>
+                        <input type='text' id='filter_name'/>
+                    </div>
+                    <div class='filter' id='filter_stars'>
+                        Min. stars:
+                        <input type='number' id='filter_stars_min' min='1' max='6' value='1'/>
+                        <br/>
+                        Max. stars:
+                        <input type='number' id='filter_stars_max' min='1' max='6' value='6'/>
+                    </div>
+                    <div id='filter_apply'>
+                        <input type='button' value='Apply' onClick='loadCatalog();'>
+                    </div>
+                </div>
+                <div id='catalog'>
+                    <img class='loader' alt='Loading...' src='<?$path["img"]["layout"]?>control/loader.png'/>
+                </div> <!-- #catalog -->
             </div> <!-- .section -->
         </div> <!-- .content -->
         <div id='cover'></div>

+ 3 - 3
application/view/collection.php

@@ -84,7 +84,7 @@
                             <option value="Light">Light</option>
                         </select>
                     </td>
-                <tr>
+                </tr>
                 <tr>
                     <td colspan='2' class='center'>
                         <span id='new_frame'>
@@ -92,15 +92,15 @@
                         </span>
                     </td>
                 </tr>
-                </tr>
+                <tr>
                     <td class='left'>
                         Stars:
                     </td>
                     <td class='right'>
                         <input id='new_stars' value='3' type='number' min='1' max='6'/>
                     </td>
-                <tr>
                 </tr>
+                <tr>
                     <td class='left'>
                         Level:
                     </td>

+ 35 - 3
application/view/frame/catalog.php

@@ -6,8 +6,18 @@
     <table id='monster_header'>
         <tr>
             <td>
-                <img id='monster_img' class='monster_img border_<?=$page->element?>' src='<?=$page->img?>'/>
-                <img id='monster_img_aw' class='monster_img border_<?=$page->element?>' src='<?=$page->img_aw?>'/>
+<?php
+                if ($page->awakeable == 0 || $page->awakeable == 1){
+?>
+                    <img id='monster_img' class='monster_img border_<?=$page->element?>' src='<?=$page->img?>'/>
+<?php
+                }
+                if ($page->awakeable == 1 || $page->awakeable == 2){
+?>
+                    <img id='monster_img_aw' class='monster_img border_<?=$page->element?>' src='<?=$page->img_aw?>'/>
+<?php
+                }
+?>
             <td/>
             <td>
                 <h3 id='section-title'>
@@ -15,9 +25,16 @@
                 </h3>
                 <div id='monster_stars'>
 <?php
+                    $star_src = $path["img"]["layout"] . "icon/star.png";
+                    if ($page->awakeable == 0){
+                        $star_src = $path["img"]["layout"] . "icon/star_silver.png";
+                    }
+                    elseif ($page->awakeable == 2){
+                        $star_src = $path["img"]["layout"] . "icon/star_aw.png";
+                    }
                     for ($i = 1; $i <= $page->stars; $i++){
 ?>
-                        <img class='monster_star' src='<?=($path["img"]["layout"] . "icon/star.png")?>'/>
+                        <img class='monster_star' src='<?=$star_src?>'/>
 <?php
                     }
 ?>
@@ -48,6 +65,21 @@
                             <?=$skill->desc?>
                         </span>
                     </span>
+<?php
+                    if (isset($skill->upgrade)){
+?>
+                        <span class='skill_image skill_image_upgrade'>
+                            <img class='skill_image skill_awaken' src='<?=$skill->upgrade->img?>' alt=''/>
+                            <span class='skill_tooltip'>
+                                <img class='skill_tooltip_image skill_awaken' src='<?=$skill->upgrade->img?>' alt=''/>
+                                <span class='skill_tooltip_title'><?=$skill->upgrade->name?></span>
+                                <br/>
+                                <?=$skill->upgrade->desc?>
+                            </span>
+                        </span>
+<?php
+                    }
+?>
                     <span class='skill_name <?=$skill_awaken?> <?=$skill_leader?>'><?=$skill->name?></span>
                 </td>
 <?php

+ 33 - 0
application/view/frame/catalog_list.php

@@ -0,0 +1,33 @@
+<?php
+    foreach ($page->entry as $mon){
+        $star_src = $path["img"]["layout"] . "icon/star.png";
+        $monster_src = $monster_src = $mon["image"];
+        if ($mon["awakeable"] == 0){
+            $star_src = $path["img"]["layout"] . "icon/star_silver.png";
+        }
+        elseif ($mon["awakeable"] == 2){
+            $star_src = $path["img"]["layout"] . "icon/star_aw.png";
+            $monster_src = $mon["image_aw"];
+        }
+        $unowned = "";
+        if ($mon["owned"] == 0){
+            $unowneds = "unowned";
+        }
+?>
+        <div class='monster <?=$unowned?>'>
+            <a href='javascript:selectMonster(<?=$mon["id"]?>);'>
+                <span class='stars'>
+<?php
+                    for ($i = 0; $i < $mon["stars"]; $i ++){
+?>
+                        <img class='star' src='<?=$star_src?>'/>
+<?php
+                    }
+?>
+                </span>
+                <img class='monster border_<?=$mon["element"]?>' src='<?=$monster_src?>'/>
+            </a>
+        </div>
+<?php
+    }
+?>

+ 11 - 0
config

@@ -0,0 +1,11 @@
+# Port number
+# Required
+port=80;
+
+# Server visibility.
+# If set to yes, it will be accesible from the outside (tipically, only from 
+# your LAN). If set to no, only from the local host.
+#
+# Values: yes, no
+# Default: yes
+server_public=yes;

+ 106 - 101
install

@@ -496,107 +496,111 @@ def parseMonster(db, url, element):
         mtype = details[5]
         stars = details[6]
 
-        # Regions where the monster can be obtained
-        obtainablePage = mpage[mpage.index('<b>Obtainable from:</b>'):mpage.index('</td>', mpage.index('<b>Obtainable from:</b>'))]
-        obtainable = getObtainable(obtainablePage)
-
-        # Essences required to awaken the monster
-        if awakeable == 1:
-            essencesPage = mpage[mpage.index('<div id="essences">'):mpage.index('</table>', mpage.index('<div id="essences">'))]
-            essences = getEssences(essencesPage)
-
-        # Skills
-        skillsPage = mpage[mpage.index('<table', mpage.index('<table', mpage.index('<div id="skills">') + 1) + 1):mpage.index('</table>', mpage.index('<table', mpage.index('<table', mpage.index('<div id="skills">') + 1) + 1))]
-        skills = getSkills(skillsPage)
-
-        # Stats
-        statsPage = mpage[mpage.index('Evolution Stats'):]
-        stats = getStats(statsPage, awakeable)
-        ahp = stats[0]
-        aatk = stats[1]
-        adef = stats[2]
-        wahp = stats[3]
-        waatk = stats[4]
-        wadef = stats[5]
-        spd = stats[6]
-        crir = stats[7]
-        crid = stats[8]
-        res = stats[9]
-        acc = stats[10]
-        wspd = stats[11]
-        wcrir = stats[12]
-        wcrid = stats[13]
-        wres = stats[14]
-        wacc = stats[15]
-
-        # Save monster
-        strname = element  + ' ' + name + " - " + name_aw
-        if awakeable == 0:
-            strname = element  + ' ' + name
-        elif awakeable == 2:
-            strname = name_aw
-        print ("    Saving monster: " + strname + "...")
-        if img != '':
-            if download(img, 'public/img/content/monster/' + str(id["monster"]).zfill(3) + '.png'):
-                img = str(id["monster"]).zfill(3) + '.png'
-            else:
-                print("Error downloading image for monster " + str(id["monster"]))
-        if img != '':
-            if download(img_aw, 'public/img/content/monster/' + str(id["monster"]).zfill(3) + '_aw.png'):
-                img_aw = str(id["monster"]).zfill(3) + '_aw.png'
-            else:
-                print("Error downloading image for awakened monster " + str(id["monster"]))
-        insert(db, 'monster', (id["monster"], None, stars, element, name, name_aw, mtype, awakeable, img, img_aw))
-
-        # Save locations
-        for o in obtainable:
-            insert(db, 'monster_location', (id["monster"], o))
-        for e in essences:
-            insert(db, 'monster_essence', (id["monster"], e[1], e[2], e[0]))
-
-        # Save skills
-        idx = 0
-        for s in skills:
-            #                0    1    2       3      4       5      6   7
-            # id monster idx name desc passive awaken upgrade leader img cooldown
-            if download(s[6], 'public/img/content/skill/' + str(id["monster_skill"]).zfill(4) + '.png'):
-                s[6] = str(id["monster_skill"]).zfill(4) + '.png'
-            else:
-                s[6] = ''
-            if s[4] == 1:
-                s[4] = id["monster_skill"] - 1
-            insert(db, 'monster_skill', (id["monster_skill"], id["monster"], idx, s[0], s[1], s[2], s[3], None, s[5], s[6], s[7]))
-            idx = idx + 1
-            id["monster_skill"] = id["monster_skill"] + 1
-
-        # Save stats
-        i = 0
-        s = stars
-        while i < len(ahp):
-            if i + 1 < len(ahp):
-                insert(db, 'monster_stat', (id["monster"], s, 0, 'HP', ahp[i], ahp[i + 1]))
-                insert(db, 'monster_stat', (id["monster"], s, 0, 'ATK', aatk[i], aatk[i + 1]))
-                insert(db, 'monster_stat', (id["monster"], s, 0, 'DEF', aatk[i], aatk[i + 1]))
-                insert(db, 'monster_stat', (id["monster"], s, 0, 'SPD', spd, spd))
-                insert(db, 'monster_stat', (id["monster"], s, 0, 'CRIR', crir, crir))
-                insert(db, 'monster_stat', (id["monster"], s, 0, 'CRID', crid, crid))
-                insert(db, 'monster_stat', (id["monster"], s, 0, 'RES', res, res))
-                insert(db, 'monster_stat', (id["monster"], s, 0, 'ACC', acc, acc))
-            if i + 1 < len(wahp):
-                insert(db, 'monster_stat', (id["monster"], s, 1, 'HP', wahp[i], wahp[i + 1]))
-                insert(db, 'monster_stat', (id["monster"], s, 1, 'ATK', waatk[i], waatk[i + 1]))
-                insert(db, 'monster_stat', (id["monster"], s, 1, 'DEF', waatk[i], waatk[i + 1]))
-                insert(db, 'monster_stat', (id["monster"], s, 1, 'SPD', wspd, wspd))
-                insert(db, 'monster_stat', (id["monster"], s, 1, 'CRIR', wcrir, wcrir))
-                insert(db, 'monster_stat', (id["monster"], s, 1, 'CRID', wcrid, wcrid))
-                insert(db, 'monster_stat', (id["monster"], s, 1, 'RES', wres, wres))
-                insert(db, 'monster_stat', (id["monster"], s, 1, 'ACC', wacc, wacc))
-            s = s + 1
-            i = i + 2
-
-        # Save and proceed
-        db.commit()
-        id["monster"] = id["monster"] + 1
+        # Check if monster already parsed
+        cursor.execute('SELECT count(id) AS c FROM monster WHERE element = ? AND name = ? AND name_aw = ?', (element, name, name_aw))
+        if cursor.fetchone()[0] == 0:
+
+            # Regions where the monster can be obtained
+            obtainablePage = mpage[mpage.index('<b>Obtainable from:</b>'):mpage.index('</td>', mpage.index('<b>Obtainable from:</b>'))]
+            obtainable = getObtainable(obtainablePage)
+
+            # Essences required to awaken the monster
+            if awakeable == 1:
+                essencesPage = mpage[mpage.index('<div id="essences">'):mpage.index('</table>', mpage.index('<div id="essences">'))]
+                essences = getEssences(essencesPage)
+
+            # Skills
+            skillsPage = mpage[mpage.index('<table', mpage.index('<table', mpage.index('<div id="skills">') + 1) + 1):mpage.index('</table>', mpage.index('<table', mpage.index('<table', mpage.index('<div id="skills">') + 1) + 1))]
+            skills = getSkills(skillsPage)
+
+            # Stats
+            statsPage = mpage[mpage.index('Evolution Stats'):]
+            stats = getStats(statsPage, awakeable)
+            ahp = stats[0]
+            aatk = stats[1]
+            adef = stats[2]
+            wahp = stats[3]
+            waatk = stats[4]
+            wadef = stats[5]
+            spd = stats[6]
+            crir = stats[7]
+            crid = stats[8]
+            res = stats[9]
+            acc = stats[10]
+            wspd = stats[11]
+            wcrir = stats[12]
+            wcrid = stats[13]
+            wres = stats[14]
+            wacc = stats[15]
+
+            # Save monster
+            strname = element  + ' ' + name + " - " + name_aw
+            if awakeable == 0:
+                strname = element  + ' ' + name
+            elif awakeable == 2:
+                strname = name_aw
+            print ("    Saving monster: " + strname + "...")
+            if img != '':
+                if download(img, 'public/img/content/monster/' + str(id["monster"]).zfill(3) + '.png'):
+                    img = str(id["monster"]).zfill(3) + '.png'
+                else:
+                    print("Error downloading image for monster " + str(id["monster"]))
+            if img != '':
+                if download(img_aw, 'public/img/content/monster/' + str(id["monster"]).zfill(3) + '_aw.png'):
+                    img_aw = str(id["monster"]).zfill(3) + '_aw.png'
+                else:
+                    print("Error downloading image for awakened monster " + str(id["monster"]))
+            insert(db, 'monster', (id["monster"], None, stars, element, name, name_aw, mtype, awakeable, img, img_aw))
+
+            # Save locations
+            for o in obtainable:
+                insert(db, 'monster_location', (id["monster"], o))
+            for e in essences:
+                insert(db, 'monster_essence', (id["monster"], e[1], e[2], e[0]))
+
+            # Save skills
+            idx = 0
+            for s in skills:
+                #                0    1    2       3      4       5      6   7
+                # id monster idx name desc passive awaken upgrade leader img cooldown
+                if download(s[6], 'public/img/content/skill/' + str(id["monster_skill"]).zfill(4) + '.png'):
+                    s[6] = str(id["monster_skill"]).zfill(4) + '.png'
+                else:
+                    s[6] = ''
+                if s[4] == 1:
+                    s[4] = id["monster_skill"] - 1
+                insert(db, 'monster_skill', (id["monster_skill"], id["monster"], idx, s[0], s[1], s[2], s[3], None, s[5], s[6], s[7]))
+                idx = idx + 1
+                id["monster_skill"] = id["monster_skill"] + 1
+
+            # Save stats
+            i = 0
+            s = stars
+            while i < len(ahp):
+                if i + 1 < len(ahp):
+                    insert(db, 'monster_stat', (id["monster"], s, 0, 'HP', ahp[i], ahp[i + 1]))
+                    insert(db, 'monster_stat', (id["monster"], s, 0, 'ATK', aatk[i], aatk[i + 1]))
+                    insert(db, 'monster_stat', (id["monster"], s, 0, 'DEF', aatk[i], aatk[i + 1]))
+                    insert(db, 'monster_stat', (id["monster"], s, 0, 'SPD', spd, spd))
+                    insert(db, 'monster_stat', (id["monster"], s, 0, 'CRIR', crir, crir))
+                    insert(db, 'monster_stat', (id["monster"], s, 0, 'CRID', crid, crid))
+                    insert(db, 'monster_stat', (id["monster"], s, 0, 'RES', res, res))
+                    insert(db, 'monster_stat', (id["monster"], s, 0, 'ACC', acc, acc))
+                if i + 1 < len(wahp):
+                    insert(db, 'monster_stat', (id["monster"], s, 1, 'HP', wahp[i], wahp[i + 1]))
+                    insert(db, 'monster_stat', (id["monster"], s, 1, 'ATK', waatk[i], waatk[i + 1]))
+                    insert(db, 'monster_stat', (id["monster"], s, 1, 'DEF', waatk[i], waatk[i + 1]))
+                    insert(db, 'monster_stat', (id["monster"], s, 1, 'SPD', wspd, wspd))
+                    insert(db, 'monster_stat', (id["monster"], s, 1, 'CRIR', wcrir, wcrir))
+                    insert(db, 'monster_stat', (id["monster"], s, 1, 'CRID', wcrid, wcrid))
+                    insert(db, 'monster_stat', (id["monster"], s, 1, 'RES', wres, wres))
+                    insert(db, 'monster_stat', (id["monster"], s, 1, 'ACC', wacc, wacc))
+                s = s + 1
+                i = i + 2
+
+            # Save and proceed
+            db.commit()
+            id["monster"] = id["monster"] + 1
 
     except IOError as e:
         db.rollback()
@@ -737,6 +741,7 @@ def parse(db, baseUrl, elements):
     # Detect upgrade skills
     cursor = db.cursor()
     cursor.execute('UPDATE monster_skill SET upgrade = id + 1 WHERE name = (SELECT name FROM monster_skill s WHERE s.id = monster_skill.id + 1)')
+    cursor.execute('UPDATE monster_skill SET monster = null WHERE id IN (SELECT upgrade FROM monster_skill);')
     cursor.close;
 
     # Get essence icons

+ 67 - 8
public/css/catalog.css

@@ -1,3 +1,28 @@
+div#filters{
+    width: 80%;
+    text-align:center;
+    margin: 1em auto 2em auto;
+    border: 0.1em solid #000000;
+    border-radius: 0.5em;
+    background-color: #aa8866;
+}
+div#filters div.filter{
+    vertical-align: top;
+    margin: 0.7em;
+    display: inline-block;
+    text-align: center;
+}
+div#filters div.filter input{
+    margin-top: 0.5em;
+}
+div#filters div#filter_stars input{
+    width: 3em;
+}
+div#filters div#filter_apply{
+    text-align: center;
+    margin: 2em auto 1em auto;
+}
+
 div#catalog{
     display: block;
     width: 80%;
@@ -20,7 +45,7 @@ div#catalog div.monster{
     border-radius: 15%;
 }
 
-div#catalog div.monster{
+div#catalog div.monster.unowned{
     background-color: #000000;
     filter: brightness(50%);
 }
@@ -91,7 +116,7 @@ div#viewer{
     div#viewer{
         width: 90%;
         height: 90%;
-        left: 5%;
+        left: 3%;
         top: 5%;
     }
 }
@@ -115,6 +140,11 @@ div#viewer div#viewer_info table#monster_header{
     margin: auto;
     border-collapse: collapse;
 }
+@media screen and (max-width : 990px){
+    div#viewer div#viewer_info table#monster_header{
+        width: 100%;
+    }
+}
 
 div#viewer div#viewer_info table#monster_header img.monster_img{
     width: 6.5em;
@@ -126,10 +156,11 @@ div#viewer div#viewer_info table#monster_header img.monster_img{
 }
 @media screen and (max-width : 990px){
     div#viewer div#viewer_info table#monster_header img.monster_img{
-        width: 5.6em;
-        height: 5.6em;
+        width: 5em;
+        height: 5em;
         border-width: 0.2em;
         border-radius: 10%;
+        margin: 0.1em;
     }
 }
 
@@ -137,22 +168,37 @@ div#viewer div#viewer_info table#monster_header div#monster_stars{
     margin: 0.5em auto;
     padding: 0.3em;
 }
+@media screen and (max-width : 990px){
+    div#viewer div#viewer_info table#monster_header div#monster_stars{
+        margin: 0.3em auto;
+        padding: 0.1em;
+    }
+}
 
 div#viewer div#viewer_info table#monster_header div#monster_stars img.monster_star{
     width: 2em;
     height: 2em;
     filter: drop-shadow(0 0 0.1em #000000) drop-shadow(0 0 0.1em #000000) drop-shadow(0 0 0.1em #000000);
 }
+@media screen and (max-width : 990px){
+    div#viewer div#viewer_info table#monster_header div#monster_stars img.monster_star{
+        width: 1.6em;
+        height: 1.6em;
+    }
+}
 
 div#viewer div#viewer_info table#monster_skills{
     width: 90%;
-    margin: auto;
+    margin: 2em auto 2em auto;
     border-collapse: collapse;
+    border: 0.1em solid #000000;
+    border-radius: 0.5em;
+    background-color: #aa8866;
 }
 
 div#viewer div#viewer_info table#monster_skills td{
     vertical-align: top;
-    padding: 0.1em 0.2em;
+    padding: 0.1em;
     text-align: center;
     width: 1%;
 }
@@ -216,6 +262,17 @@ div#viewer div#viewer_info table#monster_stats td span.stat.awake{
     font-style: italic;
 }
 
+div#viewer div#viewer_info div#monster_location{
+    margin: 1em 20%;
+}
+
+div#viewer div#viewer_info div#monster_awake{
+    text-align: center;
+}
+div#viewer div#viewer_info div#monster_awake table{
+    margin: auto;
+}
+
 div#viewer div#viewer_info div#monster_awake td.essence{
     text-align: center;
 }
@@ -223,7 +280,8 @@ div#viewer div#viewer_info div#monster_awake td.essence{
 div#viewer div#viewer_info div#monster_awake td.essence img{
     display: block;
     border-width: 0.2em;
-    border-radius: 10%;
+    border-style: solid;
+    border-radius: 50%;
     width: 2.5em;
     height: 2.5em;
 }
@@ -231,7 +289,8 @@ div#viewer div#viewer_info div#monster_awake td.essence img{
 div#viewer div#viewer_info div#monster_awake td.essence span{
     display: block;
     text-align: right;
-    margin: -2em 0.5em 0 0;
+    margin: -1em 0.2em 0 0;
     color: #ffffff;
     text-shadow: 0 0 0.2em #000000;
+    filter: drop-shadow(0 0 0.1em #000000) drop-shadow(0 0 0.1em #000000);
 }

+ 3 - 0
public/css/collection.css

@@ -206,6 +206,9 @@ div#portrait_container div#portrait table#portrait_skills{
     width: 80%;
     margin: auto;
     border-collapse: collapse;
+    border: 0.1em solid #000000;
+    border-radius: 0.5em;
+    background-color: #aa8866;
 }
 
 div#portrait_container div#portrait table#portrait_skills td{

+ 19 - 4
public/css/ui.css

@@ -122,6 +122,13 @@ img.slider{
     vertial-align: middle;
     transition: all .3s ease-in-out;
 }
+img.loader{
+    animation: spin 2s linear infinite;
+}
+@keyframes spin {
+    0% { transform: rotate(0deg); }
+    100% { transform: rotate(360deg); }
+}
 div#cover{ /* Page cofer for opening floating windows. */
     display: none;
     background-color: #000000bb;
@@ -245,7 +252,6 @@ div.section div.entry{  /* Separated elements in a section. */
 }
 
 img.skill_image{
-    display: block;
     margin: 0 auto;
     width: 2.5em;
     height: 2.5em;
@@ -263,6 +269,7 @@ img.skill_image.skill_leader{
     filter: drop-shadow(0 0 0.1em #8888ff) drop-shadow(0 0 0.1em #8888ff) drop-shadow(0 0 0.1em #8888ff);
 }
 span.skill_name{
+    display: block;
     font-style: italic;
 }
 span.skill_name.skill_awaken{
@@ -276,9 +283,8 @@ span.skill_name.skill_leader{
 }
 span.skill_image{
     position: relative;
-    margin-left: 10%;
-    margin-top: 15%;
 }
+
 span.skill_image span.skill_tooltip{
     color: #ffffff;
     padding: 0.7em;
@@ -286,7 +292,6 @@ span.skill_image span.skill_tooltip{
     border: 0.2em solid #f2c920;;
     border-radius: 0.5em;
     text-shadow: 0 0 0.1em #000000;
-    cursor: pointer;
     box-shadow: 0 0 0.2em #000000;
     width: 18em;
     top: -7em;
@@ -294,12 +299,22 @@ span.skill_image span.skill_tooltip{
     opacity: 0;
     position: absolute;
     text-align: center;
+    display: none;
     z-index: 2;
     text-transform: none;
     transition: all 0.3s ease-in-out;
 }
+@media screen and (max-width : 990px){
+    span.skill_image span.skill_tooltip{
+        width: 12em;
+        top: -9em;
+        left: -6em;
+        padding: 0.4em
+    }
+}
 span.skill_image:hover span.skill_tooltip{
     opacity: 1;
+    display: block;
     z-index: 99;
 }
 span.skill_image span.skill_tooltip img.skill_tooltip_image{

BIN
public/img/layout/control/loader.png


BIN
public/img/layout/icon/star_silver.png


+ 2 - 2
public/index.php

@@ -1,7 +1,7 @@
 <?php
-
+	//set_include_path('./');
     //require_once("../application/config/config.php");
-    include "../application/config/config.php";
+    include __DIR__ . "/../application/config.php";
     include_once($path["controller"]);
 
     $request = $_SERVER['REQUEST_URI'];

+ 48 - 9
public/script/catalog.js

@@ -1,14 +1,53 @@
-
-function showNew(show){
-    if (show === true){
-        document.getElementById('cover').style.display = 'block';
-        document.getElementById('cover').style.opacity = '0.8';
-        document.getElementById('new').style.display = 'block';
+function loadCatalog(){
+    document.getElementById("catalog").innerHTML = "<img class='loader' alt='Loading...' src='/img/layout/control/loader.png'/>";
+    // Get filter values
+    var filters = "";
+    var fName = document.getElementById('filter_name').value;
+    var fType = document.getElementById('filter_type').value;
+    var fElement = document.getElementById('filter_element').value;
+    var fMinStars = document.getElementById('filter_stars_min').value;
+    var fMaxStars = document.getElementById('filter_stars_max').value;
+    if (fName && /^\s*$/.test(fName) == false){
+        filters = filters + "name=" + fName + "&";
+    }
+    if (fType && /^\s*$/.test(fType) == false){
+        filters = filters + "type=" + fType + "&";
+    }
+    if (fElement && /^\s*$/.test(fElement) == false){
+        filters = filters + "element=" + fElement + "&";
+    }
+    if (Number.isInteger(fMinStars) && Number.isInteger(fMaxStars) && fMinStars < fMaxStars){
+        var p = fMinStars;
+        fMinStars = fMaxStars;
+        fMaxStars = p;
+    }
+    if (Number.isInteger(fMinStars) && fMinStars > 0 && fMinStars < 7){
+        filters = filters + "minstars=" + fMinStars + "&";
+    }
+    if (Number.isInteger(fMaxStars) && fMaxStars > 0 && fMaxStars < 7){
+        filters = filters + "maxstars=" + fMaxStars + "&";
+    }
+    if (filters.length > 0 && filters.slice(-1) == '&'){
+        filters = filters.slice(0, -1)
+    }
+    var req = new XMLHttpRequest();
+    req.onreadystatechange = function() {
+        if (this.readyState == 4){
+            if (this.status == 200){
+                document.getElementById("catalog").innerHTML = this.responseText;
+            }
+            else{
+                document.getElementById("catalog").innerHTML = "Error getting monster collection (HTTP status " + this.status + ")";
+            }
+        }
+    };
+    req.open("POST", "/frame/catalog_list/", true);
+    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+    if (filters.length > 0){
+        req.send(filters);
     }
     else{
-        document.getElementById('cover').style.display = 'none';
-        document.getElementById('cover').style.opacity = '0';
-        document.getElementById('new').style.display = 'none';
+        req.send();
     }
 }
 

+ 17 - 0
start_server

@@ -0,0 +1,17 @@
+#!/bin/bash
+port=80
+server_public=yes
+
+. config
+
+host=0.0.0.0;
+if [ "$server_public" == "no" ]; then
+	host=localhost;
+fi
+
+
+
+echo "PUBLIC: " $server_public $host;
+php -S $host:$port -t public/ >> server.log 2>&1  &
+pid=$!
+echo $pid > .php_pid

+ 7 - 0
stop_server

@@ -0,0 +1,7 @@
+#!/bin/bash
+if [ ! -f .php_pid ]; then
+	echo Server not started.
+else
+	kill -9 $(cat .php_pid)
+	rm .php_pid
+fi