summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDastgir <dastgirp@gmail.com>2018-07-26 10:08:21 +0530
committerDastgir <dastgirp@gmail.com>2018-09-02 11:48:08 +0530
commit63c2c3779bb0897bd61793fe9fe7cd8b65e4bfc0 (patch)
treeae9f35598a33e6c0f02f06b7a3184740b442daec
parent504ad2ca7d6ef4923093f74ac2afd5fc1bd39fd1 (diff)
downloadhercules-63c2c3779bb0897bd61793fe9fe7cd8b65e4bfc0.tar.gz
hercules-63c2c3779bb0897bd61793fe9fe7cd8b65e4bfc0.tar.bz2
hercules-63c2c3779bb0897bd61793fe9fe7cd8b65e4bfc0.tar.xz
hercules-63c2c3779bb0897bd61793fe9fe7cd8b65e4bfc0.zip
Extended db2sql plugin to allow generation of mob_skill_db sql files.
Fixes #2128
-rw-r--r--src/plugins/db2sql.c330
1 files changed, 329 insertions, 1 deletions
diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c
index 57e68432e..2ece501b2 100644
--- a/src/plugins/db2sql.c
+++ b/src/plugins/db2sql.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2013-2015 Hercules Dev Team
+ * Copyright (C) 2013-2018 Hercules Dev Team
*
* Hercules is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -70,6 +70,10 @@ bool mobdb2sql_torun = false;
int (*itemdb_readdb_libconfig_sub) (struct config_setting_t *it, int n, const char *source);
/// Backup of the original mob_db parser function pointer.
int (*mob_read_db_sub) (struct config_setting_t *it, int n, const char *source);
+bool (*mob_skill_db_libconfig_sub_skill) (struct config_setting_t *it, int n, int mob_id);
+
+//
+void do_mobskilldb2sql(void);
/**
* Normalizes and appends a string to the output buffer.
@@ -811,6 +815,330 @@ void do_mobdb2sql(void)
if (tosql.buf[i].p)
aFree(tosql.buf[i].p);
}
+
+ // Run mob_skill_db converter
+ do_mobskilldb2sql();
+}
+
+/**
+ * Converts Mob Skill State constant to string
+ */
+const char* mob_skill_state_tostring(enum MobSkillState mss)
+{
+ switch(mss) {
+ case MSS_ANY:
+ return "any";
+ case MSS_IDLE:
+ return "idle";
+ case MSS_WALK:
+ return "walk";
+ case MSS_LOOT:
+ return "loot";
+ case MSS_DEAD:
+ return "dead";
+ case MSS_BERSERK:
+ return "attack";
+ case MSS_ANGRY:
+ return "angry";
+ case MSS_RUSH:
+ return "chase";
+ case MSS_FOLLOW:
+ return "follow";
+ case MSS_ANYTARGET:
+ return "anytarget";
+ }
+
+ return "unknown";
+}
+
+/**
+ * Converts Mob Skill Target constant to string
+ */
+const char* mob_skill_target_tostring(int target)
+{
+ switch(target) {
+ case MST_TARGET:
+ return "target";
+ case MST_RANDOM:
+ return "randomtarget";
+ case MST_SELF:
+ return "self";
+ case MST_FRIEND:
+ return "friend";
+ case MST_MASTER:
+ return "master";
+ case MST_AROUND1:
+ return "around1";
+ case MST_AROUND2:
+ return "around2";
+ case MST_AROUND3:
+ return "around3";
+ //case MST_AROUND: // same value as MST_AROUND4
+ case MST_AROUND4:
+ return "around4";
+ case MST_AROUND5:
+ return "around5";
+ case MST_AROUND6:
+ return "around6";
+ case MST_AROUND7:
+ return "around7";
+ case MST_AROUND8:
+ return "around8";
+ }
+ return "unknown";
+}
+
+/**
+ * Converts Mob Skill Condition constant to string
+ */
+const char* mob_skill_condition_tostring(int condition)
+{
+ switch(condition) {
+ case MSC_ALWAYS:
+ return "always";
+ case MSC_MYHPLTMAXRATE:
+ return "myhpltmaxrate";
+ case MSC_MYHPINRATE:
+ return "myhpinrate";
+ case MSC_FRIENDHPLTMAXRATE:
+ return "friendhpltmaxrate";
+ case MSC_FRIENDHPINRATE:
+ return "friendhpinrate";
+ case MSC_MYSTATUSON:
+ return "mystatuson";
+ case MSC_MYSTATUSOFF:
+ return "mystatusoff";
+ case MSC_FRIENDSTATUSON:
+ return "friendstatuson";
+ case MSC_FRIENDSTATUSOFF:
+ return "friendstatusoff";
+ case MSC_ATTACKPCGT:
+ return "attackpcgt";
+ case MSC_ATTACKPCGE:
+ return "attackpcge";
+ case MSC_SLAVELT:
+ return "slavelt";
+ case MSC_SLAVELE:
+ return "slavele";
+ case MSC_CLOSEDATTACKED:
+ return "closedattacked";
+ case MSC_LONGRANGEATTACKED:
+ return "longrangeattacked";
+ case MSC_AFTERSKILL:
+ return "afterskill";
+ case MSC_SKILLUSED:
+ return "skillused";
+ case MSC_CASTTARGETED:
+ return "casttargeted";
+ case MSC_RUDEATTACKED:
+ return "rudeattacked";
+ case MSC_MASTERHPLTMAXRATE:
+ return "masterhpltmaxrate";
+ case MSC_MASTERATTACKED:
+ return "masterattacked";
+ case MSC_ALCHEMIST:
+ return "alchemist";
+ case MSC_SPAWN:
+ return "onspawn";
+ }
+ return "unknown";
+}
+
+/**
+ * Converts a Mob Skill DB entry to SQL.
+ *
+ * @see mob_skill_db_libconfig_sub_skill.
+ */
+bool mobskilldb2sql_sub(struct config_setting_t *it, int n, int mob_id)
+{
+ int i32 = 0, i;
+ StringBuf buf;
+ struct mob_db *md = mob->db(mob_id);
+ char valname[15];
+ const char *name = config_setting_name(it);
+
+ nullpo_retr(false, it);
+ Assert_retr(false, mob_id <= 0 || md != mob->dummy);
+
+ StrBuf->Init(&buf);
+
+ // MonsterID
+ StrBuf->Printf(&buf, "%d,", mob_id);
+
+ // Info
+ StrBuf->Printf(&buf, "'%s@%s',", md->name, name);
+
+ if (mob->lookup_const(it, "SkillState", &i32) && (i32 < MSS_ANY || i32 > MSS_ANYTARGET)) {
+ ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill state %d for skill '%s' in monster %d, defaulting to MSS_ANY.\n", i32, name, mob_id);
+ i32 = MSS_ANY;
+ }
+ // State
+ StrBuf->Printf(&buf, "'%s',", mob_skill_state_tostring(i32));
+
+ // SkillID
+ if (!(i32 = skill->name2id(name))) {
+ ShowWarning("mob_skill_db_libconfig_sub_skill: Non existant skill id %d in monster %d, skipping.\n", i32, mob_id);
+ return false;
+ }
+ StrBuf->Printf(&buf, "%d,", i32);
+
+ // SkillLv
+ if (!libconfig->setting_lookup_int(it, "SkillLevel", &i32) || i32 <= 0)
+ i32 = 1;
+ StrBuf->Printf(&buf, "%d,", i32);
+
+ // Rate
+ i32 = 0;
+ libconfig->setting_lookup_int(it, "Rate", &i32);
+ StrBuf->Printf(&buf, "%d,", i32);
+
+ // CastTime
+ i32 = 0;
+ libconfig->setting_lookup_int(it, "CastTime", &i32);
+ StrBuf->Printf(&buf, "%d,", i32);
+
+ // Delay
+ i32 = 0;
+ libconfig->setting_lookup_int(it, "Delay", &i32);
+ StrBuf->Printf(&buf, "%d,", i32);
+
+ // Cancelable
+ if (libconfig->setting_lookup_bool(it, "Cancelable", &i32)) {
+ StrBuf->Printf(&buf, "'%s',", ((i32 == 0) ? "no" : "yes"));
+ } else {
+ StrBuf->Printf(&buf, "'no',");
+ }
+
+ // Target
+ if (mob->lookup_const(it, "SkillTarget", &i32) && (i32 < MST_TARGET || i32 > MST_AROUND)) {
+ i32 = MST_TARGET;
+ }
+ StrBuf->Printf(&buf, "'%s',", mob_skill_target_tostring(i32));
+
+ // Condition
+ if (mob->lookup_const(it, "CastCondition", &i32) && (i32 < MSC_ALWAYS || i32 > MSC_SPAWN)) {
+ i32 = MSC_ALWAYS;
+ }
+ StrBuf->Printf(&buf, "'%s',", mob_skill_condition_tostring(i32));
+
+ // ConditionValue
+ i32 = 0;
+ if (mob->lookup_const(it, "ConditionData", &i32)) {
+ StrBuf->Printf(&buf, "'%d',", i32);
+ } else {
+ StrBuf->Printf(&buf, "NULL,");
+ }
+
+ // Val1-Val5
+ for (i = 0; i < 5; i++) {
+ sprintf(valname, "val%1d", i);
+ if (libconfig->setting_lookup_int(it, valname, &i32)) {
+ StrBuf->Printf(&buf, "%d,", i32);
+ } else {
+ StrBuf->Printf(&buf, "NULL,");
+ }
+ }
+
+ // Emotion
+ if (libconfig->setting_lookup_int(it, "Emotion", &i32)) {
+ StrBuf->Printf(&buf, "'%d',", i32);
+ } else {
+ StrBuf->Printf(&buf, "NULL,");
+ }
+
+ if (libconfig->setting_lookup_int(it, "ChatMsgID", &i32) && i32 > 0 && i32 <= MAX_MOB_CHAT) {
+ StrBuf->Printf(&buf, "'%d'", i32);
+ } else {
+ StrBuf->Printf(&buf, "NULL");
+ }
+
+ fprintf(tosql.fp, "REPLACE INTO `%s` VALUES (%s);\n", tosql.db_name, StrBuf->Value(&buf));
+
+ StrBuf->Destroy(&buf);
+
+ return true;
+
+}
+
+
+/**
+ * Prints a SQL table header for the current mob_skill_db table.
+ */
+void mobskilldb2sql_tableheader(void)
+{
+ db2sql_fileheader();
+
+ fprintf(tosql.fp,
+ "--\n"
+ "-- Table structure for table `%s`\n"
+ "--\n"
+ "\n"
+ "DROP TABLE IF EXISTS `%s`;\n"
+ "CREATE TABLE `%s` (\n"
+ " `MOB_ID` SMALLINT(6) NOT NULL,\n"
+ " `INFO` TEXT NOT NULL,\n"
+ " `STATE` TEXT NOT NULL,\n"
+ " `SKILL_ID` SMALLINT(6) NOT NULL,\n"
+ " `SKILL_LV` TINYINT(4) NOT NULL,\n"
+ " `RATE` SMALLINT(4) NOT NULL,\n"
+ " `CASTTIME` MEDIUMINT(9) NOT NULL,\n"
+ " `DELAY` INT(9) NOT NULL,\n"
+ " `CANCELABLE` TEXT NOT NULL,\n"
+ " `TARGET` TEXT NOT NULL,\n"
+ " `CONDITION` TEXT NOT NULL,\n"
+ " `CONDITION_VALUE` TEXT,\n"
+ " `VAL1` INT(11) DEFAULT NULL,\n"
+ " `VAL2` INT(11) DEFAULT NULL,\n"
+ " `VAL3` INT(11) DEFAULT NULL,\n"
+ " `VAL4` INT(11) DEFAULT NULL,\n"
+ " `VAL5` INT(11) DEFAULT NULL,\n"
+ " `EMOTION` TEXT,\n"
+ " `CHAT` TEXT\n"
+ ") ENGINE=MyISAM;\n"
+ "\n", tosql.db_name, tosql.db_name, tosql.db_name);
+}
+
+/**
+ * Mob Skill DB Conversion
+ */
+void do_mobskilldb2sql(void)
+{
+ int i;
+ struct convert_db_files {
+ const char *name;
+ const char *source;
+ const char *destination;
+ } files[] = {
+ {"mob_skill_db", DBPATH"mob_skill_db.conf", "sql-files/mob_skill_db" DBSUFFIX ".sql"},
+ {"mob_skill_db2", "mob_skill_db2.conf", "sql-files/mob_skill_db2.sql"},
+ };
+
+ /* link */
+ mob_skill_db_libconfig_sub_skill = mob->skill_db_libconfig_sub_skill;
+ mob->skill_db_libconfig_sub_skill = mobskilldb2sql_sub;
+
+ memset(&tosql.buf, 0, sizeof(tosql.buf));
+ for (i = 0; i < ARRAYLENGTH(files); i++) {
+ if ((tosql.fp = fopen(files[i].destination, "wt+")) == NULL) {
+ ShowError("do_mobskilldb2sql: File not found \"%s\".\n", files[i].destination);
+ return;
+ }
+
+ tosql.db_name = files[i].name;
+ mobskilldb2sql_tableheader();
+
+ mob->skill_db_libconfig(files[i].source, false);
+
+ fclose(tosql.fp);
+ }
+
+ /* unlink */
+ mob->skill_db_libconfig_sub_skill = mob_skill_db_libconfig_sub_skill;
+
+ for (i = 0; i < ARRAYLENGTH(tosql.buf); i++) {
+ if (tosql.buf[i].p)
+ aFree(tosql.buf[i].p);
+ }
}
/**