Explorar el Código

- Moved char server's mercenary code to a different file (int_mercenary.*)
- New Sql Patch for create mercenary_owner DB.
- Removed mer_id from char_db.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13166 54d463be-8e91-2dee-dedb-b68131a5f0ec

zephyrus hace 16 años
padre
commit
5954733c85

+ 2 - 0
sql-files/convert_engine_innodb.sql

@@ -28,6 +28,8 @@ ALTER TABLE `login` ENGINE = InnoDB;
 ALTER TABLE `mail` ENGINE = InnoDB;
 ALTER TABLE `mapreg` ENGINE = InnoDB;
 ALTER TABLE `memo` ENGINE = InnoDB;
+ALTER TABLE `mercenary` ENGINE = InnoDB;
+ALTER TABLE `mercenary_owner` ENGINE = InnoDB;
 #ALTER TABLE `mob_db` ENGINE = InnoDB;
 #ALTER TABLE `mob_db2` ENGINE = InnoDB;
 ALTER TABLE `party` ENGINE = InnoDB;

+ 2 - 0
sql-files/convert_engine_myisam.sql

@@ -28,6 +28,8 @@ ALTER TABLE `login` ENGINE = MyISAM;
 ALTER TABLE `mail` ENGINE = MyISAM;
 ALTER TABLE `mapreg` ENGINE = MyISAM;
 ALTER TABLE `memo` ENGINE = MyISAM;
+ALTER TABLE `mercenary` ENGINE = MyISAM;
+ALTER TABLE `mercenary_owner` ENGINE = MyISAM;
 #ALTER TABLE `mob_db` ENGINE = MyISAM;
 #ALTER TABLE `mob_db2` ENGINE = MyISAM;
 ALTER TABLE `party` ENGINE = MyISAM;

+ 16 - 0
sql-files/main.sql

@@ -497,6 +497,22 @@ CREATE TABLE IF NOT EXISTS `mercenary` (
   PRIMARY KEY  (`mer_id`)
 ) ENGINE=MyISAM;
 
+--
+-- Table structure for table `mercenary_owner`
+--
+
+CREATE TABLE IF NOT EXISTS `mercenary_owner` (
+  `char_id` int(11) NOT NULL,
+  `merc_id` int(11) NOT NULL default '0',
+  `arch_calls` int(11) NOT NULL default '0',
+  `arch_faith` int(11) NOT NULL default '0',
+  `spear_calls` int(11) NOT NULL default '0',
+  `spear_faith` int(11) NOT NULL default '0',
+  `sword_calls` int(11) NOT NULL default '0',
+  `sword_faith` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`char_id`)
+) ENGINE=MyISAM;
+
 --
 -- Table structure for table `party`
 --

+ 21 - 0
sql-files/upgrade_svn13166_mercenary_owner.sql

@@ -0,0 +1,21 @@
+-- Removes mer_id from Char DB
+
+ALTER TABLE `char` DROP COLUMN `mer_id`;
+
+-- Clean mercenary DB
+
+TRUNCATE TABLE `mercenary`;
+
+-- Table structure for table `mercenary_owner`
+
+CREATE TABLE IF NOT EXISTS `mercenary_owner` (
+  `char_id` int(11) NOT NULL,
+  `merc_id` int(11) NOT NULL default '0',
+  `arch_calls` int(11) NOT NULL default '0',
+  `arch_faith` int(11) NOT NULL default '0',
+  `spear_calls` int(11) NOT NULL default '0',
+  `spear_faith` int(11) NOT NULL default '0',
+  `sword_calls` int(11) NOT NULL default '0',
+  `sword_faith` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`char_id`)
+) ENGINE=MyISAM;

+ 2 - 2
src/char_sql/Makefile.in

@@ -14,8 +14,8 @@ COMMON_SQL_OBJ = ../common/obj_sql/sql.o
 COMMON_H = ../common/sql.h
 
 CHAR_OBJ = obj_sql/char.o obj_sql/inter.o obj_sql/int_party.o obj_sql/int_guild.o \
-	obj_sql/int_storage.o obj_sql/int_pet.o obj_sql/int_homun.o obj_sql/int_mail.o obj_sql/int_auction.o obj_sql/int_quest.o
-CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h int_mail.h int_auction.h int_quest.h
+	obj_sql/int_storage.o obj_sql/int_pet.o obj_sql/int_homun.o obj_sql/int_mail.o obj_sql/int_auction.o obj_sql/int_quest.o obj_sql/int_mercenary.o
+CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h int_mail.h int_auction.h int_quest.h int_mercenary.h
 
 HAVE_MYSQL=@HAVE_MYSQL@
 ifeq ($(HAVE_MYSQL),yes)

+ 38 - 24
src/char_sql/char.c

@@ -16,6 +16,7 @@
 #include "inter.h"
 #include "int_guild.h"
 #include "int_homun.h"
+#include "int_mercenary.h"
 #include "int_party.h"
 #include "int_storage.h"
 #include "char.h"
@@ -463,7 +464,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		(p->int_ != cp->int_) || (p->dex != cp->dex) || (p->luk != cp->luk) ||
 		(p->option != cp->option) ||
 		(p->party_id != cp->party_id) || (p->guild_id != cp->guild_id) ||
-		(p->pet_id != cp->pet_id) || (p->weapon != cp->weapon) || (p->hom_id != cp->hom_id) || (p->mer_id != cp->mer_id) ||
+		(p->pet_id != cp->pet_id) || (p->weapon != cp->weapon) || (p->hom_id != cp->hom_id) ||
 		(p->shield != cp->shield) || (p->head_top != cp->head_top) ||
 		(p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom)
 	)
@@ -472,7 +473,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 			"`base_exp`='%u', `job_exp`='%u', `zeny`='%d',"
 			"`max_hp`='%d',`hp`='%d',`max_sp`='%d',`sp`='%d',`status_point`='%d',`skill_point`='%d',"
 			"`str`='%d',`agi`='%d',`vit`='%d',`int`='%d',`dex`='%d',`luk`='%d',"
-			"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`mer_id`='%d',"
+			"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',"
 			"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
 			"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d'"
 			" WHERE  `account_id`='%d' AND `char_id` = '%d'",
@@ -480,7 +481,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 			p->base_exp, p->job_exp, p->zeny,
 			p->max_hp, p->hp, p->max_sp, p->sp, p->status_point, p->skill_point,
 			p->str, p->agi, p->vit, p->int_, p->dex, p->luk,
-			p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id, p->mer_id,
+			p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id,
 			p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom,
 			mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
 			mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y,
@@ -518,6 +519,15 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		strcat(save_status, " status2");
 	}
 
+	/* Mercenary Owner */
+	if( (p->mer_id != cp->mer_id) ||
+		(p->arch_calls != cp->arch_calls) || (p->arch_faith != cp->arch_faith) ||
+		(p->spear_calls != cp->spear_calls) || (p->spear_faith != cp->spear_faith) ||
+		(p->sword_calls != cp->sword_calls) || (p->sword_faith != cp->sword_faith) )
+	{
+		mercenary_owner_tosql(char_id, p);
+	}
+
 	//memo points
 	if( memcmp(p->memo_point, cp->memo_point, sizeof(p->memo_point)) )
 	{
@@ -908,7 +918,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT "
 		"`char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`,"
 		"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
-		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`mer_id`,`hair`,"
+		"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`hair`,"
 		"`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
 		"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`"
 		" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
@@ -943,26 +953,25 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 26, SQLDT_INT,    &p->guild_id, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_INT,    &p->pet_id, 0, NULL, NULL)
 	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_INT,    &p->hom_id, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_INT,    &p->mer_id, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT,  &p->hair, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT,  &p->hair_color, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT,  &p->clothes_color, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT,  &p->weapon, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT,  &p->shield, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT,  &p->head_top, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT,  &p->head_mid, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_SHORT,  &p->head_bottom, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_SHORT,  &p->last_point.x, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_SHORT,  &p->last_point.y, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_SHORT,  &p->save_point.x, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_SHORT,  &p->save_point.y, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_INT,    &p->partner_id, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_INT,    &p->father, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_INT,    &p->mother, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT,    &p->child, 0, NULL, NULL)
-	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_INT,    &p->fame, 0, NULL, NULL) )
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_SHORT,  &p->hair, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT,  &p->hair_color, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT,  &p->clothes_color, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT,  &p->weapon, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT,  &p->shield, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT,  &p->head_top, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT,  &p->head_mid, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT,  &p->head_bottom, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_SHORT,  &p->last_point.x, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_SHORT,  &p->last_point.y, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_SHORT,  &p->save_point.x, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_SHORT,  &p->save_point.y, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_INT,    &p->partner_id, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_INT,    &p->father, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_INT,    &p->mother, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_INT,    &p->child, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT,    &p->fame, 0, NULL, NULL) )
 	{
 		SqlStmt_ShowDebug(stmt);
 		SqlStmt_Free(stmt);
@@ -1113,6 +1122,10 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 			ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
 	}
 	strcat(t_msg, " hotkeys");
+
+	/* Mercenary Owner DataBase */
+	mercenary_owner_fromsql(char_id, p);
+
 #endif
 
 	if (save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg);	//ok. all data load successfuly!
@@ -1364,6 +1377,7 @@ int delete_char_sql(int char_id)
 	/* remove mercenary */ 
 	if( mer_id )
 		mapif_mercenary_delete(mer_id);
+	mercenary_owner_delete(char_id);
 
 	/* delete char's friends list */
 	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'", friend_db, char_id) )

+ 7 - 139
src/char_sql/int_homun.c

@@ -292,132 +292,6 @@ static void mapif_parse_homunculus_rename(int fd, int account_id, int char_id, c
 	mapif_homunculus_renamed(fd, account_id, char_id, result, name);
 }
 
-/*==========================================
- * Mercenary's System
- *------------------------------------------*/
-bool mapif_mercenary_save(struct s_mercenary* merc)
-{
-	bool flag = true;
-
-	if( merc->mercenary_id == 0 )
-	{ // Create new DB entry
-		if( SQL_ERROR == Sql_Query(sql_handle,
-			"INSERT INTO `mercenary` (`char_id`,`class`,`hp`,`sp`,`kill_counter`,`life_time`) VALUES ('%d','%d','%d','%d','%u','%u')",
-			merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time) )
-		{
-			Sql_ShowDebug(sql_handle);
-			flag = false;
-		}
-		else
-			merc->mercenary_id = (int)Sql_LastInsertId(sql_handle);
-	}
-	else if( SQL_ERROR == Sql_Query(sql_handle,
-		"UPDATE `mercenary` SET `char_id` = '%d', `class` = '%d', `hp` = '%d', `sp` = '%d', `kill_counter` = '%u', `life_time` = '%u' WHERE `mer_id` = '%d'",
-		merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time, merc->mercenary_id) )
-	{ // Update DB entry
-		Sql_ShowDebug(sql_handle);
-		flag = false;
-	}
-
-	return flag;
-}
-
-bool mapif_mercenary_load(int merc_id, int char_id, struct s_mercenary *merc)
-{
-	char* data;
-
-	memset(merc, 0, sizeof(struct s_mercenary));
-	merc->mercenary_id = merc_id;
-	merc->char_id = char_id;
-
-	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `hp`, `sp`, `kill_counter`, `life_time` FROM `mercenary` WHERE `mer_id` = '%d' AND `char_id` = '%d'", merc_id, char_id) )
-	{
-		Sql_ShowDebug(sql_handle);
-		return false;
-	}
-
-	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
-	{
-		Sql_FreeResult(sql_handle);
-		return false;
-	}
-
-	Sql_GetData(sql_handle,  0, &data, NULL); merc->class_ = atoi(data);
-	Sql_GetData(sql_handle,  1, &data, NULL); merc->hp = atoi(data);
-	Sql_GetData(sql_handle,  2, &data, NULL); merc->sp = atoi(data);
-	Sql_GetData(sql_handle,  3, &data, NULL); merc->kill_count = atoi(data);
-	Sql_GetData(sql_handle,  4, &data, NULL); merc->life_time = atoi(data);
-	Sql_FreeResult(sql_handle);
-	if( save_log )
-		ShowInfo("Mercenary loaded (%d - %d).\n", merc->mercenary_id, merc->char_id);
-	
-	return true;
-}
-
-bool mapif_mercenary_delete(int merc_id)
-{
-	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `mercenary` WHERE `mer_id` = '%d'", merc_id) )
-	{
-		Sql_ShowDebug(sql_handle);
-		return false;
-	}
-
-	return true;
-}
-
-static void mapif_mercenary_send(int fd, struct s_mercenary *merc, unsigned char flag)
-{
-	int size = sizeof(struct s_mercenary) + 5;
-
-	WFIFOHEAD(fd,size);
-	WFIFOW(fd,0) = 0x3870;
-	WFIFOW(fd,2) = size;
-	WFIFOB(fd,4) = flag;
-	memcpy(WFIFOP(fd,5),merc,sizeof(struct s_mercenary));
-	WFIFOSET(fd,size);
-}
-
-static void mapif_parse_mercenary_create(int fd, struct s_mercenary* merc)
-{
-	bool result = mapif_mercenary_save(merc);
-	mapif_mercenary_send(fd, merc, result);
-}
-
-static void mapif_parse_mercenary_load(int fd, int merc_id, int char_id)
-{
-	struct s_mercenary merc;
-	bool result = mapif_mercenary_load(merc_id, char_id, &merc);
-	mapif_mercenary_send(fd, &merc, result);
-}
-
-static void mapif_mercenary_deleted(int fd, unsigned char flag)
-{
-	WFIFOHEAD(fd,3);
-	WFIFOW(fd,0) = 0x3871;
-	WFIFOB(fd,2) = flag;
-	WFIFOSET(fd,3);
-}
-
-static void mapif_parse_mercenary_delete(int fd, int merc_id)
-{
-	bool result = mapif_mercenary_delete(merc_id);
-	mapif_mercenary_deleted(fd, result);
-}
-
-static void mapif_mercenary_saved(int fd, unsigned char flag)
-{
-	WFIFOHEAD(fd,3);
-	WFIFOW(fd,0) = 0x3872;
-	WFIFOB(fd,2) = flag;
-	WFIFOSET(fd,3);
-}
-
-static void mapif_parse_mercenary_save(int fd, struct s_mercenary* merc)
-{
-	bool result = mapif_mercenary_save(merc);
-	mapif_mercenary_saved(fd, result);
-}
-
 /*==========================================
  * Inter Packets
  *------------------------------------------*/
@@ -427,19 +301,13 @@ int inter_homunculus_parse_frommap(int fd)
 
 	switch( cmd )
 	{
-	// Homunculus Packets
-	case 0x3090: mapif_parse_homunculus_create(fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,8)); break;
-	case 0x3091: mapif_parse_homunculus_load  (fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
-	case 0x3092: mapif_parse_homunculus_save  (fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,8)); break;
-	case 0x3093: mapif_parse_homunculus_delete(fd, (int)RFIFOL(fd,2)); break;
-	case 0x3094: mapif_parse_homunculus_rename(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6), (char*)RFIFOP(fd,10)); break;
-	// Mercenary Packets
-	case 0x3070: mapif_parse_mercenary_create(fd, (struct s_mercenary*)RFIFOP(fd,4)); break;
-	case 0x3071: mapif_parse_mercenary_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
-	case 0x3072: mapif_parse_mercenary_delete(fd, (int)RFIFOL(fd,2)); break;
-	case 0x3073: mapif_parse_mercenary_save(fd, (struct s_mercenary*)RFIFOP(fd,4)); break;
-	default:
-		return 0;
+		case 0x3090: mapif_parse_homunculus_create(fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,8)); break;
+		case 0x3091: mapif_parse_homunculus_load  (fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
+		case 0x3092: mapif_parse_homunculus_save  (fd, (int)RFIFOW(fd,2), (int)RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,8)); break;
+		case 0x3093: mapif_parse_homunculus_delete(fd, (int)RFIFOL(fd,2)); break;
+		case 0x3094: mapif_parse_homunculus_rename(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6), (char*)RFIFOP(fd,10)); break;
+		default:
+			return 0;
 	}
 	return 1;
 }

+ 0 - 3
src/char_sql/int_homun.h

@@ -5,7 +5,6 @@
 #define _INT_HOMUN_SQL_H_
 
 struct s_homunculus;
-struct s_mercenary;
 
 int inter_homunculus_sql_init(void);
 void inter_homunculus_sql_final(void);
@@ -16,6 +15,4 @@ bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd);
 bool mapif_homunculus_delete(int homun_id);
 bool mapif_homunculus_rename(char *name);
 
-bool mapif_mercenary_delete(int merc_id);
-
 #endif /* _INT_HOMUN_SQL_H_ */

+ 218 - 0
src/char_sql/int_mercenary.c

@@ -0,0 +1,218 @@
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#include "../common/mmo.h"
+#include "../common/malloc.h"
+#include "../common/strlib.h"
+#include "../common/showmsg.h"
+#include "../common/socket.h"
+#include "../common/utils.h"
+#include "../common/sql.h"
+#include "char.h"
+#include "inter.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+bool mercenary_owner_fromsql(int char_id, struct mmo_charstatus *status)
+{
+	char* data;
+
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith` FROM `mercenary_owner` WHERE `char_id` = '%d'", char_id) )
+	{
+		Sql_ShowDebug(sql_handle);
+		return false;
+	}
+
+	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+	{
+		Sql_FreeResult(sql_handle);
+		return false;
+	}
+
+	Sql_GetData(sql_handle,  0, &data, NULL); status->mer_id = atoi(data);
+	Sql_GetData(sql_handle,  1, &data, NULL); status->arch_calls = atoi(data);
+	Sql_GetData(sql_handle,  2, &data, NULL); status->arch_faith = atoi(data);
+	Sql_GetData(sql_handle,  3, &data, NULL); status->spear_calls = atoi(data);
+	Sql_GetData(sql_handle,  4, &data, NULL); status->spear_faith = atoi(data);
+	Sql_GetData(sql_handle,  5, &data, NULL); status->sword_calls = atoi(data);
+	Sql_GetData(sql_handle,  6, &data, NULL); status->sword_faith = atoi(data);
+	Sql_FreeResult(sql_handle);
+
+	return true;
+}
+
+bool mercenary_owner_tosql(int char_id, struct mmo_charstatus *status)
+{
+	if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `mercenary_owner` (`char_id`, `merc_id`, `arch_calls`, `arch_faith`, `spear_calls`, `spear_faith`, `sword_calls`, `sword_faith`) VALUES ('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+		char_id, status->mer_id, status->arch_calls, status->arch_faith, status->spear_calls, status->spear_faith, status->sword_calls, status->sword_faith) )
+	{
+		Sql_ShowDebug(sql_handle);
+		return false;
+	}
+
+	return true;
+}
+
+bool mercenary_owner_delete(int char_id)
+{
+	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `mercenary_owner` WHERE `char_id` = '%d'", char_id) )
+	{
+		Sql_ShowDebug(sql_handle);
+		return false;
+	}
+
+	return true;
+}
+
+bool mapif_mercenary_save(struct s_mercenary* merc)
+{
+	bool flag = true;
+
+	if( merc->mercenary_id == 0 )
+	{ // Create new DB entry
+		if( SQL_ERROR == Sql_Query(sql_handle,
+			"INSERT INTO `mercenary` (`char_id`,`class`,`hp`,`sp`,`kill_counter`,`life_time`) VALUES ('%d','%d','%d','%d','%u','%u')",
+			merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time) )
+		{
+			Sql_ShowDebug(sql_handle);
+			flag = false;
+		}
+		else
+			merc->mercenary_id = (int)Sql_LastInsertId(sql_handle);
+	}
+	else if( SQL_ERROR == Sql_Query(sql_handle,
+		"UPDATE `mercenary` SET `char_id` = '%d', `class` = '%d', `hp` = '%d', `sp` = '%d', `kill_counter` = '%u', `life_time` = '%u' WHERE `mer_id` = '%d'",
+		merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time, merc->mercenary_id) )
+	{ // Update DB entry
+		Sql_ShowDebug(sql_handle);
+		flag = false;
+	}
+
+	return flag;
+}
+
+bool mapif_mercenary_load(int merc_id, int char_id, struct s_mercenary *merc)
+{
+	char* data;
+
+	memset(merc, 0, sizeof(struct s_mercenary));
+	merc->mercenary_id = merc_id;
+	merc->char_id = char_id;
+
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `hp`, `sp`, `kill_counter`, `life_time` FROM `mercenary` WHERE `mer_id` = '%d' AND `char_id` = '%d'", merc_id, char_id) )
+	{
+		Sql_ShowDebug(sql_handle);
+		return false;
+	}
+
+	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+	{
+		Sql_FreeResult(sql_handle);
+		return false;
+	}
+
+	Sql_GetData(sql_handle,  0, &data, NULL); merc->class_ = atoi(data);
+	Sql_GetData(sql_handle,  1, &data, NULL); merc->hp = atoi(data);
+	Sql_GetData(sql_handle,  2, &data, NULL); merc->sp = atoi(data);
+	Sql_GetData(sql_handle,  3, &data, NULL); merc->kill_count = atoi(data);
+	Sql_GetData(sql_handle,  4, &data, NULL); merc->life_time = atoi(data);
+	Sql_FreeResult(sql_handle);
+	if( save_log )
+		ShowInfo("Mercenary loaded (%d - %d).\n", merc->mercenary_id, merc->char_id);
+	
+	return true;
+}
+
+bool mapif_mercenary_delete(int merc_id)
+{
+	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `mercenary` WHERE `mer_id` = '%d'", merc_id) )
+	{
+		Sql_ShowDebug(sql_handle);
+		return false;
+	}
+
+	return true;
+}
+
+static void mapif_mercenary_send(int fd, struct s_mercenary *merc, unsigned char flag)
+{
+	int size = sizeof(struct s_mercenary) + 5;
+
+	WFIFOHEAD(fd,size);
+	WFIFOW(fd,0) = 0x3870;
+	WFIFOW(fd,2) = size;
+	WFIFOB(fd,4) = flag;
+	memcpy(WFIFOP(fd,5),merc,sizeof(struct s_mercenary));
+	WFIFOSET(fd,size);
+}
+
+static void mapif_parse_mercenary_create(int fd, struct s_mercenary* merc)
+{
+	bool result = mapif_mercenary_save(merc);
+	mapif_mercenary_send(fd, merc, result);
+}
+
+static void mapif_parse_mercenary_load(int fd, int merc_id, int char_id)
+{
+	struct s_mercenary merc;
+	bool result = mapif_mercenary_load(merc_id, char_id, &merc);
+	mapif_mercenary_send(fd, &merc, result);
+}
+
+static void mapif_mercenary_deleted(int fd, unsigned char flag)
+{
+	WFIFOHEAD(fd,3);
+	WFIFOW(fd,0) = 0x3871;
+	WFIFOB(fd,2) = flag;
+	WFIFOSET(fd,3);
+}
+
+static void mapif_parse_mercenary_delete(int fd, int merc_id)
+{
+	bool result = mapif_mercenary_delete(merc_id);
+	mapif_mercenary_deleted(fd, result);
+}
+
+static void mapif_mercenary_saved(int fd, unsigned char flag)
+{
+	WFIFOHEAD(fd,3);
+	WFIFOW(fd,0) = 0x3872;
+	WFIFOB(fd,2) = flag;
+	WFIFOSET(fd,3);
+}
+
+static void mapif_parse_mercenary_save(int fd, struct s_mercenary* merc)
+{
+	bool result = mapif_mercenary_save(merc);
+	mapif_mercenary_saved(fd, result);
+}
+
+int inter_mercenary_sql_init(void)
+{
+	return 0;
+}
+void inter_mercenary_sql_final(void)
+{
+	return;
+}
+
+/*==========================================
+ * Inter Packets
+ *------------------------------------------*/
+int inter_mercenary_parse_frommap(int fd)
+{
+	unsigned short cmd = RFIFOW(fd,0);
+
+	switch( cmd )
+	{
+		case 0x3070: mapif_parse_mercenary_create(fd, (struct s_mercenary*)RFIFOP(fd,4)); break;
+		case 0x3071: mapif_parse_mercenary_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
+		case 0x3072: mapif_parse_mercenary_delete(fd, (int)RFIFOL(fd,2)); break;
+		case 0x3073: mapif_parse_mercenary_save(fd, (struct s_mercenary*)RFIFOP(fd,4)); break;
+		default:
+			return 0;
+	}
+	return 1;
+}

+ 20 - 0
src/char_sql/int_mercenary.h

@@ -0,0 +1,20 @@
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#ifndef _INT_MERCENARY_SQL_H_
+#define _INT_MERCENARY_SQL_H_
+
+struct s_mercenary;
+
+int inter_mercenary_sql_init(void);
+void inter_mercenary_sql_final(void);
+int inter_mercenary_parse_frommap(int fd);
+
+// Mercenary Owner Database
+bool mercenary_owner_fromsql(int char_id, struct mmo_charstatus *status);
+bool mercenary_owner_tosql(int char_id, struct mmo_charstatus *status);
+bool mercenary_owner_delete(int char_id);
+
+bool mapif_mercenary_delete(int merc_id);
+
+#endif /* _INT_MERCENARY_SQL_H_ */

+ 6 - 2
src/char_sql/inter.c

@@ -15,6 +15,7 @@
 #include "int_storage.h"
 #include "int_pet.h"
 #include "int_homun.h"
+#include "int_mercenary.h"
 #include "int_mail.h"
 #include "int_auction.h"
 #include "int_quest.h"
@@ -296,7 +297,8 @@ int inter_init_sql(const char *file)
 	inter_storage_sql_init();
 	inter_party_sql_init();
 	inter_pet_sql_init();
-	inter_homunculus_sql_init(); // albator
+	inter_homunculus_sql_init();
+	inter_mercenary_sql_init();
 	inter_accreg_sql_init();
 	inter_mail_sql_init();
 	inter_auction_sql_init();
@@ -315,7 +317,8 @@ void inter_final(void)
 	inter_storage_sql_final();
 	inter_party_sql_final();
 	inter_pet_sql_final();
-	inter_homunculus_sql_final();	//[orn]
+	inter_homunculus_sql_final();
+	inter_mercenary_sql_final();
 	inter_mail_sql_final();
 	inter_auction_sql_final();
 	
@@ -719,6 +722,7 @@ int inter_parse_frommap(int fd)
 		  || inter_storage_parse_frommap(fd)
 		  || inter_pet_parse_frommap(fd)
 		  || inter_homunculus_parse_frommap(fd)
+		  || inter_mercenary_parse_frommap(fd)
 		  || inter_mail_parse_frommap(fd)
 		  || inter_auction_parse_frommap(fd)
 		  || inter_quest_parse_frommap(fd)

+ 8 - 0
vcproj-6/char-server_sql.dsp

@@ -219,6 +219,14 @@ SOURCE=..\src\char_sql\int_homun.h
 # End Source File
 # Begin Source File
 
+SOURCE=..\src\char_sql\int_mercenary.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\char_sql\int_mercenary.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\char_sql\int_mail.c
 # End Source File
 # Begin Source File

+ 6 - 0
vcproj-7.1/char-server_sql.vcproj

@@ -173,6 +173,12 @@
 			<File
 				RelativePath="..\src\char_sql\int_mail.h">
 			</File>
+			<File
+				RelativePath="..\src\char_sql\int_mercenary.c">
+			</File>
+			<File
+				RelativePath="..\src\char_sql\int_mercenary.h">
+			</File>
 			<File
 				RelativePath="..\src\char_sql\int_party.c">
 			</File>

+ 8 - 0
vcproj-8/char-server_sql.vcproj

@@ -370,6 +370,14 @@
 				RelativePath="..\src\char_sql\int_mail.h"
 				>
 			</File>
+			<File
+				RelativePath="..\src\char_sql\int_mercenary.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\char_sql\int_mercenary.h"
+				>
+			</File>
 			<File
 				RelativePath="..\src\char_sql\int_party.c"
 				>

+ 8 - 0
vcproj-9/char-server_sql.vcproj

@@ -375,6 +375,14 @@
 				RelativePath="..\src\char_sql\int_mail.h"
 				>
 			</File>
+			<File
+				RelativePath="..\src\char_sql\int_mercenary.c"
+				>
+			</File>
+			<File
+				RelativePath="..\src\char_sql\int_mercenary.h"
+				>
+			</File>
 			<File
 				RelativePath="..\src\char_sql\int_party.c"
 				>