瀏覽代碼

Fixed bugreport:6343 homun-s skill tree now is properly populated with previous homun form skills, note the sql table update: upgrade_svn16663.sql

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16663 54d463be-8e91-2dee-dedb-b68131a5f0ec
shennetsind 12 年之前
父節點
當前提交
ba768bfa77
共有 4 個文件被更改,包括 68 次插入40 次删除
  1. 1 0
      sql-files/upgrade_svn16663.sql
  2. 25 24
      src/char/int_homun.c
  3. 1 0
      src/common/mmo.h
  4. 41 16
      src/map/homunculus.c

+ 1 - 0
sql-files/upgrade_svn16663.sql

@@ -0,0 +1 @@
+ALTER TABLE  `homunculus` ADD  `prev_class` MEDIUMINT( 9 ) NOT NULL AFTER  `class`

+ 25 - 24
src/char/int_homun.c

@@ -93,9 +93,9 @@ bool mapif_homunculus_save(struct s_homunculus* hd)
 	if( hd->hom_id == 0 )
 	{// new homunculus
 		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
-			"(`char_id`, `class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) "
-			"VALUES ('%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
-			homunculus_db, hd->char_id, hd->class_, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
+			"(`char_id`, `class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) "
+			"VALUES ('%d', '%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
+			homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
 			hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize) )
 		{
 			Sql_ShowDebug(sql_handle);
@@ -108,8 +108,8 @@ bool mapif_homunculus_save(struct s_homunculus* hd)
 	}
 	else
 	{
-		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'",
-			homunculus_db, hd->char_id, hd->class_, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'",
+			homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
 			hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id) )
 		{
 			Sql_ShowDebug(sql_handle);
@@ -156,7 +156,7 @@ bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd)
 
 	memset(hd, 0, sizeof(*hd));
 
-	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `%s` WHERE `homun_id`='%u'", homunculus_db, homun_id) )
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `%s` WHERE `homun_id`='%u'", homunculus_db, homun_id) )
 	{
 		Sql_ShowDebug(sql_handle);
 		return false;
@@ -177,24 +177,25 @@ bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd)
 	hd->hom_id = homun_id;
 	Sql_GetData(sql_handle,  1, &data, NULL); hd->char_id = atoi(data);
 	Sql_GetData(sql_handle,  2, &data, NULL); hd->class_ = atoi(data);
-	Sql_GetData(sql_handle,  3, &data, &len); safestrncpy(hd->name, data, sizeof(hd->name));
-	Sql_GetData(sql_handle,  4, &data, NULL); hd->level = atoi(data);
-	Sql_GetData(sql_handle,  5, &data, NULL); hd->exp = atoi(data);
-	Sql_GetData(sql_handle,  6, &data, NULL); hd->intimacy = (unsigned int)strtoul(data, NULL, 10);
-	Sql_GetData(sql_handle,  7, &data, NULL); hd->hunger = atoi(data);
-	Sql_GetData(sql_handle,  8, &data, NULL); hd->str = atoi(data);
-	Sql_GetData(sql_handle,  9, &data, NULL); hd->agi = atoi(data);
-	Sql_GetData(sql_handle, 10, &data, NULL); hd->vit = atoi(data);
-	Sql_GetData(sql_handle, 11, &data, NULL); hd->int_ = atoi(data);
-	Sql_GetData(sql_handle, 12, &data, NULL); hd->dex = atoi(data);
-	Sql_GetData(sql_handle, 13, &data, NULL); hd->luk = atoi(data);
-	Sql_GetData(sql_handle, 14, &data, NULL); hd->hp = atoi(data);
-	Sql_GetData(sql_handle, 15, &data, NULL); hd->max_hp = atoi(data);
-	Sql_GetData(sql_handle, 16, &data, NULL); hd->sp = atoi(data);
-	Sql_GetData(sql_handle, 17, &data, NULL); hd->max_sp = atoi(data);
-	Sql_GetData(sql_handle, 18, &data, NULL); hd->skillpts = atoi(data);
-	Sql_GetData(sql_handle, 19, &data, NULL); hd->rename_flag = atoi(data);
-	Sql_GetData(sql_handle, 20, &data, NULL); hd->vaporize = atoi(data);
+	Sql_GetData(sql_handle,  3, &data, NULL); hd->prev_class = atoi(data);
+	Sql_GetData(sql_handle,  4, &data, &len); safestrncpy(hd->name, data, sizeof(hd->name));
+	Sql_GetData(sql_handle,  5, &data, NULL); hd->level = atoi(data);
+	Sql_GetData(sql_handle,  6, &data, NULL); hd->exp = atoi(data);
+	Sql_GetData(sql_handle,  7, &data, NULL); hd->intimacy = (unsigned int)strtoul(data, NULL, 10);
+	Sql_GetData(sql_handle,  8, &data, NULL); hd->hunger = atoi(data);
+	Sql_GetData(sql_handle,  9, &data, NULL); hd->str = atoi(data);
+	Sql_GetData(sql_handle, 10, &data, NULL); hd->agi = atoi(data);
+	Sql_GetData(sql_handle, 11, &data, NULL); hd->vit = atoi(data);
+	Sql_GetData(sql_handle, 12, &data, NULL); hd->int_ = atoi(data);
+	Sql_GetData(sql_handle, 13, &data, NULL); hd->dex = atoi(data);
+	Sql_GetData(sql_handle, 14, &data, NULL); hd->luk = atoi(data);
+	Sql_GetData(sql_handle, 15, &data, NULL); hd->hp = atoi(data);
+	Sql_GetData(sql_handle, 16, &data, NULL); hd->max_hp = atoi(data);
+	Sql_GetData(sql_handle, 17, &data, NULL); hd->sp = atoi(data);
+	Sql_GetData(sql_handle, 18, &data, NULL); hd->max_sp = atoi(data);
+	Sql_GetData(sql_handle, 19, &data, NULL); hd->skillpts = atoi(data);
+	Sql_GetData(sql_handle, 20, &data, NULL); hd->rename_flag = atoi(data);
+	Sql_GetData(sql_handle, 21, &data, NULL); hd->vaporize = atoi(data);
 	Sql_FreeResult(sql_handle);
 
 	hd->intimacy = cap_value(hd->intimacy, 0, 100000);

+ 1 - 0
src/common/mmo.h

@@ -274,6 +274,7 @@ struct s_homunculus {	//[orn]
 	int hom_id;
 	int char_id;
 	short class_;
+	short prev_class;
 	int hp,max_hp,sp,max_sp;
 	unsigned int intimacy;	//[orn]
 	short hunger;

+ 41 - 16
src/map/homunculus.c

@@ -157,32 +157,53 @@ int merc_hom_delete(struct homun_data *hd, int emote)
 
 int merc_hom_calc_skilltree(struct homun_data *hd)
 {
-	int i,id=0 ;
-	int j,f=1;
-	int c=0;
+	int i, id = 0;
+	int j, f = 1;
+	int c = 0;
 
 	nullpo_ret(hd);
+	/* load previous homunculus form skills first. */
+	if( hd->homunculus.prev_class != 0 ) {
+		c = hd->homunculus.prev_class - HM_CLASS_BASE;
+		
+		for( i = 0; i < MAX_SKILL_TREE && ( id = hskill_tree[c][i].id ) > 0; i++ ) {
+			if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
+				continue; //Skill already known.
+			if(!battle_config.skillfree) {
+				for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ) {
+					if( hskill_tree[c][i].need[j].id &&
+					   merc_hom_checkskill(hd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv ) {
+						f = 0;
+						break;
+					}
+				}
+			}
+			if ( f )
+				hd->homunculus.hskill[id-HM_SKILLBASE].id = id;
+		}
+		
+		f = 1;
+		id = c = 0;
+	}
+	
 	c = hd->homunculus.class_ - HM_CLASS_BASE;
 	
-	for(i=0;i < MAX_SKILL_TREE && (id = hskill_tree[c][i].id) > 0;i++)
-	{
-		if(hd->homunculus.hskill[id-HM_SKILLBASE].id)
+	for( i = 0; i < MAX_SKILL_TREE && ( id = hskill_tree[c][i].id ) > 0; i++ ) {
+		if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id )
 			continue; //Skill already known.
-		if(!battle_config.skillfree)
-		{
-			for(j=0;j<MAX_PC_SKILL_REQUIRE;j++)
-			{
+		if(!battle_config.skillfree) {
+			for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ) {
 				if( hskill_tree[c][i].need[j].id &&
-					merc_hom_checkskill(hd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv) 
-				{
-					f=0;
+					merc_hom_checkskill(hd,hskill_tree[c][i].need[j].id) < hskill_tree[c][i].need[j].lv ) {
+					f = 0;
 					break;
 				}
 			}
 		}
-		if (f)
-			hd->homunculus.hskill[id-HM_SKILLBASE].id = id ;
+		if ( f )
+			hd->homunculus.hskill[id-HM_SKILLBASE].id = id;
 	}
+	
 	if( hd->master )
 		clif_homskillinfoblock(hd->master);
 	return 0;
@@ -370,7 +391,7 @@ int hom_mutate(struct homun_data *hd, int homun_id)
 {
 	struct s_homunculus *hom;
 	struct map_session_data *sd;
-	int m_class, m_id;
+	int m_class, m_id, prev_class = 0;
 	nullpo_ret(hd);
 
 	m_class = hom_class2mapid(hd->homunculus.class_);
@@ -385,6 +406,8 @@ int hom_mutate(struct homun_data *hd, int homun_id)
 	if (!sd)
 		return 0;
 
+	prev_class = hd->homunculus.class_;
+	
 	if (!merc_hom_change_class(hd, homun_id)) {
 		ShowError("hom_mutate: Can't evolve homunc from %d to %d", hd->homunculus.class_, homun_id);
 		return 0;
@@ -397,10 +420,12 @@ int hom_mutate(struct homun_data *hd, int homun_id)
 	clif_emotion(&sd->bl, E_NO1);
 	clif_specialeffect(&hd->bl,568,AREA);
 
+	
 	//status_Calc flag&1 will make current HP/SP be reloaded from hom structure
 	hom = &hd->homunculus;
 	hom->hp = hd->battle_status.hp;
 	hom->sp = hd->battle_status.sp;
+	hom->prev_class = prev_class;
 	status_calc_homunculus(hd,1);
 
 	if (!(battle_config.hom_setting&0x2))