/*
* 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 .
*/
/**
* @file runeoptimizer.c
*
* Implementation of the functions used by the gui command.
*
* This file implements the main function, and the functions declared in
* {@link runeoptimizer.h}.
*/
#include
#include
#include
#include
#include
#include "runeoptimizer.h"
#include "error/error.h"
#include "db/db.h"
#include "help/help.h"
#include "optimize/optimize.h"
#include "team/team.h"
#include "unit/unit.h"
#include "update/update.h"
#include "player/player.h"
#include "gui/gui.h"
/**
* DEF stat multiplier.
*
* For effective HP calculation.
*/
#define EHP_DEF_MULTIPLIER 3.5f
/**
* DEF base value.
*
* For effective HP calculation.
*/
#define EHP_DEF_BASE 1140.0f
/**
* HP stat divider.
*
* For effective HP calculation.
*/
#define EHP_HP_DIVIDER 1000.0f
/**
* Just 100.
*
* For perccentage calculations.
*/
#define PERCENT 100.0f
/**
* Command version.
*
* Keyword to launch the version command.
*/
#define CMD_VERSION "version"
/**
* Command update.
*
* Keyword to launch the update command.
*/
#define CMD_UPDATE "update"
/**
* Command optimize.
*
* Keyword to launch the optimize command.
*/
#define CMD_OPTIMIZE "optimize"
/**
* Command help.
*
* Keyword to launch the help command.
*/
#define CMD_HELP "help"
/**
* Command team.
*
* Keyword to launch the team command.
*/
#define CMD_TEAM "team"
/**
* Command unit.
*
* Keyword to launch the unit command.
*/
#define CMD_UNIT "unit"
/**
* Command player.
*
* Keyword to launch the player command.
*/
#define CMD_PLAYER "player"
/**
* Command gui.
*
* Keyword to launch the gui command.
*/
#define CMD_GUI "gui"
#ifdef _WIN32
/**
* Home environment variable for Windows.
*
* Key to get the environment variable to determine the user directory.
*/
#define ENV_VAR_HOME "APPDATA"
/**
* The default path to the database for Windows.
*
* Relative (and to be appended to) the user directory path.
* @todo: This won't work on Windows.
*/
#define DEFAULT_DB_PATH_FROM_HOME "/RuneOptimizer/data.sqlite"
#else
/**
* Home environment variable for Linux.
*
* Key to get the environment variable to determine the user directory.
*/
#define ENV_VAR_HOME "HOME"
/**
* The default path to the database for Linux.
*
* Relative (and to be appended to) the user directory path.
* @todo: This won't work on Windows.
*/
#define DEFAULT_DB_PATH_FROM_HOME "/.local/share/RuneOptimizer/data.sqlite"
#endif
/**
* Argument cutter for program arguments.
*
* Determines how many parameters will be removed from the start of the list of
* parameters passed to the program before passing that list to any command that
* needs them.
*
* Basically it to remove the executable name and the command name.
*/
#define ARGS_CUT_FOR_COMMANDS 2
sqlite3 *db = NULL;
char db_location[DB_PATH_LEN];
const char STAT_NAMES[DIFFERENT_STATS][9] = {
"NULL", "HP_FLAT", "HP", "ATK_FLAT", "ATK", "DEF_FLAT",
"DEF", "NULL", "SPD", "CRR", "CRD", "RES", "ACC"
};
const char SET_NAMES[DIFFERENT_SETS][9] = {
"NULL", "ENERGY", "GUARD", "SWIFT", "BLADE", "RAGE",
"FOCUS", "ENDURE", "FATAL", "NULL", "DESPAIR", "VAMPIRE",
"NULL", "VIOLENT", "NEMESIS", "WILL", "SHIELD", "REVENGE",
"DESTROY", "FIGHT", "DETERMIN", "ENHANCE", "ACCURACY", "TOLERANCE"
};
const char QUALITY_NAMES[DIFFERENT_QUALITIES][9] = {
"NULL",
"NORMAL", "MAGIC", "RARE", "HERO", "LEGEND", // 1-5
"NULL", "NULL", "NULL", "NULL", "NULL",
"A.NORMAL", "A.MAGIC", "A.RARE", "A.HERO", "A.LEGEND" //11-15
};
const char STAT_NAMES_PRINTABLE[DIFFERENT_STATS][12] = {
"NULL",
"HP %4d ", "HP %4d%% ", "ATK %4d ", "ATK %4d%% ", "DEF %4d ", "DEF %4d%% ", // 1-6
"NULL",
"SPD %4d ", "CRR %4d%% ", "CRD %4d%% ", "RES %4d%% ", "ACC %4d%% " // 8-12
};
const int STAT_ROLL_MAX[DIFFERENT_STATS][RUNE_MAX_STARS + 1] = {
{-1, -1, -1, -1, -1, -1, -1}, // NULL (unused)
{-1, 60, 105, 165, 225, 300, 375}, // HP
{-1, 2, 3, 5, 6, 7, 8}, // HP%
{-1, 4, 5, 8, 10, 15, 20}, // ATK
{-1, 2, 3, 5, 6, 7, 8}, // ATK%
{-1, 4, 5, 8, 10, 15, 20}, // DEF
{-1, 2, 3, 5, 6, 7, 8}, // DEF%
{-1, -1, -1, -1, -1, -1, -1}, // NULL (unused)
{-1, 1, 2, 3, 4, 5, 6}, // SPD
{-1, 1, 2, 3, 4, 5, 6}, // CRR
{-1, 2, 3, 4, 5, 5, 7}, // CRD
{-1, 2, 3, 4, 5, 7, 8}, // RES
{-1, 2, 3, 4, 5, 7, 8} // ACC
};
extern unsigned int calculate_ehp(unsigned int hp, unsigned short def){
// Sorry, but this is the formula, and I don't understand it either.
// Take it or leave it.
unsigned int ehp = ceil(
(((((float) def) * EHP_DEF_MULTIPLIER) + EHP_DEF_BASE) * ((float) hp)) /
EHP_HP_DIVIDER
);
return ehp;
}
extern unsigned short calculate_dmg(
unsigned short atk, unsigned short crr, unsigned short crd
){
float crr_capped = (float) crr;
if (crr_capped > CRR_CAP){
crr_capped = CRR_CAP;
}
unsigned short dmg = ceil(
((float)atk * ((PERCENT - crr_capped) / PERCENT)) + // Non-crit
((float)atk * (crr_capped / PERCENT) * ((float)(crd + 100) / PERCENT)) // Crit
);
return(dmg);
}
int main(int argc, char *argv[]){
// Parse the arguments to find the command (index 1)
// If no arguments, end here
if (argc < 2){
fprintf(stderr, "No command specified\n");
return(ERROR_INPUT_NO_COMMAND);
}
// Set the global database location
strcat(db_location, getenv(ENV_VAR_HOME));
strcat(db_location, DEFAULT_DB_PATH_FROM_HOME);
int result = SUCCESS;
// Version command
if (strcmp(argv[1], CMD_VERSION) == 0){
printf("%s\n", VERSION);
return(SUCCESS);
}
// Update command
else if (strcmp(argv[1], CMD_UPDATE) == 0){
return(
update(argc - ARGS_CUT_FOR_COMMANDS, argv + ARGS_CUT_FOR_COMMANDS)
);
}
// Optimize command.
else if (strcmp(argv[1], CMD_OPTIMIZE) == 0){
// Pass the rest of the arguments to the team command.
return(
optimize(argc - ARGS_CUT_FOR_COMMANDS, argv + ARGS_CUT_FOR_COMMANDS)
);
}
// Help command. Call and return
else if (strcmp(argv[1], CMD_HELP) == 0){
help();
return(SUCCESS);
}
// Team command.
else if (strcmp(argv[1], CMD_TEAM) == 0){
// Pass the rest of the arguments to the team command.
return(
team(argc - ARGS_CUT_FOR_COMMANDS, argv + ARGS_CUT_FOR_COMMANDS)
);
}
// Unit command.
else if (strcmp(argv[1], CMD_UNIT) == 0){
// Pass the rest of the arguments to the team command.
return(
unit(argc - ARGS_CUT_FOR_COMMANDS, argv + ARGS_CUT_FOR_COMMANDS)
);
}
// Player command.
else if (strcmp(argv[1], CMD_PLAYER) == 0){
return(player());
}
// GUI command.
else if (strcmp(argv[1], CMD_GUI) == 0){
return(gui());
}
// Any other command is an error
else{
fprintf(stderr, "Invalid command specified: %s\n", argv[1]);
return(ERROR_INPUT_INVALID_COMMAND);
}
return result;
}