Converts the mob database to YAML (#5435)

* Combines mob_race2 and mob_drop databases into one.
* General cleanups and optimizations.
* Includes CSV2YAML conversion tool.
Thanks to @vstumpf, @lukasrmattos, and @Lemongrass3110!
This commit is contained in:
Aleos
2021-02-16 17:09:06 -05:00
committed by GitHub
parent 6ed0359522
commit 7992e0891b
58 changed files with 136726 additions and 12811 deletions

View File

@@ -31,6 +31,24 @@
#include "../common/winapi.hpp"
#endif
// Only for constants - do not use functions of it or linking will fail
#include "../map/achievement.hpp"
#include "../map/battle.hpp"
#include "../map/battleground.hpp"
#include "../map/channel.hpp"
#include "../map/chat.hpp"
#include "../map/date.hpp"
#include "../map/instance.hpp"
#include "../map/mercenary.hpp"
#include "../map/mob.hpp"
#include "../map/npc.hpp"
#include "../map/pc.hpp"
#include "../map/pet.hpp"
#include "../map/quest.hpp"
#include "../map/script.hpp"
#include "../map/skill.hpp"
#include "../map/storage.hpp"
using namespace rathena;
#ifndef WIN32
@@ -47,8 +65,12 @@ int getch( void ){
}
#endif
// Constants for conversion
std::unordered_map<const char *, int64> constants;
// Forward declaration of conversion functions
static bool item_db_yaml2sql(const std::string &file, const std::string &table);
static bool mob_db_yaml2sql(const std::string &file, const std::string &table);
bool fileExists( const std::string& path );
bool askConfirmation( const char* fmt, ... );
@@ -56,6 +78,38 @@ bool askConfirmation( const char* fmt, ... );
YAML::Node inNode;
std::ofstream out;
// Implement the function instead of including the original version by linking
void script_set_constant_(const char *name, int64 value, const char *constant_name, bool isparameter, bool deprecated) {
constants[name] = value;
}
const char *constant_lookup(int32 value, const char *prefix) {
if (prefix == nullptr)
return nullptr;
for (auto const &pair : constants) {
// Same prefix group and same value
if (strncasecmp(pair.first, prefix, strlen(prefix)) == 0 && pair.second == value) {
return pair.first;
}
}
return nullptr;
}
int64 constant_lookup_int(const char *constant) {
if (constant == nullptr)
return -100;
for (auto const &pair : constants) {
if (strlen(pair.first) == strlen(constant) && strncasecmp(pair.first, constant, strlen(constant)) == 0) {
return pair.second;
}
}
return -100;
}
void copyFileIfExists( std::ofstream& file,const std::string& name ){
std::string path = "doc/yaml/sql/" + name + ".sql";
@@ -136,9 +190,13 @@ int do_init( int argc, char** argv ){
#ifdef RENEWAL
const std::string item_table_name = "item_db_re";
const std::string item_import_table_name = "item_db2_re";
const std::string mob_table_name = "mob_db_re";
const std::string mob_import_table_name = "mob_db2_re";
#else
const std::string item_table_name = "item_db";
const std::string item_import_table_name = "item_db2";
const std::string mob_table_name = "mob_db";
const std::string mob_import_table_name = "mob_db2";
#endif
std::vector<std::string> item_table_suffixes = {
"usable",
@@ -146,6 +204,9 @@ int do_init( int argc, char** argv ){
"etc"
};
// Load constants
#include "../map/script_constants.hpp"
for( const std::string& suffix : item_table_suffixes ){
if (!process("ITEM_DB", 1, { path_db_mode }, "item_db_" + suffix, item_table_name + "_" + suffix, item_table_name, [](const std::string& path, const std::string& name_ext, const std::string& table) -> bool {
return item_db_yaml2sql(path + name_ext, table);
@@ -160,6 +221,18 @@ int do_init( int argc, char** argv ){
return 0;
}
if (!process("MOB_DB", 1, { path_db_mode }, "mob_db", mob_table_name, mob_table_name, [](const std::string &path, const std::string &name_ext, const std::string &table) -> bool {
return mob_db_yaml2sql(path + name_ext, table);
})) {
return 0;
}
if (!process("MOB_DB", 1, { path_db_import }, "mob_db", mob_import_table_name, mob_import_table_name, [](const std::string &path, const std::string &name_ext, const std::string &table) -> bool {
return mob_db_yaml2sql(path + name_ext, table);
})) {
return 0;
}
// TODO: add implementations ;-)
return 0;
@@ -638,3 +711,200 @@ static bool item_db_yaml2sql(const std::string &file, const std::string &table)
return true;
}
// Copied and adjusted from mob.cpp
static bool mob_db_yaml2sql(const std::string &file, const std::string &table) {
size_t entries = 0;
for (const YAML::Node &input : inNode["Body"]) {
std::string column = "", value = "";
if (appendEntry(input["Id"], value))
column.append("`id`,");
if (appendEntry(input["AegisName"], value, true))
column.append("`name_aegis`,");
if (appendEntry(input["Name"], value, true))
column.append("`name_english`,");
if (appendEntry(input["Name"], value, true))
column.append("`name_japanese`,");
if (appendEntry(input["Level"], value))
column.append("`level`,");
if (appendEntry(input["Hp"], value))
column.append("`hp`,");
if (appendEntry(input["Sp"], value))
column.append("`sp`,");
if (appendEntry(input["BaseExp"], value))
column.append("`base_exp`,");
if (appendEntry(input["JobExp"], value))
column.append("`job_exp`,");
if (appendEntry(input["MvpExp"], value))
column.append("`mvp_exp`,");
if (appendEntry(input["Attack"], value))
column.append("`attack`,");
if (appendEntry(input["Attack2"], value))
column.append("`attack2`,");
if (appendEntry(input["Defense"], value))
column.append("`defense`,");
if (appendEntry(input["MagicDefense"], value))
column.append("`magic_defense`,");
if (appendEntry(input["Str"], value))
column.append("`str`,");
if (appendEntry(input["Agi"], value))
column.append("`agi`,");
if (appendEntry(input["Vit"], value))
column.append("`vit`,");
if (appendEntry(input["Int"], value))
column.append("`int`,");
if (appendEntry(input["Dex"], value))
column.append("`dex`,");
if (appendEntry(input["Luk"], value))
column.append("`luk`,");
if (appendEntry(input["AttackRange"], value))
column.append("`attack_range`,");
if (appendEntry(input["SkillRange"], value))
column.append("`skill_range`,");
if (appendEntry(input["ChaseRange"], value))
column.append("`chase_range`,");
if (appendEntry(input["Size"], value, true))
column.append("`size`,");
if (appendEntry(input["Race"], value, true))
column.append("`race`,");
const YAML::Node &racegroups = input["RaceGroups"];
if (racegroups) {
for (uint16 i = 1; i < RC2_MAX; i++) {
std::string constant = constant_lookup(i, "RC2_");
constant.erase(0, 4);
if (appendEntry(racegroups[name2Upper(constant)], value)) {
std::transform(constant.begin(), constant.end(), constant.begin(), ::tolower);
column.append("`racegroup_" + constant + "`,");
}
}
}
if (appendEntry(input["Element"], value, true))
column.append("`element`,");
if (appendEntry(input["ElementLevel"], value))
column.append("`element_level`,");
if (appendEntry(input["WalkSpeed"], value))
column.append("`walk_speed`,");
if (appendEntry(input["AttackDelay"], value))
column.append("`attack_delay`,");
if (appendEntry(input["AttackMotion"], value))
column.append("`attack_motion`,");
if (appendEntry(input["DamageMotion"], value))
column.append("`damage_motion`,");
if (appendEntry(input["Ai"], value, true))
column.append("`ai`,");
if (appendEntry(input["Class"], value, true))
column.append("`class`,");
const YAML::Node &modes = input["Modes"];
if (modes) {
if (appendEntry(modes["CanMove"], value))
column.append("`mode_canmove`,");
if (appendEntry(modes["Looter"], value))
column.append("`mode_looter`,");
if (appendEntry(modes["Aggressive"], value))
column.append("`mode_aggressive`,");
if (appendEntry(modes["Assist"], value))
column.append("`mode_assist`,");
if (appendEntry(modes["CastSensorIdle"], value))
column.append("`mode_castsensoridle`,");
if (appendEntry(modes["NoRandomWalk"], value))
column.append("`mode_norandomwalk`,");
if (appendEntry(modes["NoCast"], value))
column.append("`mode_nocast`,");
if (appendEntry(modes["CanAttack"], value))
column.append("`mode_canattack`,");
if (appendEntry(modes["CastSensorChase"], value))
column.append("`mode_castsensorchase`,");
if (appendEntry(modes["ChangeChase"], value))
column.append("`mode_changechase`,");
if (appendEntry(modes["Angry"], value))
column.append("`mode_angry`,");
if (appendEntry(modes["ChangeTargetMelee"], value))
column.append("`mode_changetargetmelee`,");
if (appendEntry(modes["ChangeTargetChase"], value))
column.append("`mode_changetargetchase`,");
if (appendEntry(modes["TargetWeak"], value))
column.append("`mode_targetweak`,");
if (appendEntry(modes["RandomTarget"], value))
column.append("`mode_randomtarget`,");
if (appendEntry(modes["IgnoreMelee"], value))
column.append("`mode_ignoremelee`,");
if (appendEntry(modes["IgnoreMagic"], value))
column.append("`mode_ignoremagic`,");
if (appendEntry(modes["IgnoreRanged"], value))
column.append("`mode_ignoreranged`,");
if (appendEntry(modes["Mvp"], value))
column.append("`mode_mvp`,");
if (appendEntry(modes["IgnoreMisc"], value))
column.append("`mode_ignoremisc`,");
if (appendEntry(modes["KnockBackImmune"], value))
column.append("`mode_knockbackimmune`,");
if (appendEntry(modes["TeleportBlock"], value))
column.append("`mode_teleportblock`,");
if (appendEntry(modes["FixedItemDrop"], value))
column.append("`mode_fixeditemdrop`,");
if (appendEntry(modes["Detector"], value))
column.append("`mode_detector`,");
if (appendEntry(modes["StatusImmune"], value))
column.append("`mode_statusimmune`,");
if (appendEntry(modes["SkillImmune"], value))
column.append("`mode_skillimmune`,");
}
for (uint16 i = 0; i < MAX_MVP_DROP; i++) {
if (!input["MvpDrops"].IsDefined())
continue;
const YAML::Node &mvpdrops = input["MvpDrops"][i];
if (mvpdrops) {
if (appendEntry(mvpdrops["Item"], value, true))
column.append("`mvpdrop" + std::to_string(i + 1) + "_item`,");
if (appendEntry(mvpdrops["Rate"], value))
column.append("`mvpdrop" + std::to_string(i + 1) + "_rate`,");
if (appendEntry(mvpdrops["RandomOptionGroup"], value, true))
column.append("`mvpdrop" + std::to_string(i + 1) + "_option`,");
if (appendEntry(mvpdrops["Index"], value))
column.append("`mvpdrop" + std::to_string(i + 1) + "_index`,");
}
}
for (uint16 i = 0; i < MAX_MOB_DROP; i++) {
if (!input["Drops"].IsDefined())
continue;
const YAML::Node &drops = input["Drops"][i];
if (drops) {
if (appendEntry(drops["Item"], value, true))
column.append("`drop" + std::to_string(i + 1) + "_item`,");
if (appendEntry(drops["Rate"], value))
column.append("`drop" + std::to_string(i + 1) + "_rate`,");
if (appendEntry(drops["StealProtected"], value))
column.append("`drop" + std::to_string(i + 1) + "_nosteal`,");
if (appendEntry(drops["RandomOptionGroup"], value, true))
column.append("`drop" + std::to_string(i + 1) + "_option`,");
if (appendEntry(drops["Index"], value))
column.append("`drop" + std::to_string(i + 1) + "_index`,");
}
}
column.pop_back(); // Remove last ','
value.pop_back(); // Remove last ','
out << "REPLACE INTO `" + table + "` (" + column + ") VALUES (" + value + ");\n";
entries++;
}
ShowStatus("Done converting '" CL_WHITE "%d" CL_RESET "' mobs in '" CL_WHITE "%s" CL_RESET "'.\n", entries, file.c_str());
return true;
}