浏览代码

Char server now loads/saves quest information.
Included table definitions for quests and quest objectives.

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

Kevin 17 年之前
父节点
当前提交
f5fd71f4be
共有 4 个文件被更改,包括 164 次插入3 次删除
  1. 28 0
      sql-files/main.sql
  2. 27 0
      sql-files/upgrade_svn12545.sql
  3. 108 3
      src/char_sql/char.c
  4. 1 0
      src/common/mmo.h

+ 28 - 0
sql-files/main.sql

@@ -565,6 +565,34 @@ CREATE TABLE `pet` (
   PRIMARY KEY  (`pet_id`)
 ) ENGINE=MyISAM;
 
+--
+-- Table structure for table `quest`
+--
+
+DROP TABLE IF EXISTS `quest`;
+CREATE TABLE  `quest` (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `char_id` int(11) unsigned NOT NULL default '0',
+  `quest_id` int(10) unsigned NOT NULL,
+  `state` enum('1','0') NOT NULL default '0',
+  PRIMARY KEY  (`id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `quest_mob`
+--
+
+DROP TABLE IF EXISTS `quest_objective`;
+CREATE TABLE  `quest_objective` (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `quest_id` int(11) unsigned NOT NULL,
+  `count` mediumint(8) unsigned NOT NULL default '0',
+  `name` varchar(255) NOT NULL default '',
+  `num` tinyint(3) unsigned NOT NULL,
+  PRIMARY KEY  (`id`)
+) ENGINE=MyISAM;
+
 --
 -- Table structure for table `ragsrvinfo`
 --

+ 27 - 0
sql-files/upgrade_svn12545.sql

@@ -0,0 +1,27 @@
+--
+-- Table structure for table `quest`
+--
+
+DROP TABLE IF EXISTS `quest`;
+CREATE TABLE  `quest` (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `char_id` int(11) unsigned NOT NULL default '0',
+  `quest_id` int(10) unsigned NOT NULL,
+  `state` enum('1','0') NOT NULL default '0',
+  PRIMARY KEY  (`id`)
+) ENGINE=MyISAM;
+
+--
+-- Table structure for table `quest_mob`
+--
+
+DROP TABLE IF EXISTS `quest_objective`;
+CREATE TABLE  `quest_objective` (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `quest_id` int(11) unsigned NOT NULL,
+  `count` mediumint(8) unsigned NOT NULL default '0',
+  `name` varchar(255) NOT NULL default '',
+  `num` tinyint(3) unsigned NOT NULL,
+  PRIMARY KEY  (`id`)
+) ENGINE=MyISAM;

+ 108 - 3
src/char_sql/char.c

@@ -63,6 +63,8 @@ char mail_db[256] = "mail"; // MAIL SYSTEM
 char auction_db[256] = "auction"; // Auctions System
 char friend_db[256] = "friends";
 char hotkey_db[256] = "hotkey";
+char quest_db[256] = "quest";
+char quest_obj_db[256] = "quest_objective";
 
 #ifndef TXT_SQL_CONVERT
 static DBMap* char_db_; // int char_id -> struct mmo_charstatus*
@@ -436,12 +438,12 @@ static void* create_charstatus(DBKey key, va_list args)
 
 int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 {
-	int i = 0;
+	int i = 0, j;
 	int count = 0;
 	int diff = 0;
 	char save_status[128]; //For displaying save information. [Skotlex]
 	struct mmo_charstatus *cp;
-	StringBuf buf;
+	StringBuf buf, buf2;
 
 	if (char_id!=p->char_id) return 0;
 
@@ -653,6 +655,75 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		else //Friend list cleared.
 			strcat(save_status, " friends");
 	}
+
+	StringBuf_Clear(&buf);
+	StringBuf_Printf(&buf, "REPLACE INTO `%s` (`char_id`, `quest_id`, `state`) VALUES ", quest_db);
+	for(i=0; i<MAX_QUEST; i++)
+	{
+
+		if(p->quest_log[i].quest_id)
+		{
+			if(diff)
+				StringBuf_AppendStr(&buf, ",");
+			StringBuf_Printf(&buf, "('%d', '%d', '%d')", p->char_id, p->quest_log[i].quest_id, p->quest_log[i].state);
+			diff = 1;
+		}
+
+	}
+
+	if(diff) {
+		if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+			Sql_ShowDebug(sql_handle);
+		else
+			strcat(save_status, " hotkeys");
+	}
+
+	//save quests
+	StringBuf_Init(&buf2);
+	StringBuf_Clear(&buf);
+	StringBuf_Clear(&buf2);
+	StringBuf_Printf(&buf, "REPLACE INTO `%s` (`char_id`, `quest_id`, `state`) VALUES ", quest_db);
+	for(i=0; i<MAX_QUEST; i++)
+	{
+
+		if(p->quest_log[i].quest_id)
+		{
+			if(diff)
+				StringBuf_AppendStr(&buf, ",");
+			StringBuf_Printf(&buf, "('%d', '%d', '%d')", p->char_id, p->quest_log[i].quest_id, p->quest_log[i].state);
+			diff = 1;
+
+			StringBuf_Printf(&buf2, "REPLACE INTO `%s` (`quest_id`, `num`, `name`, `count`) VALUES ", quest_obj_db);
+			for(j=0; j<MAX_QUEST_OBJECTIVES; j++)
+			{
+
+				if(p->quest_log[i].objectives[j].name)
+				{
+
+					if(count)
+						StringBuf_AppendStr(&buf2, ",");
+					StringBuf_Printf(&buf2, "('%d', '%d', '%s', '%d')", p->quest_log[i].quest_id, j, p->quest_log[i].objectives[j].name, p->quest_log[i].objectives[j].count);
+					count = 1;
+
+				}
+			}
+
+			if(diff) {
+				if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf2)) )
+					Sql_ShowDebug(sql_handle);
+			}
+		}
+	}
+
+	if(diff) {
+		if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
+			Sql_ShowDebug(sql_handle);
+		else
+			strcat(save_status, " hotkeys");
+	}
+
+	StringBuf_Destroy(&buf2);
+
 #ifdef HOTKEY_SAVING
 	// hotkeys
 	StringBuf_Clear(&buf);
@@ -911,7 +982,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	char t_msg[128] = "";
 	struct mmo_charstatus* cp;
 	StringBuf buf;
-	SqlStmt* stmt;
+	SqlStmt* stmt, *stmt2;
 	char last_map[MAP_NAME_LENGTH_EXT];
 	char save_map[MAP_NAME_LENGTH_EXT];
 	char point_map[MAP_NAME_LENGTH_EXT];
@@ -919,6 +990,8 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 	struct item tmp_item;
 	struct skill tmp_skill;
 	struct s_friend tmp_friend;
+	struct quest tmp_quest;
+	struct quest_objective tmp_quest_obj;
 #ifdef HOTKEY_SAVING
 	struct hotkey tmp_hotkey;
 	int hotkey_num;
@@ -1119,6 +1192,38 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 		memcpy(&p->friends[i], &tmp_friend, sizeof(tmp_friend));
 	strcat(t_msg, " friends");
 
+	//read quests
+	//`quests` (`quest_id`, `char_id`, `state`)
+	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT q.`quest_id`, q.`state` FROM `%s` q", quest_db)
+	||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+	||	SQL_ERROR == SqlStmt_Execute(stmt)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT,    &tmp_quest.quest_id, 0, NULL, NULL)
+	||	SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT,	   &tmp_quest.state, 0, NULL, NULL) )
+		SqlStmt_ShowDebug(stmt);
+
+	stmt2 = SqlStmt_Malloc(sql_handle);
+
+	for( i = 0; i < MAX_QUEST && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+	{
+		memcpy(&p->quest_log[i], &tmp_quest, sizeof(tmp_quest));
+
+		//`quest_objectives`
+		if( SQL_ERROR == SqlStmt_Prepare(stmt2, "SELECT q.`count`, q.`name` FROM `%s` q", quest_obj_db)
+		||	SQL_ERROR == SqlStmt_BindParam(stmt2, 0, SQLDT_INT, &char_id, 0)
+		||	SQL_ERROR == SqlStmt_Execute(stmt2)
+		||	SQL_ERROR == SqlStmt_BindColumn(stmt2, 0, SQLDT_INT,    &tmp_quest_obj.count, 0, NULL, NULL)
+		||	SQL_ERROR == SqlStmt_BindColumn(stmt2, 1, SQLDT_STRING, &tmp_quest_obj.name, 0, NULL, NULL) )
+			SqlStmt_ShowDebug(stmt2);
+
+		for( j = 0; j < MAX_QUEST_OBJECTIVES && SQL_SUCCESS == SqlStmt_NextRow(stmt2); ++j )
+			memcpy(&p->quest_log[i].objectives[j], &tmp_quest_obj, sizeof(tmp_quest_obj));
+		p->quest_log[i].num_objectives = j+1;
+	}
+	p->num_quests = i+1;
+	strcat(t_msg, " quests");
+
+	SqlStmt_Free(stmt2);
+
 #ifdef HOTKEY_SAVING
 	//read hotkeys
 	//`hotkey` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`

+ 1 - 0
src/common/mmo.h

@@ -271,6 +271,7 @@ struct mmo_charstatus {
 	struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
 	struct item inventory[MAX_INVENTORY],cart[MAX_CART];
 	struct skill skill[MAX_SKILL];
+	int num_quests;
 	struct quest quest_log[MAX_QUEST];
 
 	struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]