From be90f6c69b6ac54ee83878f603cb9bf733d29d04 Mon Sep 17 00:00:00 2001
From: Asheraf <acheraf1998@gmail.com>
Date: Tue, 17 Apr 2018 02:43:16 +0100
Subject: Convert mob_skill_db into libconf format

---
 src/map/mob.c    | 385 +++++++++++++++++++++++++------------------------------
 src/map/mob.h    |   4 +-
 src/map/script.c |  54 ++++++++
 3 files changed, 234 insertions(+), 209 deletions(-)

(limited to 'src')

diff --git a/src/map/mob.c b/src/map/mob.c
index f2927738e..070c0ea63 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -4816,292 +4816,259 @@ void mob_readchatdb(void) {
 /*==========================================
  * processes one mob_skill_db entry
  *------------------------------------------*/
-bool mob_parse_row_mobskilldb(char** str, int columns, int current)
+bool mob_skill_db_libconfig(const char *filename, bool ignore_missing)
 {
-	static const struct {
-		char str[32];
-		enum MobSkillState id;
-	} state[] = {
-		{ "any",       MSS_ANY       }, //All states except Dead
-		{ "idle",      MSS_IDLE      },
-		{ "walk",      MSS_WALK      },
-		{ "loot",      MSS_LOOT      },
-		{ "dead",      MSS_DEAD      },
-		{ "attack",    MSS_BERSERK   }, //Retaliating attack
-		{ "angry",     MSS_ANGRY     }, //Preemptive attack (aggressive mobs)
-		{ "chase",     MSS_RUSH      }, //Chase escaping target
-		{ "follow",    MSS_FOLLOW    }, //Preemptive chase (aggressive mobs)
-		{ "anytarget", MSS_ANYTARGET }, //Berserk+Angry+Rush+Follow
-	};
-	static const struct {
-		char str[32];
-		int id;
-	} cond1[] = {
-		{ "always",            MSC_ALWAYS            },
-		{ "myhpltmaxrate",     MSC_MYHPLTMAXRATE     },
-		{ "myhpinrate",        MSC_MYHPINRATE        },
-		{ "friendhpltmaxrate", MSC_FRIENDHPLTMAXRATE },
-		{ "friendhpinrate",    MSC_FRIENDHPINRATE    },
-		{ "mystatuson",        MSC_MYSTATUSON        },
-		{ "mystatusoff",       MSC_MYSTATUSOFF       },
-		{ "friendstatuson",    MSC_FRIENDSTATUSON    },
-		{ "friendstatusoff",   MSC_FRIENDSTATUSOFF   },
-		{ "attackpcgt",        MSC_ATTACKPCGT        },
-		{ "attackpcge",        MSC_ATTACKPCGE        },
-		{ "slavelt",           MSC_SLAVELT           },
-		{ "slavele",           MSC_SLAVELE           },
-		{ "closedattacked",    MSC_CLOSEDATTACKED    },
-		{ "longrangeattacked", MSC_LONGRANGEATTACKED },
-		{ "skillused",         MSC_SKILLUSED         },
-		{ "afterskill",        MSC_AFTERSKILL        },
-		{ "casttargeted",      MSC_CASTTARGETED      },
-		{ "rudeattacked",      MSC_RUDEATTACKED      },
-		{ "masterhpltmaxrate", MSC_MASTERHPLTMAXRATE },
-		{ "masterattacked",    MSC_MASTERATTACKED    },
-		{ "alchemist",         MSC_ALCHEMIST         },
-		{ "onspawn",           MSC_SPAWN             },
-	}, cond2[] ={
-		{ "anybad",    -1           },
-		{ "stone",     SC_STONE     },
-		{ "freeze",    SC_FREEZE    },
-		{ "stun",      SC_STUN      },
-		{ "sleep",     SC_SLEEP     },
-		{ "poison",    SC_POISON    },
-		{ "curse",     SC_CURSE     },
-		{ "silence",   SC_SILENCE   },
-		{ "confusion", SC_CONFUSION },
-		{ "blind",     SC_BLIND     },
-		{ "hiding",    SC_HIDING    },
-		{ "sight",     SC_SIGHT     },
-	}, target[] = {
-		{ "target",       MST_TARGET  },
-		{ "randomtarget", MST_RANDOM  },
-		{ "self",         MST_SELF    },
-		{ "friend",       MST_FRIEND  },
-		{ "master",       MST_MASTER  },
-		{ "around5",      MST_AROUND5 },
-		{ "around6",      MST_AROUND6 },
-		{ "around7",      MST_AROUND7 },
-		{ "around8",      MST_AROUND8 },
-		{ "around1",      MST_AROUND1 },
-		{ "around2",      MST_AROUND2 },
-		{ "around3",      MST_AROUND3 },
-		{ "around4",      MST_AROUND4 },
-		{ "around",       MST_AROUND  },
-	};
-	static int last_mob_id = 0;  // ensures that only one error message per mob id is printed
+	struct config_t mob_skill_conf;
+	struct config_setting_t *it = NULL, *its = NULL, *mob_skill = NULL;
+	char filepath[256];
+	int i = 0;
 
-	struct mob_skill *ms, gms;
-	int mob_id;
-	int i =0, j, tmp;
-	int sidx = 0;
+	nullpo_retr(false, filename);
 
-	nullpo_retr(false, str);
-	mob_id = atoi(str[0]);
+	safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, filename);
 
-	if (mob_id > 0 && mob->db(mob_id) == mob->dummy)
-	{
-		if (mob_id != last_mob_id) {
-			ShowError("mob_parse_row_mobskilldb: Non existant Mob id %d\n", mob_id);
-			last_mob_id = mob_id;
+	if (!exists(filepath)) {
+		if (!ignore_missing) {
+			ShowError("mob_skill_db_libconfig: can't find file %s\n", filepath);
 		}
+		return 0;
+	}
+
+	if (!libconfig->load_file(&mob_skill_conf, filepath))
 		return false;
+
+	its = libconfig->lookup(&mob_skill_conf, "mob_skill_db");
+
+	if (its != NULL && (mob_skill = libconfig->setting_get_elem(its, 0)) != NULL) {
+		while ((it = libconfig->setting_get_elem(mob_skill, i++))) {
+			mob->skill_db_libconfig_sub(it, i);
+		}
 	}
-	if( strcmp(str[1],"clear")==0 ){
-		if (mob_id < 0)
+
+	libconfig->destroy(&mob_skill_conf);
+	ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, filepath);
+	return true;
+}
+
+bool mob_skill_db_libconfig_sub(struct config_setting_t *it, int n)
+{
+	int i = 0;
+	int mob_id;
+	struct config_setting_t *its;
+	const char *name = config_setting_name(it);
+
+	nullpo_retr(false, it);
+
+	if (!*name) {
+		ShowWarning("mob_skill_db_libconfig_sub: Invalid value for monster name, entry #%d, skipping.\n", n);
+		return false;
+	}
+	if (!script->get_constant(name, &mob_id)) {
+		ShowWarning("mob_skill_db_libconfig_sub: Invalid monster '%s', entry #%d, skipping.\n", name, n);
+		return false;
+	}
+	if (mob_id > 0 && mob->db(mob_id) == mob->dummy) {
+		ShowWarning("mob_skill_db_libconfig_sub: Non existant monster id %d, skipping.\n", mob_id);
+		return false;
+	}
+
+	while ((its = libconfig->setting_get_elem(it, i++))) {
+		mob->skill_db_libconfig_sub_skill(its, i, mob_id);
+	}
+	return true;
+}
+
+bool mob_skill_db_libconfig_sub_skill(struct config_setting_t *it, int n, int mob_id)
+{
+	int i, j;
+	int i32;
+	int skill_id = 0;
+	int skill_idx = 0;
+	bool clearskills = false;
+	char valname[5];
+	const char *name = config_setting_name(it);
+	struct mob_skill *ms, gms;
+
+	nullpo_retr(false, it);
+	Assert_retr(false, mob_id <= 0 || mob->db(mob_id) != mob->dummy);
+
+	if (!(skill_id = skill->name2id(name))) {
+		ShowWarning("mob_skill_db_libconfig_sub_skill: Non existant skill id %d in monster %d, skipping.\n", skill_id, mob_id);
+		return false;
+	}
+
+	// If ClearSkills flag is enabled clear all the previous skills.
+	if (libconfig->setting_lookup_bool_real(it, "ClearSkills", &clearskills) && clearskills) {
+		if (mob_id < 0) // Clearing skills globaly is not supported
 			return false;
-		memset(mob->db_data[mob_id]->skill,0,sizeof(struct mob_skill) * MAX_MOBSKILL);
-		mob->db_data[mob_id]->maxskill=0;
+		memset(mob->db_data[mob_id]->skill, 0, sizeof(struct mob_skill) * MAX_MOBSKILL);
+		mob->db_data[mob_id]->maxskill = 0;
 		return true;
 	}
 
 	if (mob_id < 0) {
-		//Prepare global skill. [Skotlex]
+		// Prepare global skill. [Skotlex]
 		memset(&gms, 0, sizeof (struct mob_skill));
 		ms = &gms;
 	} else {
-		ARR_FIND( 0, MAX_MOBSKILL, i, (ms = &mob->db_data[mob_id]->skill[i])->skill_id == 0 );
-		if( i == MAX_MOBSKILL )
-		{
-			if (mob_id != last_mob_id) {
-				ShowError("mob_parse_row_mobskilldb: Too many skills for monster %d[%s]\n", mob_id, mob->db_data[mob_id]->sprite);
-				last_mob_id = mob_id;
-			}
+		ARR_FIND(0, MAX_MOBSKILL, i, (ms = &mob->db_data[mob_id]->skill[i])->skill_id == 0);
+		if (i == MAX_MOBSKILL) {
+			ShowError("mob_skill_db_libconfig_sub_skill: Too many skills for monster %d\n", mob_id);
 			return false;
 		}
 	}
+	ms->skill_id = skill_id;
 
-	//State
-	ARR_FIND( 0, ARRAYLENGTH(state), j, strcmp(str[2],state[j].str) == 0 );
-	if( j < ARRAYLENGTH(state) )
-		ms->state = state[j].id;
-	else {
-		ShowWarning("mob_parse_row_mobskilldb: Unrecognized state %s\n", str[2]);
-		ms->state = MSS_ANY;
-	}
-
-	//Skill ID
-	j=atoi(str[3]);
-	if ( !(sidx = skill->get_index(j) ) ) {
-		if (mob_id < 0)
-			ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for all mobs\n", j);
-		else
-			ShowError("mob_parse_row_mobskilldb: Invalid Skill ID (%d) for mob %d (%s)\n", j, mob_id, mob->db_data[mob_id]->sprite);
-		return false;
+	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 id %d in monster %d, defaulting to MSS_ANY.\n", i32, skill_id, mob_id);
+		i32 = MSS_ANY;
 	}
-	ms->skill_id=j;
+	ms->state = i32;
 
-	//Skill lvl
-	j= atoi(str[4])<=0 ? 1 : atoi(str[4]);
-	ms->skill_lv= j>battle_config.mob_max_skilllvl ? battle_config.mob_max_skilllvl : j; //we strip max skill level
+	if (!libconfig->setting_lookup_int(it, "SkillLevel", &i32) || i32 <= 0)
+		i32 = 1;
+	ms->skill_lv = i32 > battle_config.mob_max_skilllvl ? battle_config.mob_max_skilllvl : i32; //we strip max skill level
 
 	//Apply battle_config modifiers to rate (permillage) and delay [Skotlex]
-	tmp = atoi(str[5]);
+	if (libconfig->setting_lookup_int(it, "Rate", &i32))
+		ms->permillage = i32;
+
 	if (battle_config.mob_skill_rate != 100)
-		tmp = tmp*battle_config.mob_skill_rate/100;
-	if (tmp > 10000)
-		ms->permillage= 10000;
-	else if (!tmp && battle_config.mob_skill_rate)
-		ms->permillage= 1;
-	else
-		ms->permillage= tmp;
-	ms->casttime=atoi(str[6]);
-	ms->delay=atoi(str[7]);
+		ms->permillage = ms->permillage * battle_config.mob_skill_rate / 100;
+	if (ms->permillage > 10000)
+		ms->permillage = 10000;
+	else if (ms->permillage == 0 && battle_config.mob_skill_rate)
+		ms->permillage = 1;
+
+	if (libconfig->setting_lookup_int(it, "CastTime", &i32) && i32 > 0)
+		ms->casttime = i32;
+
+	if (libconfig->setting_lookup_int(it, "Delay", &i32))
+		ms->delay = i32;
 	if (battle_config.mob_skill_delay != 100)
-		ms->delay = ms->delay*battle_config.mob_skill_delay/100;
+		ms->delay = ms->delay * battle_config.mob_skill_delay / 100;
 	if (ms->delay < 0 || ms->delay > MOB_MAX_DELAY) //time overflow?
 		ms->delay = MOB_MAX_DELAY;
-	ms->cancel=atoi(str[8]);
-	if( strcmp(str[8],"yes")==0 ) ms->cancel=1;
-
-	//Target
-	ARR_FIND( 0, ARRAYLENGTH(target), j, strcmp(str[9],target[j].str) == 0 );
-	if( j < ARRAYLENGTH(target) )
-		ms->target = target[j].id;
-	else {
-		ShowWarning("mob_parse_row_mobskilldb: Unrecognized target %s for %d\n", str[9], mob_id);
+
+	if (libconfig->setting_lookup_bool(it, "Cancelable", &i32))
+		ms->cancel = (i32 == 0) ? 0 : 1;
+
+	if (mob->lookup_const(it, "SkillTarget", &i32) && (i32 < MST_TARGET || i32 > MST_AROUND)) {
+		ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill target %d for skill id %d in monster %d, defaulting to MST_TARGET.\n", i32, skill_id, mob_id);
 		ms->target = MST_TARGET;
 	}
+	ms->target = i32;
 
 	//Check that the target condition is right for the skill type. [Skotlex]
-	if ( skill->get_casttype2(sidx) == CAST_GROUND) {//Ground skill.
+	skill_idx = skill->get_index(skill_id);
+	if (skill->get_casttype2(skill_idx) == CAST_GROUND) {//Ground skill.
 		if (ms->target > MST_AROUND) {
-			ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target for ground skill %d (%s) for %s.\n",
-				ms->skill_id, skill->dbs->db[sidx].name,
-				mob_id < 0?"all mobs":mob->db_data[mob_id]->sprite);
+			ShowWarning("mob_skill_db_libconfig_sub_skill: Wrong mob skill target for ground skill %d (%s) for %s.\n",
+				ms->skill_id, skill->dbs->db[skill_idx].name,
+				mob_id < 0 ? "all mobs" : mob->db_data[mob_id]->sprite);
 			ms->target = MST_TARGET;
 		}
 	} else if (ms->target > MST_MASTER) {
-		ShowWarning("mob_parse_row_mobskilldb: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s.\n",
-			ms->skill_id, skill->dbs->db[sidx].name,
-			mob_id < 0?"all mobs":mob->db_data[mob_id]->sprite);
+		ShowWarning("mob_skill_db_libconfig_sub_skill: Wrong mob skill target 'around' for non-ground skill %d (%s) for %s.\n",
+			ms->skill_id, skill->dbs->db[skill_idx].name,
+			mob_id < 0 ? "all mobs" : mob->db_data[mob_id]->sprite);
 		ms->target = MST_TARGET;
 	}
 
-	//Cond1
-	ARR_FIND( 0, ARRAYLENGTH(cond1), j, strcmp(str[10],cond1[j].str) == 0 );
-	if( j < ARRAYLENGTH(cond1) )
-		ms->cond1 = cond1[j].id;
-	else {
-		ShowWarning("mob_parse_row_mobskilldb: Unrecognized condition 1 %s for %d\n", str[10], mob_id);
-		ms->cond1 = -1;
+	if (mob->lookup_const(it, "CastCondition", &i32) && (i32 < MSC_ALWAYS || i32 > MSC_SPAWN)) {
+		ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid skill condition %d for skill id %d in monster %d, defaulting to MSC_ALWAYS.\n", i32, skill_id, mob_id);
+		ms->cond1 = MSC_ALWAYS;
 	}
+	ms->cond1 = i32;
 
-	//Cond2
-	// numeric value
-	ms->cond2 = atoi(str[11]);
-	// or special constant
-	ARR_FIND( 0, ARRAYLENGTH(cond2), j, strcmp(str[11],cond2[j].str) == 0 );
-	if( j < ARRAYLENGTH(cond2) )
-		ms->cond2 = cond2[j].id;
+	if (mob->lookup_const(it, "ConditionData", &i32))
+		ms->cond2 = i32;
 
-	ms->val[0]=(int)strtol(str[12],NULL,0);
-	ms->val[1]=(int)strtol(str[13],NULL,0);
-	ms->val[2]=(int)strtol(str[14],NULL,0);
-	ms->val[3]=(int)strtol(str[15],NULL,0);
-	ms->val[4]=(int)strtol(str[16],NULL,0);
+	for (i = 0; i < 5; i++) {
+		sprintf(valname, "val%1d", i);
+		if (libconfig->setting_lookup_int(it, valname, &i32))
+			ms->val[i] = i32;
+	}
 
 	if (ms->skill_id == NPC_EMOTION) {
 		ms->val[1] &= MD_MASK;
 		ms->val[2] &= MD_MASK;
 		ms->val[3] &= MD_MASK;
+
+		if (mob_id > 0 && (uint32)ms->val[1] == mob->db(mob_id)->status.mode) {
+			ms->val[1] = MD_NONE;
+			ms->val[4] = 1; //request to return mode to normal.
+		}
 	}
-	if (ms->skill_id == NPC_EMOTION && mob_id > 0
-	 && (uint32)ms->val[1] == mob->db(mob_id)->status.mode) {
-		ms->val[1] = MD_NONE;
-		ms->val[4] = 1; //request to return mode to normal.
-	}
-	if (ms->skill_id == NPC_EMOTION_ON && mob_id>0 && ms->val[1] != MD_NONE) {
+
+	if (ms->skill_id == NPC_EMOTION_ON && mob_id > 0 && ms->val[1] != MD_NONE) {
 		//Adds a mode to the mob.
 		//Remove aggressive mode when the new mob type is passive.
-		if (!(ms->val[1]&MD_AGGRESSIVE))
+		if (!(ms->val[1] & MD_AGGRESSIVE))
 			ms->val[3] |= MD_AGGRESSIVE;
 		ms->val[2] |= (uint32)ms->val[1]; //Add the new mode.
 		ms->val[1] = MD_NONE; //Do not "set" it.
 	}
 
-	if(*str[17])
-		ms->emotion=atoi(str[17]);
+	if (libconfig->setting_lookup_int(it, "Emotion", &i32))
+		ms->emotion = i32;
 	else
-		ms->emotion=-1;
+		ms->emotion = -1;
 
-	if(str[18]!=NULL && mob->chat_db[atoi(str[18])]!=NULL)
-		ms->msg_id=atoi(str[18]);
-	else
-		ms->msg_id=0;
+	if (libconfig->setting_lookup_int(it, "ChatMsgID", &i32) && i32 > 0 && i32 <= MAX_MOB_CHAT) {
+		if (mob->chat_db[i32] == NULL) {
+			ShowWarning("mob_skill_db_libconfig_sub_skill: Invalid msg id %d for skill id %d in monster %d, ignoring.\n", i32, skill_id, mob_id);
+		} else {
+			ms->msg_id = i32;
+		}
+	}
 
 	if (mob_id < 0) {
-		//Set this skill to ALL mobs. [Skotlex]
+		// Set this skill to ALL mobs. [Skotlex]
 		mob_id *= -1;
-		for (i = 1; i < MAX_MOB_DB; i++)
-		{
+		for (i = 1; i < MAX_MOB_DB; i++) {
 			if (mob->db_data[i] == NULL)
 				continue;
-			if (mob->db_data[i]->status.mode&MD_BOSS)
-			{
-				if (!(mob_id&2)) //Skill not for bosses
+			if (mob->db_data[i]->status.mode & MD_BOSS) {
+				if (!(mob_id & 2)) //Skill not for bosses
 					continue;
-			} else
-				if (!(mob_id&1)) //Skill not for normal enemies.
+			} else {
+				if (!(mob_id & 1)) //Skill not for normal enemies.
 					continue;
-
-			ARR_FIND( 0, MAX_MOBSKILL, j, mob->db_data[i]->skill[j].skill_id == 0 );
-			if(j==MAX_MOBSKILL)
+			}
+			ARR_FIND(0, MAX_MOBSKILL, j, mob->db_data[i]->skill[j].skill_id == 0);
+			if (j == MAX_MOBSKILL)
 				continue;
 
-			memcpy (&mob->db_data[i]->skill[j], ms, sizeof(struct mob_skill));
-			mob->db_data[i]->maxskill=j+1;
+			memcpy(&mob->db_data[i]->skill[j], ms, sizeof(struct mob_skill));
+			mob->db_data[i]->maxskill = j + 1;
 		}
-	} else //Skill set on a single mob.
-		mob->db_data[mob_id]->maxskill=i+1;
+	} else { //Skill set on a single mob.
+		mob->db_data[mob_id]->maxskill = i + 1;
+	}
 
 	return true;
 }
 
+
 /*==========================================
  * mob_skill_db.txt reading
  *------------------------------------------*/
 void mob_readskilldb(void) {
-	const char* filename[] = {
-		DBPATH"mob_skill_db.txt",
-		"mob_skill_db2.txt" };
-	int fi;
 
-	if( battle_config.mob_skill_rate == 0 ) {
+	const char *filename[] = {
+		DBPATH"mob_skill_db.conf",
+		"mob_skill_db2.conf"
+	};
+	int i;
+
+	if (battle_config.mob_skill_rate == 0) {
 		ShowStatus("Mob skill use disabled. Not reading mob skills.\n");
 		return;
 	}
 
-	for( fi = 0; fi < ARRAYLENGTH(filename); ++fi ) {
-		if(fi > 0) {
-			char filepath[256];
-			safesnprintf(filepath, 256, "%s/%s", map->db_path, filename[fi]);
-			if(!exists(filepath)) {
-				continue;
-			}
-		}
-
-		sv->readdb(map->db_path, filename[fi], ',', 19, 19, -1, mob->parse_row_mobskilldb);
+	for (i = 0; i < ARRAYLENGTH(filename); ++i) {
+		mob->skill_db_libconfig(filename[i], i > 0 ? true : false);
 	}
 }
 
@@ -5425,11 +5392,13 @@ void mob_defaults(void) {
 	mob->read_randommonster = mob_read_randommonster;
 	mob->parse_row_chatdb = mob_parse_row_chatdb;
 	mob->readchatdb = mob_readchatdb;
-	mob->parse_row_mobskilldb = mob_parse_row_mobskilldb;
 	mob->readskilldb = mob_readskilldb;
 	mob->readdb_race2 = mob_readdb_race2;
 	mob->readdb_itemratio = mob_readdb_itemratio;
 	mob->load = mob_load;
 	mob->clear_spawninfo = mob_clear_spawninfo;
 	mob->destroy_mob_db = mob_destroy_mob_db;
+	mob->skill_db_libconfig = mob_skill_db_libconfig;
+	mob->skill_db_libconfig_sub = mob_skill_db_libconfig_sub;
+	mob->skill_db_libconfig_sub_skill = mob_skill_db_libconfig_sub_skill;
 }
diff --git a/src/map/mob.h b/src/map/mob.h
index 2a1a729de..c4469c2fa 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -535,13 +535,15 @@ struct mob_interface {
 	int (*read_randommonster) (void);
 	bool (*parse_row_chatdb) (char **str, const char *source, int line, int *last_msg_id);
 	void (*readchatdb) (void);
-	bool (*parse_row_mobskilldb) (char **str, int columns, int current);
 	void (*readskilldb) (void);
 	bool (*readdb_race2) (char *fields[], int columns, int current);
 	bool (*readdb_itemratio) (char *str[], int columns, int current);
 	void (*load) (bool minimal);
 	void (*clear_spawninfo) (void);
 	void (*destroy_mob_db) (int index);
+	bool (*skill_db_libconfig) (const char *filename, bool ignore_missing);
+	bool (*skill_db_libconfig_sub) (struct config_setting_t *it, int n);
+	bool (*skill_db_libconfig_sub_skill) (struct config_setting_t *it, int n, int mob_id);
 };
 
 #ifdef HERCULES_CORE
diff --git a/src/map/script.c b/src/map/script.c
index d11b6741a..f71eae012 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -25034,6 +25034,60 @@ void script_hardcoded_constants(void)
 	script->set_constant("ITEMINFO_MATK", ITEMINFO_MATK, false, false);
 	script->set_constant("ITEMINFO_VIEWSPRITE", ITEMINFO_VIEWSPRITE, false, false);
 
+	script->constdb_comment("monster skill states");
+	script->set_constant("MSS_ANY", MSS_ANY, false, false);
+	script->set_constant("MSS_IDLE", MSS_IDLE, false, false);
+	script->set_constant("MSS_WALK", MSS_WALK, false, false);
+	script->set_constant("MSS_LOOT", MSS_LOOT, false, false);
+	script->set_constant("MSS_DEAD", MSS_DEAD, false, false);
+	script->set_constant("MSS_BERSERK", MSS_BERSERK, false, false);
+	script->set_constant("MSS_ANGRY", MSS_ANGRY, false, false);
+	script->set_constant("MSS_RUSH", MSS_RUSH, false, false);
+	script->set_constant("MSS_FOLLOW", MSS_FOLLOW, false, false);
+	script->set_constant("MSS_ANYTARGET", MSS_ANYTARGET, false, false);
+
+	script->constdb_comment("monster skill conditions");
+	script->set_constant("MSC_ANY", -1, false, false);
+	script->set_constant("MSC_ALWAYS", MSC_ALWAYS, false, false);
+	script->set_constant("MSC_MYHPLTMAXRATE", MSC_MYHPLTMAXRATE, false, false);
+	script->set_constant("MSC_MYHPINRATE", MSC_MYHPINRATE, false, false);
+	script->set_constant("MSC_FRIENDHPLTMAXRATE", MSC_FRIENDHPLTMAXRATE, false, false);
+	script->set_constant("MSC_FRIENDHPINRATE", MSC_FRIENDHPINRATE, false, false);
+	script->set_constant("MSC_MYSTATUSON", MSC_MYSTATUSON, false, false);
+	script->set_constant("MSC_MYSTATUSOFF", MSC_MYSTATUSOFF, false, false);
+	script->set_constant("MSC_FRIENDSTATUSON", MSC_FRIENDSTATUSON, false, false);
+	script->set_constant("MSC_FRIENDSTATUSOFF", MSC_FRIENDSTATUSOFF, false, false);
+	script->set_constant("MSC_ATTACKPCGT", MSC_ATTACKPCGT, false, false);
+	script->set_constant("MSC_ATTACKPCGE", MSC_ATTACKPCGE, false, false);
+	script->set_constant("MSC_SLAVELT", MSC_SLAVELT, false, false);
+	script->set_constant("MSC_SLAVELE", MSC_SLAVELE, false, false);
+	script->set_constant("MSC_CLOSEDATTACKED", MSC_CLOSEDATTACKED, false, false);
+	script->set_constant("MSC_LONGRANGEATTACKED", MSC_LONGRANGEATTACKED, false, false);
+	script->set_constant("MSC_SKILLUSED", MSC_SKILLUSED, false, false);
+	script->set_constant("MSC_AFTERSKILL", MSC_AFTERSKILL, false, false);
+	script->set_constant("MSC_CASTTARGETED", MSC_CASTTARGETED, false, false);
+	script->set_constant("MSC_RUDEATTACKED", MSC_RUDEATTACKED, false, false);
+	script->set_constant("MSC_MASTERHPLTMAXRATE", MSC_MASTERHPLTMAXRATE, false, false);
+	script->set_constant("MSC_MASTERATTACKED", MSC_MASTERATTACKED, false, false);
+	script->set_constant("MSC_ALCHEMIST", MSC_ALCHEMIST, false, false);
+	script->set_constant("MSC_SPAWN", MSC_SPAWN, false, false);
+
+	script->constdb_comment("monster skill targets");
+	script->set_constant("MST_TARGET", MST_TARGET, false, false);
+	script->set_constant("MST_RANDOM", MST_RANDOM , false, false);
+	script->set_constant("MST_SELF", MST_SELF, false, false);
+	script->set_constant("MST_FRIEND", MST_FRIEND , false, false);
+	script->set_constant("MST_MASTER", MST_MASTER , false, false);
+	script->set_constant("MST_AROUND5", MST_AROUND5, false, false);
+	script->set_constant("MST_AROUND6", MST_AROUND6, false, false);
+	script->set_constant("MST_AROUND7", MST_AROUND7, false, false);
+	script->set_constant("MST_AROUND8", MST_AROUND8, false, false);
+	script->set_constant("MST_AROUND1", MST_AROUND1, false, false);
+	script->set_constant("MST_AROUND2", MST_AROUND2, false, false);
+	script->set_constant("MST_AROUND3", MST_AROUND3, false, false);
+	script->set_constant("MST_AROUND4", MST_AROUND4, false, false);
+	script->set_constant("MST_AROUND", MST_AROUND , false, false);
+
 	script->constdb_comment("Renewal");
 #ifdef RENEWAL
 	script->set_constant("RENEWAL", 1, false, false);
-- 
cgit v1.2.3-70-g09d2