ソースを参照

The JSON updater is now fully functional.

Iñigo Valentin 4 年 前
コミット
aa1ddea3df

+ 24 - 0
src/RuneOptimizer/RuneOptimizer.h

@@ -19,6 +19,30 @@
 
 char db_location[256];
 
+struct Rune_Set_Count {
+    unsigned short energy;
+    unsigned short guard;
+    unsigned short swift;
+    unsigned short blade;
+    unsigned short rage;
+    unsigned short focus;
+    unsigned short endure;
+    unsigned short fatal;
+    unsigned short despair;
+    unsigned short vampire;
+    unsigned short violent;
+    unsigned short nemesis;
+    unsigned short will;
+    unsigned short shield;
+    unsigned short revenge;
+    unsigned short destroy;
+    unsigned short fight;
+    unsigned short determination;
+    unsigned short enhance;
+    unsigned short accuracy;
+    unsigned short tolerance;
+};
+
 /**
  * Starts the program.
  *

+ 2 - 0
src/RuneOptimizer/error/error.h

@@ -66,3 +66,5 @@
 #define ERROR_DB_INSERT_UNITS 219
 #define ERROR_DB_INSERT_TEAMS 220
 #define ERROR_DB_INSERT_UNITS_TEAMS 221
+#define ERROR_DB_UPDATE_UNITS 222
+#define ERROR_DB_RUNES 223

+ 2 - 2
src/RuneOptimizer/optimize/optimize.c

@@ -1693,9 +1693,9 @@ int optimize(int argc, char *argv[]){
                 stats.def += unit.base_def * 0.15 * (set_count.guard % 2);
             if (set_count.swift >= 4) // +25% base SPD per set of 4
                 stats.spd += unit.base_spd * 0.25;
-            if (set_count.guard >= 2) // +12% CRR per set of 2
+            if (set_count.blade >= 2) // +12% CRR per set of 2
                 stats.crr += 12;
-            if (set_count.swift >= 4) // +40% CRD per set of 4
+            if (set_count.rage >= 4) // +40% CRD per set of 4
                 stats.crd += 40;
             if (set_count.focus >= 2) // +20% ACC per set of 2
                 stats.acc += 20;

+ 1 - 23
src/RuneOptimizer/optimize/optimize.h

@@ -107,29 +107,7 @@ struct Stats {
     unsigned short dmg;
 };
 
-struct Rune_Set_Count {
-    unsigned short energy;
-    unsigned short guard;
-    unsigned short swift;
-    unsigned short blade;
-    unsigned short rage;
-    unsigned short focus;
-    unsigned short endure;
-    unsigned short fatal;
-    unsigned short despair;
-    unsigned short vampire;
-    unsigned short violent;
-    unsigned short nemesis;
-    unsigned short will;
-    unsigned short shield;
-    unsigned short revenge;
-    unsigned short destroy;
-    unsigned short fight;
-    unsigned short determination;
-    unsigned short enhance;
-    unsigned short accuracy;
-    unsigned short tolerance;
-};
+
 typedef struct Result {
     unsigned char rune_ids[6][12];
     signed int rating;

+ 246 - 67
src/RuneOptimizer/update/update.c

@@ -33,8 +33,6 @@ int update(int argc, char *argv[]){
         return ERROR_INPUT_UPDATE_NO_ARGUMENTS;
     }
 
-
-
     // First, test json
     if (strlen(argv[0]) > 5){
         char extension[6];
@@ -43,7 +41,7 @@ int update(int argc, char *argv[]){
             return update_json(argv[0]);
         }
     }
-    // TODO: More ifs...
+    // TODO: More ifs as more options are implemented...
     fprintf(stderr, "Unknwon source supplied: %d\n", argv[0]);
     return ERROR_INPUT_UPDATE_UNKNOWN_SOURCE;
 }
@@ -57,7 +55,7 @@ int update(int argc, char *argv[]){
 int update_json(char file[]){
     printf("Updating from json file: %s\n", file);
 
-    // TODO: All file opening can be skkiped with
+    // Read the JSON content
     json_object *root = json_object_from_file(file);
     if (!root){
         fprintf(stderr, "Cant access file: %s\n", file);
@@ -91,7 +89,6 @@ int update_json(char file[]){
     json_object *runes = json_object_object_get(root, "runes");
     int rune_count = json_object_array_length(runes);
     json_object *idx;
-    // TODO: DEBug impossible condition
     for (int i = 0; i < rune_count; i++){
         total_runes ++;
         struct DB_Rune rune;
@@ -116,30 +113,21 @@ int update_json(char file[]){
         rune.buy_value = json_object_get_int(base_value);
         json_object *sell_value = json_object_object_get(idx, "sell_value");
         rune.sell_value = json_object_get_int(sell_value);
-        //printf("\tRune %d: Slot %d:\n", json_object_get_int(rune_id), json_object_get_int(slot_no));
+
         // Main stat
         json_object *pri_eff = json_object_object_get(idx, "pri_eff");
         json_object *pri_stat = json_object_array_get_idx(pri_eff, 0);
         rune.main.stat = json_object_get_int(pri_stat);
         json_object *pri_value = json_object_array_get_idx(pri_eff, 1);
         rune.main.value = json_object_get_int(pri_value);
-        //printf("\t\tMain %d: %d\n", json_object_get_int(pri_stat), json_object_get_int(pri_value));
 
         json_object *prefix_eff = json_object_object_get(idx, "prefix_eff");
-        // No need to check, if no innate, its 0
-        /*if (json_object_get_type(prefix_eff) == json_type_null){
-            printf("\t\tNo innate\n");
-        }
-        else{
-            json_object *prefix_stat = json_object_array_get_idx(prefix_eff, 0);
-            json_object *prefix_value = json_object_array_get_idx(prefix_eff, 0);
-            printf("\t\tInnate %d: %d\n", json_object_get_int(prefix_stat), json_object_get_int(prefix_value));
-        }*/
+
+        // Innate stat
         json_object *prefix_stat = json_object_array_get_idx(prefix_eff, 0);
         rune.innate.stat = json_object_get_int(prefix_stat);
         json_object *prefix_value = json_object_array_get_idx(prefix_eff, 1);
         rune.innate.value = json_object_get_int(prefix_value);
-        //printf("\t\tInnate %d: %d\n", json_object_get_int(prefix_stat), json_object_get_int(prefix_value));
 
         json_object *sec_eff = json_object_object_get(idx, "sec_eff");
         int stat_count = json_object_array_length(sec_eff);
@@ -152,17 +140,15 @@ int update_json(char file[]){
             rune.stats[i].stat = json_object_get_int(stat);
             json_object *value = json_object_array_get_idx(stat_idx, 1);
             rune.stats[i].value = json_object_get_int(value);
-            json_object *grind = json_object_array_get_idx(stat_idx, 2);
-            rune.stats[i].grind = json_object_get_int(grind);
-            json_object *enchant = json_object_array_get_idx(stat_idx, 3);
+            json_object *enchant = json_object_array_get_idx(stat_idx, 2);
+            rune.stats[i].enchant = json_object_get_int(enchant);
+            json_object *grind = json_object_array_get_idx(stat_idx, 3);
             rune.stats[i].grind = json_object_get_int(grind);
             //printf("\t\t\tStat %d: %d: (+%d, %d)\n", json_object_get_int(stat), json_object_get_int(value), json_object_get_int(grind), json_object_get_int(enchant));
         }
 
         // All the rune info has been loaded. Now, calculate the rest of stats
-        //printf("\n\n\nATK FLAT PRE : %d\n", rune.atk_flat);
         calculate_rune_totals(&rune);
-        //printf("ATK FLAT POST: %d\n", rune.atk_flat);
 
         // Insert the rune into the database
         sqlite3_stmt *res;
@@ -395,7 +381,6 @@ int update_json(char file[]){
     unsigned int total_units = 0;
     json_object *unit_list = json_object_object_get(root, "unit_list");
     int unit_count = json_object_array_length(unit_list);
-    // TODO: Debug remove limir
     for (int i = 0; i < unit_count; i++){
         total_units ++;
         struct DB_Unit unit;
@@ -431,9 +416,8 @@ int update_json(char file[]){
         if (strlen(json_object_get_string(homunculus_name)) > 0){
             strcpy(unit.name, json_object_get_string(homunculus_name));
         }
-        //printf("UNIT %s: %s\n", unit.id, unit.name);
 
-        // TODO: Insert unit
+        // Insert unit
         sqlite3_stmt *res;
         char sql[2000];
         strcpy(
@@ -445,7 +429,7 @@ int update_json(char file[]){
         "  stars,"
         "  level,"
         "  base_hp,"
-        "  base_akt,"
+        "  base_atk,"
         "  base_def,"
         "  base_spd,"
         "  base_crr,"
@@ -453,7 +437,7 @@ int update_json(char file[]){
         "  base_res,"
         "  base_acc,"
         "  current_hp,"
-        "  current_akt,"
+        "  current_atk,"
         "  current_def,"
         "  current_spd,"
         "  current_crr,"
@@ -536,7 +520,6 @@ int update_json(char file[]){
             rune.buy_value = json_object_get_int(base_value);
             json_object *sell_value = json_object_object_get(idx, "sell_value");
             rune.sell_value = json_object_get_int(sell_value);
-            //printf("\tRune %d: Slot %d:\n", json_object_get_int(rune_id), json_object_get_int(slot_no));
 
             // Main stat
             json_object *pri_eff = json_object_object_get(idx, "pri_eff");
@@ -544,23 +527,14 @@ int update_json(char file[]){
             rune.main.stat = json_object_get_int(pri_stat);
             json_object *pri_value = json_object_array_get_idx(pri_eff, 1);
             rune.main.value = json_object_get_int(pri_value);
-            //printf("\t\tMain %d: %d\n", json_object_get_int(pri_stat), json_object_get_int(pri_value));
 
             json_object *prefix_eff = json_object_object_get(idx, "prefix_eff");
-            // No need to check, if no innate, its 0
-            /*if (json_object_get_type(prefix_eff) == json_type_null){
-                printf("\t\tNo innate\n");
-            }
-            else{
-                json_object *prefix_stat = json_object_array_get_idx(prefix_eff, 0);
-                json_object *prefix_value = json_object_array_get_idx(prefix_eff, 0);
-                printf("\t\tInnate %d: %d\n", json_object_get_int(prefix_stat), json_object_get_int(prefix_value));
-            }*/
+
+            // Innate stat
             json_object *prefix_stat = json_object_array_get_idx(prefix_eff, 0);
             rune.innate.stat = json_object_get_int(prefix_stat);
             json_object *prefix_value = json_object_array_get_idx(prefix_eff, 1);
             rune.innate.value = json_object_get_int(prefix_value);
-            //printf("\t\tInnate %d: %d\n", json_object_get_int(prefix_stat), json_object_get_int(prefix_value));
 
             json_object *sec_eff = json_object_object_get(idx, "sec_eff");
             int stat_count = json_object_array_length(sec_eff);
@@ -573,17 +547,14 @@ int update_json(char file[]){
                 rune.stats[i].stat = json_object_get_int(stat);
                 json_object *value = json_object_array_get_idx(stat_idx, 1);
                 rune.stats[i].value = json_object_get_int(value);
-                json_object *grind = json_object_array_get_idx(stat_idx, 2);
-                rune.stats[i].grind = json_object_get_int(grind);
-                json_object *enchant = json_object_array_get_idx(stat_idx, 3);
+                json_object *enchant = json_object_array_get_idx(stat_idx, 2);
+                rune.stats[i].enchant = json_object_get_int(enchant);
+                json_object *grind = json_object_array_get_idx(stat_idx, 3);
                 rune.stats[i].grind = json_object_get_int(grind);
-                //printf("\t\t\tStat %d: %d: (+%d, %d)\n", json_object_get_int(stat), json_object_get_int(value), json_object_get_int(grind), json_object_get_int(enchant));
             }
 
             // All the rune info has been loaded. Now, calculate the rest of stats
-            //printf("\n\n\nATK FLAT PRE : %d\n", rune.atk_flat);
             calculate_rune_totals(&rune);
-            //printf("ATK FLAT POST: %d\n", rune.atk_flat);
 
             // Insert the rune into the database
             sqlite3_stmt *res;
@@ -835,7 +806,7 @@ int calculate_current_stats(){
       "SELECT"
       "  id,"
       "  base_hp,"
-      "  base_akt,"
+      "  base_atk,"
       "  base_def,"
       "  base_spd,"
       "  base_crr,"
@@ -843,7 +814,7 @@ int calculate_current_stats(){
       "  base_res,"
       "  base_acc,"
       "  current_hp,"
-      "  current_akt,"
+      "  current_atk,"
       "  current_def,"
       "  current_spd,"
       "  current_crr,"
@@ -867,21 +838,21 @@ int calculate_current_stats(){
 
     unsigned char id[12];
     unsigned int base_hp = 0;
-    unsigned char base_atk = 0;
-    unsigned char base_def = 0;
-    unsigned char base_spd = 0;
-    unsigned char base_crr = 0;
-    unsigned char base_crd = 0;
-    unsigned char base_res = 0;
-    unsigned char base_acc = 0;
+    unsigned int base_atk = 0;
+    unsigned int base_def = 0;
+    unsigned int base_spd = 0;
+    unsigned int base_crr = 0;
+    unsigned int base_crd = 0;
+    unsigned int base_res = 0;
+    unsigned int base_acc = 0;
     unsigned int current_hp = 0;
-    unsigned char current_atk = 0;
-    unsigned char current_def = 0;
-    unsigned char current_spd = 0;
-    unsigned char current_crr = 0;
-    unsigned char current_crd = 0;
-    unsigned char current_res = 0;
-    unsigned char current_acc = 0;
+    unsigned int current_atk = 0;
+    unsigned int current_def = 0;
+    unsigned int current_spd = 0;
+    unsigned int current_crr = 0;
+    unsigned int current_crd = 0;
+    unsigned int current_res = 0;
+    unsigned int current_acc = 0;
     while (SQLITE_ROW == sqlite3_step(stmt_select)){
         strcpy(id, sqlite3_column_text(stmt_select, 0));
         base_hp = sqlite3_column_int(stmt_select, 1);
@@ -900,10 +871,216 @@ int calculate_current_stats(){
         current_crd = base_crd;
         current_res = base_res;
         current_acc = base_acc;
-        // TODO: Loop runes and add flat and percent stats
-        // TODO: Also, count rune sets for bonus
-        // TODO: Cap cappable stats
-        // TODO: Update in database
+
+        // Loop runes and add flat and percent stats
+        // Also, count rune sets for bonus
+        struct Rune_Set_Count set_count;
+        set_count.energy = 0;
+        set_count.guard = 0;
+        set_count.swift = 0;
+        set_count.blade = 0;
+        set_count.rage = 0;
+        set_count.focus = 0;
+        set_count.endure = 0;
+        set_count.fatal = 0;
+        set_count.despair = 0;
+        set_count.vampire = 0;
+        set_count.violent = 0;
+        set_count.nemesis = 0;
+        set_count.will = 0;
+        set_count.shield = 0;
+        set_count.revenge = 0;
+        set_count.destroy = 0;
+        set_count.fight = 0;
+        set_count.determination = 0;
+        set_count.enhance = 0;
+        set_count.accuracy = 0;
+        set_count.tolerance = 0;
+        strcpy(
+          query,
+          "SELECT"
+          "  type,"
+          "  current_hp_flat,"
+          "  current_atk_flat,"
+          "  current_def_flat,"
+          "  current_hp_percent,"
+          "  current_atk_percent,"
+          "  current_def_percent,"
+          "  current_spd,"
+          "  current_crr,"
+          "  current_crd,"
+          "  current_res,"
+          "  current_acc,"
+          "  slot"
+          " FROM runes WHERE unit = ?"
+        );
+        sqlite3_stmt *stmt_runes;
+        if (SQLITE_OK != sqlite3_prepare_v2(db, query, -1, &stmt_runes, 0)) {
+            fprintf(stderr, "Error getting runes: %s\n", sqlite3_errmsg(db));
+            return ERROR_DB_RUNES;
+        }
+        sqlite3_bind_text(stmt_runes, 1, id, strlen(id), NULL);
+        while (SQLITE_ROW == sqlite3_step(stmt_runes)){
+            // Switch the rune set
+            switch (sqlite3_column_int(stmt_runes, 0)){
+                case ENERGY:
+                    set_count.energy ++;
+                    break;
+                case GUARD:
+                    set_count.guard ++;
+                    break;
+                case SWIFT:
+                    set_count.swift ++;
+                    break;
+                case BLADE:
+                    set_count.blade ++;
+                    break;
+                case RAGE:
+                    set_count.rage ++;
+                    break;
+                case FOCUS:
+                    set_count.focus ++;
+                    break;
+                case ENDURE:
+                    set_count.endure ++;
+                    break;
+                case FATAL:
+                    set_count.fatal ++;
+                    break;
+                case DESPAIR:
+                    set_count.despair ++;
+                    break;
+                case VAMPIRE:
+                    set_count.vampire ++;
+                    break;
+                case VIOLENT:
+                    set_count.violent ++;
+                    break;
+                case NEMESIS:
+                    set_count.nemesis ++;
+                    break;
+                case WILL:
+                    set_count.will ++;
+                    break;
+                case SHIELD:
+                    set_count.shield ++;
+                    break;
+                case REVENGE:
+                    set_count.revenge ++;
+                    break;
+                case DESTROY:
+                    set_count.destroy ++;
+                    break;
+                case FIGHT:
+                    set_count.fight ++;
+                    break;
+                case DETERMINATION:
+                    set_count.determination ++;
+                    break;
+                case ENHANCE:
+                    set_count.enhance ++;
+                    break;
+                case ACCURACY:
+                    set_count.accuracy ++;
+                    break;
+                case TOLERANCE:
+                    set_count.tolerance ++;
+                    break;
+            }
+
+            //Add rune values
+            current_hp += sqlite3_column_int(stmt_runes, 1);
+            current_atk += sqlite3_column_int(stmt_runes, 2);
+            current_def += sqlite3_column_int(stmt_runes, 3);
+            current_hp += base_hp * sqlite3_column_int(stmt_runes, 4) / 100;
+            current_atk += base_atk * sqlite3_column_int(stmt_runes, 5) / 100;
+            current_def += base_def * sqlite3_column_int(stmt_runes, 6) / 100;
+            current_spd += sqlite3_column_int(stmt_runes, 7);
+            current_crr += sqlite3_column_int(stmt_runes, 8);
+            current_crd += sqlite3_column_int(stmt_runes, 9);
+            current_res += sqlite3_column_int(stmt_runes, 10);
+            current_acc += sqlite3_column_int(stmt_runes, 11);
+        }
+        sqlite3_finalize(stmt_runes);
+
+        // Rune set bonuses
+        if (set_count.energy >= 2) // +15% Base HP per set of 2
+            current_hp += base_hp * 0.15 * (set_count.energy % 2);
+        if (set_count.guard >= 2) // +15% base DEF per set of 2
+            current_def += base_def * 0.15 * (set_count.guard % 2);
+        if (set_count.swift >= 4) // +25% base SPD per set of 4
+            current_spd += base_spd * 0.25;
+        if (set_count.blade >= 2) // +12% CRR per set of 2
+            current_crr += 12;
+        if (set_count.rage >= 4) // +40% CRD per set of 4
+            current_crd += 40;
+        if (set_count.focus >= 2) // +20% ACC per set of 2
+            current_acc += 20;
+        if (set_count.endure >= 2) // +20% RES per set of 2
+            current_res += 20;
+        if (set_count.fatal >= 4) // +35% base ATK per set of 4
+            current_atk += base_atk * 0.35;
+        if (set_count.fight >= 2) // +8% base ATK per set of 2
+            current_atk += base_atk * 0.08 * (set_count.fight % 2);
+        if (set_count.determination >= 2) // +8% base DEF per set of 2
+            current_def += base_def * 0.08 * (set_count.determination % 2);
+        if (set_count.enhance >= 2) // +8% base HP per set of 2
+            current_hp += base_hp * 0.08 * (set_count.enhance % 2);
+        if (set_count.accuracy >= 2) // +10% ACC per set of 2
+            current_acc += 20;
+        if (set_count.tolerance >= 2) // +10% RES per set of 2
+            current_res += 20;
+
+        // Cap limited stats
+        if (current_crr > 100) current_crr = 100;
+        if (current_res > 100) current_res = 100;
+        if (current_acc > 85) current_acc = 85;
+
+        // Update in database
+        sqlite3_stmt *stmt_update;
+        strcpy(
+          query,
+          "UPDATE units SET"
+          "  current_hp = ?,"
+          "  current_atk = ?,"
+          "  current_def = ?,"
+          "  current_spd = ?,"
+          "  current_crr = ?,"
+          "  current_crd = ?,"
+          "  current_res = ?,"
+          "  current_acc = ?"
+          "WHERE id = ?"
+        );
+        if (SQLITE_OK != sqlite3_prepare_v2(db, query, -1, &stmt_update, 0)) {
+            fprintf(
+            stderr,
+            "Failed to prepare statement to update units: %s\n",
+            sqlite3_errmsg(db)
+            );
+            sqlite3_finalize(stmt_update);
+            sqlite3_close(db);
+            return ERROR_DB_UPDATE_UNITS;
+        }
+        sqlite3_bind_int(stmt_update, 1, current_hp);
+        sqlite3_bind_int(stmt_update, 2, current_atk);
+        sqlite3_bind_int(stmt_update, 3, current_def);
+        sqlite3_bind_int(stmt_update, 4, current_spd);
+        sqlite3_bind_int(stmt_update, 5, current_crr);
+        sqlite3_bind_int(stmt_update, 6, current_crd);
+        sqlite3_bind_int(stmt_update, 7, current_res);
+        sqlite3_bind_int(stmt_update, 8, current_acc);
+        sqlite3_bind_text(stmt_update, 9, id, strlen(id), NULL);
+        if (SQLITE_DONE != sqlite3_step(stmt_update)){
+            fprintf(
+            stderr,
+            "Failed to execute statement to update units: %s\n",
+            sqlite3_errmsg(db)
+            );
+            sqlite3_finalize(stmt_update);
+            sqlite3_close(db);
+            return ERROR_DB_UPDATE_UNITS;
+        }
+        sqlite3_finalize(stmt_update);
     }
     sqlite3_finalize(stmt_select);
     sqlite3_close(db);
@@ -1099,7 +1276,7 @@ int recreate_tables(){
       "  stars INT,"
       "  level INT,"
       "  base_hp INT,"
-      "  base_akt INT,"
+      "  base_atk INT,"
       "  base_def INT,"
       "  base_spd INT,"
       "  base_crr INT,"
@@ -1107,7 +1284,7 @@ int recreate_tables(){
       "  base_res INT,"
       "  base_acc INT,"
       "  current_hp INT,"
-      "  current_akt INT,"
+      "  current_atk INT,"
       "  current_def INT,"
       "  current_spd INT,"
       "  current_crr INT,"
@@ -7072,5 +7249,7 @@ void get_monster_name(int id, char name[64]){
         case 25615:
             strcpy(name, "Maya");
             break;
+        default:
+            strcpy(name, "UNKNOWN MONSTER");
     }
 }

+ 33 - 33
src/RuneOptimizer/update/update.h

@@ -62,39 +62,39 @@ struct DB_Rune {
     unsigned int buy_value;
     unsigned int sell_value;
     unsigned char unit[12];
-    unsigned char current_hp_percent;
-    unsigned char current_atk_percent;
-    unsigned char current_def_percent;
-    unsigned char current_hp_flat;
-    unsigned char current_atk_flat;
-    unsigned char current_def_flat;
-    unsigned char current_spd;
-    unsigned char current_crr;
-    unsigned char current_crd;
-    unsigned char current_acc;
-    unsigned char current_res;
-    unsigned char lv12_hp_percent;
-    unsigned char lv12_atk_percent;
-    unsigned char lv12_def_percent;
-    unsigned char lv12_hp_flat;
-    unsigned char lv12_atk_flat;
-    unsigned char lv12_def_flat;
-    unsigned char lv12_spd;
-    unsigned char lv12_crr;
-    unsigned char lv12_crd;
-    unsigned char lv12_acc;
-    unsigned char lv12_res;
-    unsigned char lv15_hp_percent;
-    unsigned char lv15_atk_percent;
-    unsigned char lv15_def_percent;
-    unsigned char lv15_hp_flat;
-    unsigned char lv15_atk_flat;
-    unsigned char lv15_def_flat;
-    unsigned char lv15_spd;
-    unsigned char lv15_crr;
-    unsigned char lv15_crd;
-    unsigned char lv15_acc;
-    unsigned char lv15_res;
+    unsigned int current_hp_percent;
+    unsigned int current_atk_percent;
+    unsigned int current_def_percent;
+    unsigned int current_hp_flat;
+    unsigned int current_atk_flat;
+    unsigned int current_def_flat;
+    unsigned int current_spd;
+    unsigned int current_crr;
+    unsigned int current_crd;
+    unsigned int current_acc;
+    unsigned int current_res;
+    unsigned int lv12_hp_percent;
+    unsigned int lv12_atk_percent;
+    unsigned int lv12_def_percent;
+    unsigned int lv12_hp_flat;
+    unsigned int lv12_atk_flat;
+    unsigned int lv12_def_flat;
+    unsigned int lv12_spd;
+    unsigned int lv12_crr;
+    unsigned int lv12_crd;
+    unsigned int lv12_acc;
+    unsigned int lv12_res;
+    unsigned int lv15_hp_percent;
+    unsigned int lv15_atk_percent;
+    unsigned int lv15_def_percent;
+    unsigned int lv15_hp_flat;
+    unsigned int lv15_atk_flat;
+    unsigned int lv15_def_flat;
+    unsigned int lv15_spd;
+    unsigned int lv15_crr;
+    unsigned int lv15_crd;
+    unsigned int lv15_acc;
+    unsigned int lv15_res;
     struct Rune_Stat main;
     struct Rune_Stat innate;
     unsigned char stat_count;