|
|
@@ -84,6 +84,43 @@
|
|
|
*/
|
|
|
#define RUNE_QUERY_LEN 3500
|
|
|
|
|
|
+/**
|
|
|
+ * Rating point given for a rune set of 2.
|
|
|
+ *
|
|
|
+ * Applies for Nemesis, Will, Shield, Revenge and Destroy. Loosely calculated
|
|
|
+ * to compensate for the stat loss for not equipping a stat boosting set of 2.
|
|
|
+ */
|
|
|
+#define RATING_SET_OF_2 21.586
|
|
|
+
|
|
|
+/**
|
|
|
+ * Rating point given for a rune set of 4.
|
|
|
+ *
|
|
|
+ * Applies for Despair, Vampire and Violent. Loosely calculated to compensate
|
|
|
+ * for the stat loss for not equipping a stat boosting set of 4.
|
|
|
+ */
|
|
|
+#define RATING_SET_OF_4 43.860
|
|
|
+
|
|
|
+/**
|
|
|
+ * Rating point giving for a Fight or Determination set.
|
|
|
+ *
|
|
|
+ * Loosely calculated to compensate for not equipping a individual set.
|
|
|
+ */
|
|
|
+#define RATING_SET_FIG_DET 14.828
|
|
|
+
|
|
|
+/**
|
|
|
+ * Rating point giving for a Enhance set.
|
|
|
+ *
|
|
|
+ * Loosely calculated to compensate for not equipping a individual set.
|
|
|
+ */
|
|
|
+#define RATING_SET_ENH 11.520
|
|
|
+
|
|
|
+/**
|
|
|
+ * Rating point giving for a Accuracy or Tolerance set.
|
|
|
+ *
|
|
|
+ * Loosely calculated to compensate for not equipping a individual set.
|
|
|
+ */
|
|
|
+#define RATING_SET_ACC_TOL 6.950
|
|
|
+
|
|
|
/**
|
|
|
* Limit on runes per slot for the optimizations.
|
|
|
*
|
|
|
@@ -1034,6 +1071,74 @@ static int read_unit(char *id, Unit *unit){
|
|
|
unit->current_dmg = calculate_dmg(
|
|
|
unit->current_atk, unit->current_crr, unit->current_crd
|
|
|
);
|
|
|
+
|
|
|
+ // Calculate the rating points that the current set would give.
|
|
|
+ // Non-stat-boosting sets and team stat sets add to this, to compensate
|
|
|
+ // the stat loss.
|
|
|
+ // Later, for each result, this must be substracted to the calculated
|
|
|
+ // rating
|
|
|
+ unit->set_rating_points = 0.0f;
|
|
|
+ Rune_Set_Count sets;
|
|
|
+ struct Stats stats;
|
|
|
+ sets.despair = 0;
|
|
|
+ sets.vampire = 0;
|
|
|
+ sets.violent = 0;
|
|
|
+ sets.nemesis = 0;
|
|
|
+ sets.will = 0;
|
|
|
+ sets.shield = 0;
|
|
|
+ sets.revenge = 0;
|
|
|
+ sets.destroy = 0;
|
|
|
+ sets.fight = 0;
|
|
|
+ sets.determination = 0;
|
|
|
+ sets.enhance = 0;
|
|
|
+ sets.accuracy = 0;
|
|
|
+ sets.tolerance = 0;
|
|
|
+ sqlite3_stmt *stmt_runes;
|
|
|
+ strcpy(parameters[0], (char *) id);
|
|
|
+ db_query(&stmt_runes, "SELECT type FROM runes WHERE unit = ?", parameters);
|
|
|
+ while (SQLITE_ROW == sqlite3_step(stmt_runes)){
|
|
|
+ int type = sqlite3_column_int(stmt_runes, 0);
|
|
|
+ switch (type){
|
|
|
+ case DESPAIR: sets.despair ++; break;
|
|
|
+ case VAMPIRE: sets.vampire ++; break;
|
|
|
+ case VIOLENT: sets.violent ++; break;
|
|
|
+ case NEMESIS: sets.nemesis ++; break;
|
|
|
+ case WILL: sets.will ++; break;
|
|
|
+ case SHIELD: sets.shield ++; break;
|
|
|
+ case REVENGE: sets.revenge ++; break;
|
|
|
+ case DESTROY: sets.destroy ++; break;
|
|
|
+ case FIGHT: sets.fight ++; break;
|
|
|
+ case DETERMINATION: sets.determination ++; break;
|
|
|
+ case ENHANCE: sets.enhance ++; break;
|
|
|
+ case ACCURACY: sets.accuracy ++; break;
|
|
|
+ case TOLERANCE: sets.tolerance ++; break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (sets.nemesis >= 2)
|
|
|
+ unit->set_rating_points += RATING_SET_OF_2 * floor(sets.nemesis / 2);
|
|
|
+ if (sets.will >= 2)
|
|
|
+ unit->set_rating_points += RATING_SET_OF_2 * floor(sets.will / 2);
|
|
|
+ if (sets.shield >= 2)
|
|
|
+ unit->set_rating_points += RATING_SET_OF_2 * floor(sets.shield / 2);
|
|
|
+ if (sets.revenge >= 2)
|
|
|
+ unit->set_rating_points += RATING_SET_OF_2 * floor(sets.revenge / 2);
|
|
|
+ if (sets.destroy >= 2)
|
|
|
+ unit->set_rating_points += RATING_SET_OF_2 * floor(sets.destroy / 2);
|
|
|
+ if (sets.despair >= 4 || sets.vampire >= 4 || sets.violent >= 4)
|
|
|
+ unit->set_rating_points += 43.86;
|
|
|
+ if (sets.fight >= 2)
|
|
|
+ unit->set_rating_points += RATING_SET_FIG_DET * floor(sets.fight / 2);
|
|
|
+ if (sets.determination >= 2)
|
|
|
+ unit->set_rating_points +=
|
|
|
+ RATING_SET_FIG_DET * floor(sets.determination / 2);
|
|
|
+ if (sets.enhance >= 2)
|
|
|
+ unit->set_rating_points += RATING_SET_ENH * floor(sets.enhance / 2);
|
|
|
+ if (sets.accuracy >= 2)
|
|
|
+ unit->set_rating_points +=
|
|
|
+ RATING_SET_ACC_TOL * floor(sets.accuracy / 2);
|
|
|
+ if (sets.tolerance >= 2)
|
|
|
+ unit->set_rating_points +=
|
|
|
+ RATING_SET_ACC_TOL * floor(sets.tolerance / 2);
|
|
|
return(SUCCESS);
|
|
|
}
|
|
|
|
|
|
@@ -1427,10 +1532,10 @@ static thrd_start_t optimize_thread(void *data_ptr){
|
|
|
// Set stats
|
|
|
if (set_count.energy >= 2) // +15% Base HP per set of 2
|
|
|
stats.hp +=
|
|
|
- data->unit->base_hp * 0.15 * (set_count.energy % 2);
|
|
|
+ data->unit->base_hp * 0.15 * floor(set_count.energy / 2);
|
|
|
if (set_count.guard >= 2) // +15% base DEF per set of 2
|
|
|
stats.def +=
|
|
|
- data->unit->base_def * 0.15 * (set_count.guard % 2);
|
|
|
+ data->unit->base_def * 0.15 * floor(set_count.guard / 2);
|
|
|
if (set_count.swift >= 4) // +25% base SPD per set of 4
|
|
|
stats.spd += data->unit->base_spd * 0.25;
|
|
|
if (set_count.blade >= 2) // +12% CRR per set of 2
|
|
|
@@ -1445,14 +1550,14 @@ static thrd_start_t optimize_thread(void *data_ptr){
|
|
|
stats.atk += data->unit->base_atk * 0.35;
|
|
|
if (set_count.fight >= 2) // +8% base ATK per set of 2
|
|
|
stats.atk +=
|
|
|
- data->unit->base_atk * 0.08 * (set_count.fight % 2);
|
|
|
+ data->unit->base_atk * 0.08 * floor(set_count.fight / 2);
|
|
|
if (set_count.determination >= 2) // +8% base DEF per set of 2
|
|
|
stats.def +=
|
|
|
data->unit->base_def * 0.08
|
|
|
- * (set_count.determination % 2);
|
|
|
+ * floor(set_count.determination / 2);
|
|
|
if (set_count.enhance >= 2) // +8% base HP per set of 2
|
|
|
stats.hp +=
|
|
|
- data->unit->base_hp * 0.08 * (set_count.enhance % 2);
|
|
|
+ data->unit->base_hp * 0.08 * floor(set_count.enhance / 2);
|
|
|
if (set_count.accuracy >= 2) // +10% ACC per set of 2
|
|
|
stats.acc += 10;
|
|
|
if (set_count.tolerance >= 2) // +10% RES per set of 2
|
|
|
@@ -1483,41 +1588,88 @@ static thrd_start_t optimize_thread(void *data_ptr){
|
|
|
// 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
|
|
|
+ // the (flat) stats roll for a substat 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
|
|
|
+ // HP: 1 rating point per 62.500 points
|
|
|
+ // ATK: 1 rating point per 3.333 points
|
|
|
+ // DEF: 1 rating point per 3.333 points
|
|
|
+ // SPD: 1 rating point per 1.000 points
|
|
|
+ // CRR: 1 rating point per 1.000 points
|
|
|
+ // CRD: 1 rating point per 1.166 points
|
|
|
+ // RES: 1 rating point per 1.333 points
|
|
|
+ // ACC: 1 rating point per 1.333 points
|
|
|
float rating = 0.0f;
|
|
|
rating +=
|
|
|
(float) ((int) stats.hp - (int) data->unit->current_hp )
|
|
|
- / 58.29f;
|
|
|
+ / 62.500f;
|
|
|
rating +=
|
|
|
(float) ((int) stats.atk - (int) data->unit->current_atk)
|
|
|
- / 1.50f;
|
|
|
+ / 3.333f;
|
|
|
rating +=
|
|
|
(float) ((int) stats.def - (int) data->unit->current_def)
|
|
|
- / 1.50f;
|
|
|
+ / 3.333f;
|
|
|
rating +=
|
|
|
(float) ((int) stats.spd - (int) data->unit->current_spd)
|
|
|
- / 1.00f;
|
|
|
+ / 1.000f;
|
|
|
rating +=
|
|
|
(float) ((int) stats.crr - (int) data->unit->current_crr)
|
|
|
- / 1.38f;
|
|
|
+ / 1.000f;
|
|
|
rating +=
|
|
|
(float) ((int) stats.crd - (int) data->unit->current_crd)
|
|
|
- / 1.90f;
|
|
|
+ / 1.166f;
|
|
|
rating +=
|
|
|
(float) ((int) stats.res - (int) data->unit->current_res)
|
|
|
- / 1.52f;
|
|
|
+ / 1.333f;
|
|
|
rating +=
|
|
|
(float) ((int) stats.acc - (int) data->unit->current_acc)
|
|
|
- / 1.52f;
|
|
|
+ / 1.333f;
|
|
|
+
|
|
|
+ // Non-stat sets also count for ratings.
|
|
|
+ // These ratings are loosely calculated to make up for the
|
|
|
+ // stats not boosted.
|
|
|
+ // Individual sets of 2 (Nenesis, Will, Shield, Revenge,
|
|
|
+ // Destroy) give RATING_SET_OF_2 points each.
|
|
|
+ // Sets of 4 (Despair, Violent, Vampire) give
|
|
|
+ // RATING_SET_OF_4 points
|
|
|
+ if (set_count.nemesis >= 2)
|
|
|
+ rating += RATING_SET_OF_2 * floor(set_count.nemesis / 2);
|
|
|
+ if (set_count.will >= 2)
|
|
|
+ rating += RATING_SET_OF_2 * floor(set_count.will / 2);
|
|
|
+ if (set_count.shield >= 2)
|
|
|
+ rating += RATING_SET_OF_2 * floor(set_count.shield / 2);
|
|
|
+ if (set_count.revenge >= 2)
|
|
|
+ rating += RATING_SET_OF_2 * floor(set_count.revenge / 2);
|
|
|
+ if (set_count.destroy >= 2)
|
|
|
+ rating += RATING_SET_OF_2 * floor(set_count.destroy / 2);
|
|
|
+ if (
|
|
|
+ set_count.despair >= 4
|
|
|
+ || set_count.vampire >= 4
|
|
|
+ || set_count.violent >= 4
|
|
|
+ ) rating += 43.86;
|
|
|
+
|
|
|
+ // Team stat bosting sets also boost ratings. These values are
|
|
|
+ // calculated from their equivalent individual sets,
|
|
|
+ // considering a team of 4.
|
|
|
+ // Fight, Determination: RATING_SET_FIG_DET points for each set.
|
|
|
+ // Enhance: +RATING_SET_ENH points for each set.
|
|
|
+ // Accuracy, Tolerance: RATING_SET_ACC_TOL points for each set
|
|
|
+ if (set_count.fight >= 2)
|
|
|
+ rating += RATING_SET_FIG_DET * floor(set_count.fight / 2);
|
|
|
+ if (set_count.determination >= 2)
|
|
|
+ rating +=
|
|
|
+ RATING_SET_FIG_DET * floor(set_count.determination / 2);
|
|
|
+ if (set_count.enhance >= 2)
|
|
|
+ rating += RATING_SET_ENH * floor(set_count.enhance / 2);
|
|
|
+ if (set_count.accuracy >= 2)
|
|
|
+ rating +=
|
|
|
+ RATING_SET_ACC_TOL * floor(set_count.accuracy / 2);
|
|
|
+ if (set_count.tolerance >= 2)
|
|
|
+ rating +=
|
|
|
+ RATING_SET_ACC_TOL * floor(set_count.tolerance / 2);
|
|
|
+
|
|
|
+ // Substract the rating for the currently equipped sets.
|
|
|
+
|
|
|
+ rating -= data->unit->set_rating_points;
|
|
|
|
|
|
// This is a valid sets and all stats are above the minimum.
|
|
|
// Create a result with rune indexes, stats, and rating.
|