Browse Source

Several fixes and improvements:
Database location is now fixed for the program and the GUI.
Fixed memory leak.
Result rating are now more consistent and accurate.
Output generation for the GUI is now faster and more efficient.
Result view implemented in GUI.

Iñigo Valentin 4 years ago
parent
commit
a36b06d03f

+ 3 - 1
src/Makefile

@@ -1,9 +1,11 @@
 CC=gcc
 CC=gcc
 CFLAGS=
 CFLAGS=
+OPTS_DEBUG=-Wall -g -fsanitize=address
+OPTS=
 LIBS=-lsqlite3 -lm
 LIBS=-lsqlite3 -lm
 OUT=../RuneOptimizer
 OUT=../RuneOptimizer
 compile :
 compile :
-	@$(CC) RuneOptimizer/RuneOptimizer.c $(LIBS) -o $(OUT)
+	@$(CC) RuneOptimizer/RuneOptimizer.c $(LIBS) $(OPTS) -o $(OUT)
 	@echo Compiled executable $(OUT)
 	@echo Compiled executable $(OUT)
 #RuneOptimizer: RuneOptimizer.c
 #RuneOptimizer: RuneOptimizer.c
 #	$(CC) -o makeRO RuneOptimizer.c
 #	$(CC) -o makeRO RuneOptimizer.c

+ 15 - 0
src/RuneOptimizer/RuneOptimizer.c

@@ -49,6 +49,21 @@ int main(int argc, char *argv[]){
         return ERROR_INPUT_NO_COMMAND;
         return ERROR_INPUT_NO_COMMAND;
     }
     }
 
 
+    // Set the global database location
+    int last_path_separator = -1;
+    for(int i = 0; i < strlen(argv[0]); i++){
+        if(argv[0][i] == '/'){
+            last_path_separator = i + 1;
+        }
+    }
+    if (last_path_separator != -1){
+        strncpy(db_location, argv[0], last_path_separator);
+    }
+    else{
+        strcpy(db_location, "");
+    }
+    strcat(db_location, DB_NAME);
+
     // Update command, TODO
     // Update command, TODO
     if (strcmp(argv[1], "update") == 0){
     if (strcmp(argv[1], "update") == 0){
         fprintf(stderr, "Updating is still unimplemented\n");
         fprintf(stderr, "Updating is still unimplemented\n");

+ 3 - 1
src/RuneOptimizer/RuneOptimizer.h

@@ -15,7 +15,9 @@
  * RuneOptimizer. If not, see <https://www.gnu.org/licenses/>.
  * RuneOptimizer. If not, see <https://www.gnu.org/licenses/>.
  */
  */
 
 
-#define DB_PATH "../data.sqlite"
+#define DB_NAME "data.sqlite"
+
+char db_location[256];
 
 
 /**
 /**
  * Starts the program.
  * Starts the program.

+ 75 - 47
src/RuneOptimizer/optimize/optimize.c

@@ -526,7 +526,7 @@ int parse_optimization_arguments(
  */
  */
 int retrieveUnit(char id[64], struct Unit *unit){
 int retrieveUnit(char id[64], struct Unit *unit){
     sqlite3 *db;
     sqlite3 *db;
-    if (SUCCESS != sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL)){
+    if (SUCCESS != sqlite3_open_v2(db_location, &db, SQLITE_OPEN_READWRITE, NULL)){
         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
         sqlite3_close(db);
         sqlite3_close(db);
         return ERROR_DB_CANT_OPEN;
         return ERROR_DB_CANT_OPEN;
@@ -735,7 +735,7 @@ void createQueryForEvenSlots(
     if (level == 12) strcpy(column, "lv12_");
     if (level == 12) strcpy(column, "lv12_");
     else if (level == 15) strcpy(column, "lv15_");
     else if (level == 15) strcpy(column, "lv15_");
     else strcpy(column, "current_");
     else strcpy(column, "current_");
-    strcpy(query, "SELECT id, unit, type, ");
+    strcpy(query, "SELECT id, unit, slot, type, ");
     strcat(query, column);
     strcat(query, column);
     strcat(query, "hp_flat, ");
     strcat(query, "hp_flat, ");
     strcat(query, column);
     strcat(query, column);
@@ -837,7 +837,7 @@ void createQueryForOddSlots(
     if (level == 12) strcpy(column, "lv12_");
     if (level == 12) strcpy(column, "lv12_");
     else if (level == 15) strcpy(column, "lv15_");
     else if (level == 15) strcpy(column, "lv15_");
     else strcpy(column, "current_");
     else strcpy(column, "current_");
-    strcpy(query, "SELECT id, unit, type, ");
+    strcpy(query, "SELECT id, unit, slot, type, ");
     strcat(query, column);
     strcat(query, column);
     strcat(query, "hp_flat, ");
     strcat(query, "hp_flat, ");
     strcat(query, column);
     strcat(query, column);
@@ -929,7 +929,7 @@ int get_runes(
     char **query;
     char **query;
     sqlite3 *db;
     sqlite3 *db;
     sqlite3_stmt *stmt_runes[7];
     sqlite3_stmt *stmt_runes[7];
-    if (SUCCESS != sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL)){
+    if (SUCCESS != sqlite3_open_v2(db_location, &db, SQLITE_OPEN_READWRITE, NULL)){
         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
         sqlite3_close(db);
         sqlite3_close(db);
         return ERROR_DB_CANT_OPEN;
         return ERROR_DB_CANT_OPEN;
@@ -957,18 +957,19 @@ int get_runes(
             if (status == SQLITE_ROW){
             if (status == SQLITE_ROW){
                 strcpy(runes[i][j].id, sqlite3_column_text(stmt_runes[i], 0));
                 strcpy(runes[i][j].id, sqlite3_column_text(stmt_runes[i], 0));
                 strcpy(runes[i][j].unit, sqlite3_column_text(stmt_runes[i], 1));
                 strcpy(runes[i][j].unit, sqlite3_column_text(stmt_runes[i], 1));
-                runes[i][j].set = sqlite3_column_int(stmt_runes[i], 2);
-                runes[i][j].hp_flat = sqlite3_column_int(stmt_runes[i], 3);
-                runes[i][j].atk_flat = sqlite3_column_int(stmt_runes[i], 4);
-                runes[i][j].def_flat = sqlite3_column_int(stmt_runes[i], 5);
-                runes[i][j].hp_percent = sqlite3_column_int(stmt_runes[i], 6);
-                runes[i][j].atk_percent = sqlite3_column_int(stmt_runes[i], 7);
-                runes[i][j].def_percent = sqlite3_column_int(stmt_runes[i], 8);
-                runes[i][j].spd = sqlite3_column_int(stmt_runes[i], 9);
-                runes[i][j].crr = sqlite3_column_int(stmt_runes[i], 10);
-                runes[i][j].crd = sqlite3_column_int(stmt_runes[i], 11);
-                runes[i][j].res = sqlite3_column_int(stmt_runes[i], 12);
-                runes[i][j].acc = sqlite3_column_int(stmt_runes[i], 13);
+                runes[i][j].slot = sqlite3_column_int(stmt_runes[i], 2);
+                runes[i][j].set = sqlite3_column_int(stmt_runes[i], 3);
+                runes[i][j].hp_flat = sqlite3_column_int(stmt_runes[i], 4);
+                runes[i][j].atk_flat = sqlite3_column_int(stmt_runes[i], 5);
+                runes[i][j].def_flat = sqlite3_column_int(stmt_runes[i], 6);
+                runes[i][j].hp_percent = sqlite3_column_int(stmt_runes[i], 7);
+                runes[i][j].atk_percent = sqlite3_column_int(stmt_runes[i], 8);
+                runes[i][j].def_percent = sqlite3_column_int(stmt_runes[i], 9);
+                runes[i][j].spd = sqlite3_column_int(stmt_runes[i], 10);
+                runes[i][j].crr = sqlite3_column_int(stmt_runes[i], 11);
+                runes[i][j].crd = sqlite3_column_int(stmt_runes[i], 12);
+                runes[i][j].res = sqlite3_column_int(stmt_runes[i], 13);
+                runes[i][j].acc = sqlite3_column_int(stmt_runes[i], 14);
                 j ++;
                 j ++;
             }
             }
             else{
             else{
@@ -1138,7 +1139,7 @@ int present_option(struct Unit *unit, Result *result){
 
 
     // Retrieve the rune stats from the database
     // Retrieve the rune stats from the database
     sqlite3 *db;
     sqlite3 *db;
-    if (SUCCESS != sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL)){
+    if (SUCCESS != sqlite3_open_v2(db_location, &db, SQLITE_OPEN_READWRITE, NULL)){
         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
         sqlite3_close(db);
         sqlite3_close(db);
         return ERROR_DB_CANT_OPEN;
         return ERROR_DB_CANT_OPEN;
@@ -1319,13 +1320,15 @@ int present_option(struct Unit *unit, Result *result){
  */
  */
 int gui_output(Result results[5000], int result_count){
 int gui_output(Result results[5000], int result_count){
     //Print for GUI
     //Print for GUI
-    char tmp[1000000];
+    char tmp[300];
     strcpy(tmp, "");
     strcpy(tmp, "");
-    char json[1000000] = "{\"results\":[";
-    for (int i = 0; i < result_count; i++){
+    char json[300];
+    printf("{\"result_count\":%d,\"results\":[\n", result_count);
+    int result_limit = 100;
+    for (int i = 0; i < result_count && i < result_limit; i++){
         //printf("RES LOOP %d\n", i);
         //printf("RES LOOP %d\n", i);
-        sprintf(tmp, "{\"rating\":%d,", results[i].rating);
-        strcat(json, tmp);
+        sprintf(tmp, "{\"id\":%d,\"rating\":%d,", i, results[i].rating);
+        strcpy(json, tmp);
         sprintf(tmp, "\"hp\":%d,", results[i].stats.hp);
         sprintf(tmp, "\"hp\":%d,", results[i].stats.hp);
         strcat(json, tmp);
         strcat(json, tmp);
         sprintf(tmp, "\"atk\":%d,", results[i].stats.atk);
         sprintf(tmp, "\"atk\":%d,", results[i].stats.atk);
@@ -1358,13 +1361,26 @@ int gui_output(Result results[5000], int result_count){
         sprintf(tmp, "\"%s\"", results[i].rune_ids[5]);
         sprintf(tmp, "\"%s\"", results[i].rune_ids[5]);
         strcat(json, tmp);
         strcat(json, tmp);
         strcat(json, "]},");
         strcat(json, "]},");
+
+        // If last result, remove last comma
+        if (i == result_count - 1 || i == result_limit - 1){
+            json[strlen(json) - 1] = 0;
+        }
+
+        printf(json);
+        printf("\n");
     }
     }
     // Remove last comma
     // Remove last comma
-    json[strlen(json) - 1] = '\0';
+    //json[strlen(json) - 1] = '\0';
+    //free(*tmp);
 
 
     // End and print
     // End and print
-    strcat(json, "]}\0");
-    printf("%s", json);
+    printf("]}\n");
+    //printf("STRLEN JSON %d\n", strlen(json));
+    //printf("%s", json);
+    //free(*json);
+    //printf("\n\nEND\n\n");
+    return SUCCESS;
 }
 }
 
 
 /**
 /**
@@ -1410,7 +1426,7 @@ int optimize(int argc, char *argv[]){
     min_stats.dmg = 1;
     min_stats.dmg = 1;
     char excluded_teams[64][64];
     char excluded_teams[64][64];
     char excluded_units[64][64];
     char excluded_units[64][64];
-    for (int i = 0; i < 128; i++){
+    for (int i = 0; i < 64; i++){
         excluded_teams[i][0] = '\0';
         excluded_teams[i][0] = '\0';
         excluded_units[i][0] = '\0';
         excluded_units[i][0] = '\0';
     }
     }
@@ -1496,16 +1512,15 @@ int optimize(int argc, char *argv[]){
 
 
     // Now its time to loop all 6 'reels' of runes and try to match combos
     // Now its time to loop all 6 'reels' of runes and try to match combos
     if (gui != 1){
     if (gui != 1){
-        printf(
-          "\n\n__Optimization progress___________________________\n",
-          max_combinations
-        );
+        printf("\n\n__Optimization progress___________________________\n");
     }
     }
+
     // Initialize arrys and some counters
     // Initialize arrys and some counters
     int index[7] = {0, 0, 0, 0, 0, 0};
     int index[7] = {0, 0, 0, 0, 0, 0};
     unsigned long tested_combinations = 0;
     unsigned long tested_combinations = 0;
     unsigned long valid_sets = 0;
     unsigned long valid_sets = 0;
     unsigned long result_count = 0;
     unsigned long result_count = 0;
+    struct Rune_Set_Count set_count;
     Result results[5000];
     Result results[5000];
     while(
     while(
         index[1] < rune_count[1] &&
         index[1] < rune_count[1] &&
@@ -1529,7 +1544,6 @@ int optimize(int argc, char *argv[]){
         }
         }
 
 
         // Calculate rune sets at current indexes.
         // Calculate rune sets at current indexes.
-        struct Rune_Set_Count set_count;
         set_count.energy = 0;
         set_count.energy = 0;
         set_count.guard = 0;
         set_count.guard = 0;
         set_count.swift = 0;
         set_count.swift = 0;
@@ -1618,6 +1632,7 @@ int optimize(int argc, char *argv[]){
                     break;
                     break;
             }
             }
         }
         }
+
         // Compare with requested sets
         // Compare with requested sets
         if (
         if (
             set_count.energy >= requested_set_count.energy &&
             set_count.energy >= requested_set_count.energy &&
@@ -1661,9 +1676,9 @@ int optimize(int argc, char *argv[]){
                 stats.def += runes[i][index[i]].def_flat;
                 stats.def += runes[i][index[i]].def_flat;
                 stats.hp += unit.base_hp * runes[i][index[i]].hp_percent / 100;
                 stats.hp += unit.base_hp * runes[i][index[i]].hp_percent / 100;
                 stats.atk +=
                 stats.atk +=
-                  unit.base_hp * runes[i][index[i]].atk_percent / 100;
+                  unit.base_atk * runes[i][index[i]].atk_percent / 100;
                 stats.def +=
                 stats.def +=
-                  unit.base_hp * runes[i][index[i]].def_percent / 100;
+                  unit.base_def * runes[i][index[i]].def_percent / 100;
                 stats.spd += runes[i][index[i]].spd;
                 stats.spd += runes[i][index[i]].spd;
                 stats.crr += runes[i][index[i]].crr;
                 stats.crr += runes[i][index[i]].crr;
                 stats.crd += runes[i][index[i]].crd;
                 stats.crd += runes[i][index[i]].crd;
@@ -1703,7 +1718,7 @@ int optimize(int argc, char *argv[]){
             // Cap cappable stats
             // Cap cappable stats
             if (stats.crr > 100) stats.crr = 100;
             if (stats.crr > 100) stats.crr = 100;
             if (stats.res > 100) stats.res = 100;
             if (stats.res > 100) stats.res = 100;
-            if (stats.crr > 85) stats.acc = 100;
+            if (stats.crr > 85) stats.acc = 85;
 
 
             // Calculated stats
             // Calculated stats
             stats.ehp = calculate_ehp(stats.hp, stats.def);
             stats.ehp = calculate_ehp(stats.hp, stats.def);
@@ -1741,18 +1756,31 @@ int optimize(int argc, char *argv[]){
                 results[result_count].stats.ehp = stats.ehp;
                 results[result_count].stats.ehp = stats.ehp;
                 results[result_count].stats.dmg = stats.dmg;
                 results[result_count].stats.dmg = stats.dmg;
 
 
-                // One rating point per stat increase over current stats.
-                // Save for HP, with takes 15 for a raing point
-                results[result_count].rating = 0;
-                results[result_count].rating +=
-                  ((stats.hp - unit.current_hp) / 15);
-                results[result_count].rating += (stats.atk - unit.current_atk);
-                results[result_count].rating += (stats.def - unit.current_def);
-                results[result_count].rating += (stats.spd - unit.current_spd);
-                results[result_count].rating += (stats.crr - unit.current_crr);
-                results[result_count].rating += (stats.crd - unit.current_crd);
-                results[result_count].rating += (stats.res - unit.current_res);
-                results[result_count].rating += (stats.acc - unit.current_acc);
+                // Calculate rating, based on the difference between the
+                // stats with this set and the current stats.
+                // This is calculated accounting for the proportions between
+                // the (flat) stats for each main stat in a 6 star, level 15
+                // rune:
+                // HP: 1 rating point per 58.29 points
+                // ATK: 1 rating point per 1.50 points
+                // DEF: 1 rating point per 1.50 points
+                // SPD: 1 rating point per 1.00 points
+                // CRR: 1 rating point per 1.38 points
+                // CRD: 1 rating point per 1.90 points
+                // RES: 1 rating point per 1.52 points
+                // ACC: 1 rating point per 1.52 points
+                float rating = 0.0f;
+                rating += (float) ((int) stats.hp  - (int) unit.current_hp ) / 58.29f;
+                rating += (float) ((int) stats.atk - (int) unit.current_atk) /  1.50f;
+                rating += (float) ((int) stats.def - (int) unit.current_def) /  1.50f;
+                rating += (float) ((int) stats.spd - (int) unit.current_spd) /  1.00f;
+                rating += (float) ((int) stats.crr - (int) unit.current_crr) /  1.38f;
+                rating += (float) ((int) stats.crd - (int) unit.current_crd) /  1.90f;
+                rating += (float) ((int) stats.res - (int) unit.current_res) /  1.52f;
+                rating += (float) ((int) stats.acc - (int) unit.current_acc) /  1.52f;
+                results[result_count].rating = (int) rating;
+
+                // Account for found result
                 result_count ++;
                 result_count ++;
             }
             }
         }
         }
@@ -1794,9 +1822,9 @@ int optimize(int argc, char *argv[]){
         if (gui != 1){
         if (gui != 1){
             printf("\n\n%d results found\n", result_count);
             printf("\n\n%d results found\n", result_count);
         }
         }
+
         // Sort results
         // Sort results
         sort_results(results, result_count);
         sort_results(results, result_count);
-
         if (gui != 1){
         if (gui != 1){
             // Preview the best option
             // Preview the best option
             present_option(&unit, &results[0]);
             present_option(&unit, &results[0]);

+ 1 - 1
src/RuneOptimizer/team/team.c

@@ -34,7 +34,7 @@ int list_teams(int argc, char *argv[]){
     }
     }
     strcat(query, " ORDER BY priority DESC");
     strcat(query, " ORDER BY priority DESC");
     sqlite3 *db;
     sqlite3 *db;
-    if (SUCCESS != sqlite3_open_v2(DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL)){
+    if (SUCCESS != sqlite3_open_v2(db_location, &db, SQLITE_OPEN_READWRITE, NULL)){
         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
         fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
         sqlite3_close(db);
         sqlite3_close(db);
         return ERROR_DB_CANT_OPEN;
         return ERROR_DB_CANT_OPEN;

+ 59 - 40
src/RuneOptimizerGUI/classes/PanelOptimizer.py

@@ -169,48 +169,54 @@ class PanelOptimizer(wx.Panel):
         #Rune set list
         #Rune set list
         runeListBox = [
         runeListBox = [
           wx.StaticBox(
           wx.StaticBox(
-            self.unitInfo, label="Slot1:", id=wx.ID_ANY,
+            parent=self.unitInfo, label="Slot1:", id=wx.ID_ANY,
             pos=(265, 30), size=(80, 115)
             pos=(265, 30), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            self.unitInfo, label="Slot2:", id=wx.ID_ANY,
+            parent=self.unitInfo, label="Slot2:", id=wx.ID_ANY,
             pos=(350, 30), size=(80, 115)
             pos=(350, 30), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            self.unitInfo, label="Slot3:", id=wx.ID_ANY,
+            parent=self.unitInfo, label="Slot3:", id=wx.ID_ANY,
             pos=(350, 150), size=(80, 115)
             pos=(350, 150), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            self.unitInfo, label="Slot4:", id=wx.ID_ANY,
+            parent=self.unitInfo, label="Slot4:", id=wx.ID_ANY,
             pos=(265, 150), size=(80, 115)
             pos=(265, 150), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            self.unitInfo, label="Slot5:", id=wx.ID_ANY,
+            parent=self.unitInfo, label="Slot5:", id=wx.ID_ANY,
             pos=(180, 150), size=(80, 115)
             pos=(180, 150), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            self.unitInfo, label="Slot6:", id=wx.ID_ANY,
+            parent=self.unitInfo, label="Slot6:", id=wx.ID_ANY,
             pos=(180, 30), size=(80, 115)
             pos=(180, 30), size=(80, 115)
           )
           )
         ]
         ]
         self.runeList = [
         self.runeList = [
           wx.StaticText(
           wx.StaticText(
-            runeListBox[0], label="", id=wx.ID_ANY, pos=(0, 0), size=(80, 115)
+            parent=runeListBox[0],  id=wx.ID_ANY, label="",
+            pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[1], label="", id=wx.ID_ANY, pos=(0, 0), size=(80, 115)
+            parent=runeListBox[1],  id=wx.ID_ANY, label="",
+            pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[2], label="", id=wx.ID_ANY, pos=(0, 0), size=(80, 115)
+            parent=runeListBox[2],  id=wx.ID_ANY, label="",
+            pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[3], label="", id=wx.ID_ANY, pos=(0, 0), size=(80, 115)
+            parent=runeListBox[3],  id=wx.ID_ANY, label="",
+            pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[4], label="", id=wx.ID_ANY, pos=(0, 0), size=(80, 115)
+            parent=runeListBox[4],  id=wx.ID_ANY, label="",
+            pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[5], label="", id=wx.ID_ANY, pos=(0, 0), size=(80, 115)
+            parent=runeListBox[5],  id=wx.ID_ANY, label="",
+            pos=(0, 0), size=(80, 115)
           )
           )
         ]
         ]
         monospaceFont.PointSize -= 2
         monospaceFont.PointSize -= 2
@@ -264,37 +270,47 @@ class PanelOptimizer(wx.Panel):
         )
         )
         self.minStatSlid = [
         self.minStatSlid = [
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 0), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 0),
+              size=(120, 25), name="slid0"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 25), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 25),
+              size=(120, 25), name="slid1"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 50), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 50),
+              size=(120, 25), name="slid2"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 75), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 75),
+              size=(120, 25), name="slid3"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 100), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 100),
+              size=(120, 25), name="slid4"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 125), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 125),
+              size=(120, 25), name="slid5"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 150), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 150),
+              size=(120, 25), name="slid6"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 175), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 175),
+              size=(120, 25), name="slid7"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 200), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 200),
+              size=(120, 25), name="slid8"
             ),
             ),
             wx.Slider(
             wx.Slider(
-              parent=minStatBox, id=wx.ID_ANY, pos=(30, 225), size=(120, 25)
+              parent=minStatBox, id=wx.ID_ANY, pos=(30, 225),
+              size=(120, 25), name="slid9"
             )
             )
         ]
         ]
-        for i in range(0, 9):
+        for i in range(0, 10):
             self.minStatSlid[i].SetMin(0)
             self.minStatSlid[i].SetMin(0)
             self.minStatSlid[i].SetMax(0)
             self.minStatSlid[i].SetMax(0)
             self.minStatSlid[i].SetValue(0)
             self.minStatSlid[i].SetValue(0)
@@ -687,8 +703,7 @@ class PanelOptimizer(wx.Panel):
         # ../RuneOptimizer optimize 7223811472 -l 15
         # ../RuneOptimizer optimize 7223811472 -l 15
         #-e rage,blade --stats atk,crr,crd -h 10000 -f 10
         #-e rage,blade --stats atk,crr,crd -h 10000 -f 10
         command = "RuneOptimizer optimize "
         command = "RuneOptimizer optimize "
-        unitId = \
-          str(self.unitList.GetItemData(self.unitList.GetFirstSelected()))
+        unitId = self.unitId
         command += unitId
         command += unitId
         level = self.level.GetSelection()
         level = self.level.GetSelection()
         if level == 1:
         if level == 1:
@@ -760,24 +775,28 @@ class PanelOptimizer(wx.Panel):
 
 
 
 
         command += (" --gui ")
         command += (" --gui ")
+        command = os.path.dirname(os.path.realpath(__file__)) + "/../../" + command
         print("Command: " + command)
         print("Command: " + command)
 
 
-        command = "../../" + command
         out = subprocess.check_output(command.split())
         out = subprocess.check_output(command.split())
-        #print ("---- OUTPUT ------------------------------------------------------------------------------------------")
-        #print(out)
-        #print ("------------------------------------------------------------------------------------------------------")
-
-        # TODO: Do this propperly
-        resultsFrame = ResultsFrame(
-          parent=None, title='Options for Lushen (DEBUG)',
-          pos=(100, 50), size=(900, 680)
-        )
-        resultsFrame.unitId = unitId
-        resultsFrame.unitName = self.unitNameValue
-        resultsFrame.currentStats = self.currentStats
-        resultsFrame.processResults(bytes.decode(out))
-        resultsFrame.Show()
+        json = bytes.decode(out)
+        # DEBUG: Sample data.
+        #self.unitId = "7223811472"
+        #json = """{"result_count":5000,"results":[
+        #    {"id":0,"rating":215,"hp":20461,"atk":2521,"dfc":845,"spd":137,"crr":63,"crd":167,"res":29,"acc":15,"ehp":83839,"dmg":5174,"runes":["22677809846","22920616295","21755980400","25633344349","26207902579","28512560500"]},
+        #    {"id":1,"rating":195,"hp":18876,"atk":2521,"dfc":853,"spd":137,"crr":60,"crd":174,"res":37,"acc":8,"ehp":77873,"dmg":5153,"runes":["22677809846","22920616295","27654723287","25633344349","26207902579","28512560500"]},
+        #    {"id":2,"rating":185,"hp":17730,"atk":2521,"dfc":862,"spd":147,"crr":60,"crd":164,"res":28,"acc":15,"ehp":73704,"dmg":5002,"runes":["21564691276","22920616295","27654723287","25633344349","26207902579","22348038576"]},
+        #    {"id":3,"rating":179,"hp":15810,"atk":2431,"dfc":1011,"spd":137,"crr":61,"crd":160,"res":27,"acc":15,"ehp":73968,"dmg":4804,"runes":["21564691276","22920616295","27444728625","22750814840","26670411873","22348038576"]},
+        #    {"id":4,"rating":176,"hp":15319,"atk":2530,"dfc":909,"spd":142,"crr":60,"crd":165,"res":28,"acc":15,"ehp":66202,"dmg":5035,"runes":["21564691276","16759622995","27654723287","22750814840","26207902579","22348038576"]}]}
+        #"""
+
+
+        print ("---- OUTPUT ------------------------------------------------------------------------------------------")
+        print(json)
+        print ("------------------------------------------------------------------------------------------------------")
+
+        self.GetParent().frameResults.processResults(self.unitId, json)
+
 
 
     def minStatChangeBySlider(self, event):
     def minStatChangeBySlider(self, event):
         """Changes text when a slider is changed.
         """Changes text when a slider is changed.

+ 104 - 54
src/RuneOptimizerGUI/classes/PanelResults.py

@@ -26,9 +26,11 @@ class PanelResults(wx.Panel):
         ID of the unit being optimized (default "").
         ID of the unit being optimized (default "").
     unitName : str
     unitName : str
         Name of the unit being optimized (default "").
         Name of the unit being optimized (default "").
+    unitNameLabel : wx.StaticText
+        Labels for the unit name.
     data : Python Object
     data : Python Object
         Results from RuneOptimizer (default None).
         Results from RuneOptimizer (default None).
-    currentStats : int[10]
+    unitStats : int[10]
         The current stats of the unit being optimized. (default is
         The current stats of the unit being optimized. (default is
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).
     page : int
     page : int
@@ -87,8 +89,9 @@ class PanelResults(wx.Panel):
 
 
     unitId = ""
     unitId = ""
     unitName = ""
     unitName = ""
+    unitNameLabel = None
     data = None
     data = None
-    currentStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+    unitStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
     page = 0
     page = 0
     totalPages = 0
     totalPages = 0
     linesPerPage = 10
     linesPerPage = 10
@@ -130,9 +133,20 @@ class PanelResults(wx.Panel):
           style=wx.FONTSTYLE_ITALIC, weight=wx.FONTWEIGHT_NORMAL
           style=wx.FONTSTYLE_ITALIC, weight=wx.FONTWEIGHT_NORMAL
         )
         )
 
 
+        # Unit name and id
+        self.unitNameLabel =wx.StaticText(
+            parent=self, id=wx.ID_ANY, label="Nothing yet. Optimize something!",
+            pos=(0, 0), size=(400, 30)
+        )
+
+        # Contains the results table. Hidden until they are loaded.
+        self.resultContainer = wx.BoxSizer(wx.VERTICAL)
+        # Contains all thigs to be shown once a result is selected
+        self.resultContent = wx.BoxSizer(wx.VERTICAL)
+
         # The result list table
         # The result list table
         self.resultGrid = wx.grid.Grid(
         self.resultGrid = wx.grid.Grid(
-          parent=self, id=wx.ID_ANY, pos=(50, 30), size=(544, 220)
+          parent=self, id=wx.ID_ANY, pos=(0, 30), size=(525, 170)
         )
         )
         self.resultGrid.CreateGrid(
         self.resultGrid.CreateGrid(
           numRows=10, numCols=11,
           numRows=10, numCols=11,
@@ -142,7 +156,9 @@ class PanelResults(wx.Panel):
         self.resultGrid.SetDefaultCellAlignment(
         self.resultGrid.SetDefaultCellAlignment(
           horiz=wx.ALIGN_RIGHT, vert=wx.ALIGN_CENTRE
           horiz=wx.ALIGN_RIGHT, vert=wx.ALIGN_CENTRE
         )
         )
+        monospaceFont.PointSize -= 1
         self.resultGrid.SetDefaultCellFont(monospaceFont)
         self.resultGrid.SetDefaultCellFont(monospaceFont)
+        monospaceFont.PointSize += 1
         self.resultGrid.SetRowLabelSize(width=35)
         self.resultGrid.SetRowLabelSize(width=35)
         self.resultGrid.SetColLabelValue(col=0, value="Rating")
         self.resultGrid.SetColLabelValue(col=0, value="Rating")
         self.resultGrid.SetColSize(col=0, width=50)
         self.resultGrid.SetColSize(col=0, width=50)
@@ -167,34 +183,35 @@ class PanelResults(wx.Panel):
         self.resultGrid.SetColLabelValue(col=10, value="DMG")
         self.resultGrid.SetColLabelValue(col=10, value="DMG")
         self.resultGrid.SetColSize(col=10, width=50)
         self.resultGrid.SetColSize(col=10, width=50)
         self.resultGrid.SetColLabelSize(height=20)
         self.resultGrid.SetColLabelSize(height=20)
-        self.resultGrid.SetDefaultRowSize(height=20)
+        self.resultGrid.SetDefaultRowSize(height=15)
         self.Bind(
         self.Bind(
           wx.grid.EVT_GRID_SELECT_CELL, self.resultSelected, self.resultGrid
           wx.grid.EVT_GRID_SELECT_CELL, self.resultSelected, self.resultGrid
         )
         )
+        self.resultContainer.Add(self.resultGrid)
 
 
         # Paginator
         # Paginator
         self.pgPrevBt = wx.Button(
         self.pgPrevBt = wx.Button(
-          parent=self, id=wx.ID_ANY, pos=(580, 30), size=(40, 50),
+          parent=self, id=wx.ID_ANY, pos=(530, 30), size=(40, 50),
           style=wx.LC_REPORT, label="Prev\npage"
           style=wx.LC_REPORT, label="Prev\npage"
         )
         )
+        self.resultContainer.Add(self.pgPrevBt)
         self.resultsPageIndicator = wx.StaticText(
         self.resultsPageIndicator = wx.StaticText(
-          parent=self,id=wx.ID_ANY, pos=(580, 80), size=(40, 15),
+          parent=self,id=wx.ID_ANY, pos=(530, 80), size=(40, 15),
           style=wx.ALIGN_CENTRE_HORIZONTAL, label="1/1"
           style=wx.ALIGN_CENTRE_HORIZONTAL, label="1/1"
         )
         )
+        self.resultContainer.Add(self.resultsPageIndicator)
         self.pgNextBt = wx.Button(
         self.pgNextBt = wx.Button(
-          parent=self, id=wx.ID_ANY, pos=(580, 100), size=(40, 50),
+          parent=self, id=wx.ID_ANY, pos=(530, 100), size=(40, 50),
           style=wx.LC_REPORT, label="Next\npage"
           style=wx.LC_REPORT, label="Next\npage"
         )
         )
+        self.resultContainer.Add(self.pgNextBt)
         self.Bind(wx.EVT_BUTTON, self.pgPrev, self.pgPrevBt)
         self.Bind(wx.EVT_BUTTON, self.pgPrev, self.pgPrevBt)
         self.Bind(wx.EVT_BUTTON, self.pgNext, self.pgNextBt)
         self.Bind(wx.EVT_BUTTON, self.pgNext, self.pgNextBt)
 
 
-        # Contains all thigs to be shown once a result is selected
-        self.resultContent = wx.BoxSizer(wx.VERTICAL)
-
         # Stats table
         # Stats table
         self.statGrid = wx.grid.Grid(
         self.statGrid = wx.grid.Grid(
-          parent=self, id=wx.ID_ANY, pos=(650, 30),
-          size=(205, 220), style=wx.LC_REPORT
+          parent=self, id=wx.ID_ANY, pos=(0, 210),
+          size=(185, 220), style=wx.LC_REPORT
         )
         )
         self.statGrid.CreateGrid(
         self.statGrid.CreateGrid(
           numRows=10, numCols=2,
           numRows=10, numCols=2,
@@ -237,27 +254,27 @@ class PanelResults(wx.Panel):
         runeListBox = [
         runeListBox = [
           wx.StaticBox(
           wx.StaticBox(
             parent=self, label="Slot1:",id=wx.ID_ANY,
             parent=self, label="Slot1:",id=wx.ID_ANY,
-            pos=(200, 255), size=(140, 160)
+            pos=(350, 210), size=(140, 160)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
             parent=self, label="Slot2:",id=wx.ID_ANY,
             parent=self, label="Slot2:",id=wx.ID_ANY,
-            pos=(350, 255), size=(140, 160)
+            pos=(500, 210), size=(140, 160)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
             parent=self, label="Slot3:",id=wx.ID_ANY,
             parent=self, label="Slot3:",id=wx.ID_ANY,
-            pos=(350, 420), size=(140, 160)
+            pos=(500, 375), size=(140, 160)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
             parent=self, label="Slot4:",id=wx.ID_ANY,
             parent=self, label="Slot4:",id=wx.ID_ANY,
-            pos=(200, 420), size=(140, 160)
+            pos=(350, 375), size=(140, 160)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
             parent=self, label="Slot5:",id=wx.ID_ANY,
             parent=self, label="Slot5:",id=wx.ID_ANY,
-            pos=(50, 420), size=(140, 160)
+            pos=(200, 375), size=(140, 160)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
             parent=self, label="Slot6:",id=wx.ID_ANY,
             parent=self, label="Slot6:",id=wx.ID_ANY,
-            pos=(50, 255), size=(140, 160)
+            pos=(200, 210), size=(140, 160)
           )
           )
         ]
         ]
         for i in range(0, 6):
         for i in range(0, 6):
@@ -523,16 +540,17 @@ class PanelResults(wx.Panel):
 
 
         # Action buttons
         # Action buttons
         applyBt = wx.Button(
         applyBt = wx.Button(
-          parent=self, id=wx.ID_ANY, pos=(650, 330), size=(165, 60),
+          parent=self, id=wx.ID_ANY, pos=(10, 450), size=(165, 60),
           style=wx.LC_REPORT, label="Apply runes"
           style=wx.LC_REPORT, label="Apply runes"
         )
         )
         self.Bind(wx.EVT_BUTTON, self.applyRunes, applyBt)
         self.Bind(wx.EVT_BUTTON, self.applyRunes, applyBt)
         self.resultContent.Add(applyBt)
         self.resultContent.Add(applyBt)
 
 
-        # By default, hide everything
+        # By default, hide everything TODO
+        self.resultContainer.ShowItems(False)
         self.resultContent.ShowItems(False)
         self.resultContent.ShowItems(False)
 
 
-    def processResults(self, jsonData):
+    def processResults(self, unitId=None, jsonData=""):
         """Processes data obtained from RuneOptimizer.
         """Processes data obtained from RuneOptimizer.
 
 
         Reads the JSON data and initializes the property data.
         Reads the JSON data and initializes the property data.
@@ -545,6 +563,41 @@ class PanelResults(wx.Panel):
 
 
         """
         """
 
 
+        if unitId != None:
+            self.unitId = unitId
+            cursor = conn.execute("""
+              SELECT
+                current_hp,
+                current_atk,
+                current_def,
+                current_spd,
+                current_crr,
+                current_crd,
+                current_res,
+                current_acc,
+                name
+              FROM units
+              WHERE
+              id = '""" + unitId + """';
+            """)
+            row = cursor.fetchone()
+            self.unitName = row[8]
+            for i in range(0, 8):
+                self.unitStats[i] = row[i]
+            # Calculate EHP and DMG
+            hp = row[0]
+            dfc = row[2]
+            ehp = math.ceil((((dfc * 3.5) + 1140) * hp) / 1000)
+            self.unitStats[8] = ehp
+            atk = row[1]
+            crr = row[4]
+            crd = row[5]
+            dmg = math.ceil(
+              (atk * (100 - crr) / 100) +
+              ((atk + (atk * crd / 100)) * crr / 100)
+            )
+            self.unitStats[9] = dmg
+
         self.data = json.loads(
         self.data = json.loads(
           jsonData,
           jsonData,
           object_hook=lambda d: SimpleNamespace(**d)
           object_hook=lambda d: SimpleNamespace(**d)
@@ -586,18 +639,6 @@ class PanelResults(wx.Panel):
             self.page += 1
             self.page += 1
             self.printResults()
             self.printResults()
 
 
-    def closeWindow(self, event):
-        """Closes the window.
-
-        Parameters
-        ----------
-        event : wxEvent, optional
-            The event that triggered the call (default is None).
-
-        """
-
-        self.Close(True)
-
     def applyRunes(self, event):
     def applyRunes(self, event):
         """Applies the selected results and saves data to the database.
         """Applies the selected results and saves data to the database.
 
 
@@ -614,8 +655,8 @@ class PanelResults(wx.Panel):
             # TODO: Show error
             # TODO: Show error
             return;
             return;
         print("self.selectedResultIndex: " + str(self.selectedResultIndex))
         print("self.selectedResultIndex: " + str(self.selectedResultIndex))
-        for i in range(0, 6):
-            print(self.data.results[self.selectedResultIndex].runes[i])
+        #for i in range(0, 6):
+        #    print(self.data.results[self.selectedResultIndex].runes[i])
         # First, unassign all runes currently assigned to the unit
         # First, unassign all runes currently assigned to the unit
         cursor = conn.execute(
         cursor = conn.execute(
           """
           """
@@ -668,7 +709,7 @@ class PanelResults(wx.Panel):
         recalculteStatsOfModifiedUnits()
         recalculteStatsOfModifiedUnits()
         print("All recalculated!")
         print("All recalculated!")
 
 
-        # Fetch the new values for self.currentStats
+        # Fetch the new values for self.unitStats
         cursor = conn.execute(
         cursor = conn.execute(
           """
           """
             SELECT
             SELECT
@@ -689,18 +730,18 @@ class PanelResults(wx.Panel):
         )
         )
         row = cursor.fetchone()
         row = cursor.fetchone()
         for i in range(0, 8):
         for i in range(0, 8):
-            self.currentStats[i] = int(row[i])
-        self.currentStats[9] = math.ceil(
-          (((self.currentStats[2] * 3.5) + 1140) * self.currentStats[0]) / 1000
+            self.unitStats[i] = int(row[i])
+        self.unitStats[9] = math.ceil(
+          (((self.unitStats[2] * 3.5) + 1140) * self.unitStats[0]) / 1000
         )
         )
-        self.currentStats[10] = math.ceil(
-          (self.currentStats[1] * (100 - self.currentStats[4]) / 100) +
+        self.unitStats[10] = math.ceil(
+          (self.unitStats[1] * (100 - self.unitStats[4]) / 100) +
           (
           (
             (
             (
-              self.currentStats[1] +
-              (self.currentStats[1] * self.currentStats[5] / 100)
+              self.unitStats[1] +
+              (self.unitStats[1] * self.unitStats[5] / 100)
             ) *
             ) *
-            self.currentStats[4] / 100
+            self.unitStats[4] / 100
           )
           )
         )
         )
         self.resultSelected(None)
         self.resultSelected(None)
@@ -746,6 +787,12 @@ class PanelResults(wx.Panel):
                 for j in range(0, 11):
                 for j in range(0, 11):
                     self.resultGrid.SetCellValue(row=i, col=j, s="")
                     self.resultGrid.SetCellValue(row=i, col=j, s="")
 
 
+        # Display the unit name
+        self.unitNameLabel.SetLabel(self.unitName + "    #" + self.unitId)
+
+        # Make the table visible
+        self.resultContainer.ShowItems(True)
+
     def resultSelected(self, event):
     def resultSelected(self, event):
         """Populates and shows the runes and effective stats with the
         """Populates and shows the runes and effective stats with the
         currently seleced result.
         currently seleced result.
@@ -766,7 +813,7 @@ class PanelResults(wx.Panel):
           s=str(self.data.results[self.selectedResultIndex].hp) + " "
           s=str(self.data.results[self.selectedResultIndex].hp) + " "
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].hp - self.currentStats[0]
+          self.data.results[self.selectedResultIndex].hp - self.unitStats[0]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=0, col=1, s="- " + str(abs(diff)) + " "
               row=0, col=1, s="- " + str(abs(diff)) + " "
@@ -789,7 +836,7 @@ class PanelResults(wx.Panel):
           s=str(self.data.results[self.selectedResultIndex].atk) + " "
           s=str(self.data.results[self.selectedResultIndex].atk) + " "
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].atk - self.currentStats[1]
+          self.data.results[self.selectedResultIndex].atk - self.unitStats[1]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=1, col=1, s="- " + str(abs(diff)) + " "
               row=1, col=1, s="- " + str(abs(diff)) + " "
@@ -810,7 +857,7 @@ class PanelResults(wx.Panel):
           s=str(self.data.results[self.selectedResultIndex].dfc) + " "
           s=str(self.data.results[self.selectedResultIndex].dfc) + " "
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].atk - self.currentStats[2]
+          self.data.results[self.selectedResultIndex].atk - self.unitStats[2]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=2, col=1, s="- " + str(abs(diff)) + " "
               row=2, col=1, s="- " + str(abs(diff)) + " "
@@ -833,7 +880,7 @@ class PanelResults(wx.Panel):
           s=str(self.data.results[self.selectedResultIndex].spd) + " "
           s=str(self.data.results[self.selectedResultIndex].spd) + " "
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].spd - self.currentStats[3]
+          self.data.results[self.selectedResultIndex].spd - self.unitStats[3]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=3, col=1, s="- " + str(abs(diff)) + " "
               row=3, col=1, s="- " + str(abs(diff)) + " "
@@ -857,7 +904,7 @@ class PanelResults(wx.Panel):
           s=str(self.data.results[self.selectedResultIndex].crr) + "%"
           s=str(self.data.results[self.selectedResultIndex].crr) + "%"
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].crr - self.currentStats[4]
+          self.data.results[self.selectedResultIndex].crr - self.unitStats[4]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=4, col=1, s="- " + str(abs(diff)) + "%"
               row=4, col=1, s="- " + str(abs(diff)) + "%"
@@ -878,7 +925,7 @@ class PanelResults(wx.Panel):
           s=str(self.data.results[self.selectedResultIndex].crd) + "%"
           s=str(self.data.results[self.selectedResultIndex].crd) + "%"
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].crd - self.currentStats[5]
+          self.data.results[self.selectedResultIndex].crd - self.unitStats[5]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=5, col=1, s="- " + str(abs(diff)) + "%"
               row=5, col=1, s="- " + str(abs(diff)) + "%"
@@ -901,7 +948,7 @@ class PanelResults(wx.Panel):
           s=str(self.data.results[self.selectedResultIndex].res) + "%"
           s=str(self.data.results[self.selectedResultIndex].res) + "%"
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].res - self.currentStats[6]
+          self.data.results[self.selectedResultIndex].res - self.unitStats[6]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=6, col=1, s="- " + str(abs(diff)) + "%"
               row=6, col=1, s="- " + str(abs(diff)) + "%"
@@ -921,7 +968,7 @@ class PanelResults(wx.Panel):
           row=7, col=0, s=str(self.data.results[self.selectedResultIndex].acc) + "%"
           row=7, col=0, s=str(self.data.results[self.selectedResultIndex].acc) + "%"
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].acc - self.currentStats[7]
+          self.data.results[self.selectedResultIndex].acc - self.unitStats[7]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=7, col=1, s="- " + str(abs(diff)) + "%"
               row=7, col=1, s="- " + str(abs(diff)) + "%"
@@ -944,7 +991,7 @@ class PanelResults(wx.Panel):
           s=str(self.data.results[self.selectedResultIndex].ehp) + " "
           s=str(self.data.results[self.selectedResultIndex].ehp) + " "
         )
         )
         diff = \
         diff = \
-          self.data.results[self.selectedResultIndex].ehp - self.currentStats[8]
+          self.data.results[self.selectedResultIndex].ehp - self.unitStats[8]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=8, col=1, s="- " + str(abs(diff)) + " "
               row=8, col=1, s="- " + str(abs(diff)) + " "
@@ -966,7 +1013,7 @@ class PanelResults(wx.Panel):
           row=9, col=0,
           row=9, col=0,
           s=str(self.data.results[self.selectedResultIndex].dmg) + " "
           s=str(self.data.results[self.selectedResultIndex].dmg) + " "
         )
         )
-        diff = self.data.results[self.selectedResultIndex].dmg - self.currentStats[9]
+        diff = self.data.results[self.selectedResultIndex].dmg - self.unitStats[9]
         if (diff < 0):
         if (diff < 0):
             self.statGrid.SetCellValue(
             self.statGrid.SetCellValue(
               row=9, col=1, s="- " + str(abs(diff)) + " "
               row=9, col=1, s="- " + str(abs(diff)) + " "
@@ -1074,3 +1121,6 @@ class PanelResults(wx.Panel):
                 else: # normal stats
                 else: # normal stats
                     self.runeStats[i][slot - 1].SetLabel(line)
                     self.runeStats[i][slot - 1].SetLabel(line)
             i += 1
             i += 1
+
+        # Make the info visible
+        self.resultContent.ShowItems(True)

+ 39 - 1
src/RuneOptimizerGUI/classes/PanelTeams.py

@@ -1 +1,39 @@
- 
+"""
+This file is part of RuneOptimizer.
+
+RuneOptimizer is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option)
+any later version.
+
+RuneOptimizer is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+more details.
+
+You should have received a copy of the GNU General Public License along with
+RuneOptimizer. If not, see <https://www.gnu.org/licenses/>.
+
+"""
+
+class PanelTeams(wx.Panel):
+    """
+    The team management Panel.
+
+    Parameters
+    ----------
+
+    Methods
+    -------
+
+    """
+
+    def __init__(self, parent, id=wx.ID_ANY):
+        """Initializes the panel.
+
+        Sets upt all the widgets.
+
+        """
+
+        # Parent constructor
+        wx.Panel.__init__(self, parent=parent, id=id)

+ 4 - 4
src/RuneOptimizerGUI/classes/PanelUnits.py

@@ -68,7 +68,7 @@ class PanelUnits(wx.Panel):
     runeInnates = None
     runeInnates = None
     runeStats = None
     runeStats = None
 
 
-    def __init__(self, parent):
+    def __init__(self, parent, id=wx.ID_ANY):
         """Initializes the panel.
         """Initializes the panel.
 
 
         Sets upt all the widgets.
         Sets upt all the widgets.
@@ -76,7 +76,7 @@ class PanelUnits(wx.Panel):
         """
         """
 
 
         # Parent constructor
         # Parent constructor
-        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+        wx.Panel.__init__(self, parent=parent, id=id)
 
 
         # Prepare some fonts
         # Prepare some fonts
         monospaceFont = wx.Font(
         monospaceFont = wx.Font(
@@ -598,7 +598,7 @@ class PanelUnits(wx.Panel):
         baseDmg = math.ceil(
         baseDmg = math.ceil(
           (baseAtk * (100 - baseCrr) / 100) +
           (baseAtk * (100 - baseCrr) / 100) +
           ((baseAtk + (baseAtk * baseCrd / 100)) * baseCrr / 100)
           ((baseAtk + (baseAtk * baseCrd / 100)) * baseCrr / 100)
-        );
+        )
         self.statGrid.SetCellValue(row=9, col=0, s=str(baseDmg))
         self.statGrid.SetCellValue(row=9, col=0, s=str(baseDmg))
         #self.minStatSlid[9].SetMin(baseDmg)
         #self.minStatSlid[9].SetMin(baseDmg)
         currentAtk = int(self.statGrid.GetCellValue(row=1, col=1))
         currentAtk = int(self.statGrid.GetCellValue(row=1, col=1))
@@ -612,7 +612,7 @@ class PanelUnits(wx.Panel):
         currentDmg = math.ceil(
         currentDmg = math.ceil(
           (currentAtk * (100 - currentCrr) / 100) +
           (currentAtk * (100 - currentCrr) / 100) +
           ((currentAtk + (currentAtk * currentCrd / 100)) * currentCrr / 100)
           ((currentAtk + (currentAtk * currentCrd / 100)) * currentCrr / 100)
-        );
+        )
         self.statGrid.SetCellValue(row=9, col=1, s=str(currentDmg))
         self.statGrid.SetCellValue(row=9, col=1, s=str(currentDmg))
         #self.minStatSlid[9].SetValue(currentDmg)
         #self.minStatSlid[9].SetValue(currentDmg)
         #self.minStatText[9].SetValue(str(currentDmg))
         #self.minStatText[9].SetValue(str(currentDmg))

+ 13 - 4
src/RuneOptimizerGUI/classes/TabList.py

@@ -29,6 +29,11 @@ class TabList(wx.Listbook):
 
 
     """
     """
 
 
+    frameUnits = None
+    frameTeams = None
+    frameOptimizer = None
+    frameResults = None
+
     def __init__(self, parent, id=wx.ID_ANY, pos=(0, 0), size=(800, 600), style=wx.LC_REPORT):
     def __init__(self, parent, id=wx.ID_ANY, pos=(0, 0), size=(800, 600), style=wx.LC_REPORT):
         """
         """
         Initializes the tablist.
         Initializes the tablist.
@@ -72,11 +77,15 @@ class TabList(wx.Listbook):
         self.AssignImageList(il)
         self.AssignImageList(il)
 
 
         # Create the entries
         # Create the entries
+        self.frameUnits = PanelUnits(self)
+        self.frameTeams = PanelTeams(self)
+        self.frameOptimizer = PanelOptimizer(self)
+        self.frameResults = PanelResults(self)
         pages = [
         pages = [
-          (PanelUnits(self), "Units"),
-          (PanelUnits(self), "Teams"),
-          (PanelUnits(self), "Optimize"),
-          (PanelUnits(self), "Results")
+          (self.frameUnits, "Units"),
+          (self.frameTeams, "Teams"),
+          (self.frameOptimizer, "Optimize"),
+          (self.frameResults, "Results")
         ]
         ]
 
 
         # Add icons to the entries
         # Add icons to the entries