Browse Source

* Fix homunc & code cleanup [Toms]
- Timer problems on delete_timer
- Intimacy problem (overflow & new values)
- Homunc deleted if intimacy < 0
- base exp is now given to master
- Homunc sometimes not saved

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

toms 19 years ago
parent
commit
ee5ee4fcd0
7 changed files with 114 additions and 75 deletions
  1. 7 0
      Changelog-Trunk.txt
  2. 1 1
      src/char_sql/char.c
  3. 1 1
      src/common/mmo.h
  4. 68 39
      src/map/mercenary.c
  5. 2 0
      src/map/mercenary.h
  6. 4 1
      src/map/mob.c
  7. 31 33
      src/map/skill.c

+ 7 - 0
Changelog-Trunk.txt

@@ -3,6 +3,13 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2006/07/27
+	* Fix homunc & code cleanup [Toms] 
+	  - Timer problems on delete_timer
+	  - Intimacy problem (overflow & new values)
+	  - Homunc deleted if intimacy < 0
+	  - base exp is now given to master
+	  - Homunc sometimes not saved
 2006/07/26
 	* Fixed a memory leak when reading the item_db txt. [Skotlex]
 	* Applied the necessary changes to make @partyoption reflect it's changes

+ 1 - 1
src/char_sql/char.c

@@ -482,7 +482,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->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)
 	)

+ 1 - 1
src/common/mmo.h

@@ -174,7 +174,7 @@ struct s_homunculus {	//[orn]
 	int char_id;
 	short class_;
 	int hp,max_hp,sp,max_sp;
-	int intimacy;	//[orn]
+	unsigned long intimacy;	//[orn]
 	short hunger;
 	struct skill hskill[MAX_HOMUNSKILL]; //albator
 	short skillpts;

+ 68 - 39
src/map/mercenary.c

@@ -104,6 +104,7 @@ void merc_load_exptables(void)
 
 }
 
+
 void merc_damage(struct homun_data *hd,struct block_list *src,int hp,int sp)
 {
 	nullpo_retv(hd);
@@ -119,9 +120,9 @@ void merc_damage(struct homun_data *hd,struct block_list *src,int hp,int sp)
 
 int merc_hom_dead(struct homun_data *hd, struct block_list *src)
 {
-	hd->master->homunculus.intimacy -= 100 ;
 	hd->master->homunculus.hp = 0 ;
-	if(hd->master->homunculus.intimacy <= 0) {
+	clif_hominfo(hd->master, 0); // Send dead flag
+	if(!merc_hom_decrease_intimacy(hd, 100)) { // Intimacy was < 100
 		merc_stop_walking(hd, 1);
 		merc_stop_attack(hd);
 		clif_emotion(&hd->master->bl, 23) ;	//omg
@@ -138,7 +139,6 @@ int merc_hom_dead(struct homun_data *hd, struct block_list *src)
 int merc_hom_delete(struct homun_data *hd, int flag)
 {
 	nullpo_retr(0, hd);
-
 	// Delete homunculus
 	if ( flag&1 ) {	//sabbath
 		intif_homunculus_requestdelete(hd->master->homunculus.hom_id) ;
@@ -358,6 +358,35 @@ int merc_hom_gainexp(struct homun_data *hd,int exp)
 	return 0;
 }
 
+// Return then new value
+int merc_hom_increase_intimacy(struct homun_data * hd, unsigned int value)
+{
+	if (hd->master->homunculus.intimacy + value <= 100000)
+	{
+		hd->master->homunculus.intimacy += value;
+	}
+	else
+	{
+		hd->master->homunculus.intimacy = 100000;
+	}
+	return hd->master->homunculus.intimacy;
+}
+
+// Return 0 if decrease fails or intimacy became 0 else the new value
+int merc_hom_decrease_intimacy(struct homun_data * hd, unsigned int value)
+{
+	if (hd->master->homunculus.intimacy >= value)
+	{
+		hd->master->homunculus.intimacy -= value;
+	}
+	else
+	{
+		hd->master->homunculus.intimacy = 0;
+	}
+
+	return hd->master->homunculus.intimacy;
+}
+
 int merc_hom_heal(struct homun_data *hd,int hp,int sp)
 {
 	nullpo_retr(0, hd);
@@ -469,6 +498,8 @@ int merc_natural_heal(int tid,unsigned int tick,int id,int data)
 
 	nullpo_retr(0, sd);
 	
+	sd->hd->natural_heal_timer = -1;
+
 	if(sd->homunculus.vaporize)
 		return 1;
 
@@ -573,7 +604,7 @@ int merc_menu(struct map_session_data *sd,int menunum)
 
 int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
 {
-	int i, k, intimacy, emotion;
+	int i, k, emotion;
 
 	if(hd->master->homunculus.vaporize)
 		return 1 ;
@@ -587,28 +618,22 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
 	pc_delitem(sd,i,1,0);
 
 	if ( hd->master->homunculus.hunger >= 91 ) {
-		intimacy = -50;
+		merc_hom_decrease_intimacy(hd, 50);
 		emotion = 16;
 	} else if ( hd->master->homunculus.hunger >= 76 ) {
-		intimacy = -30;
+		merc_hom_decrease_intimacy(hd, 5);
 		emotion = 19;
 	} else if ( hd->master->homunculus.hunger >= 26 ) {
-		intimacy = 80;
+		merc_hom_increase_intimacy(hd, 75);
 		emotion = 2;
 	} else if ( hd->master->homunculus.hunger >= 11 ) {
-		intimacy = 100;
+		merc_hom_increase_intimacy(hd, 100);
 		emotion = 2;
 	} else {
-		intimacy = 50;
+		merc_hom_increase_intimacy(hd, 25);
 		emotion = 2;
 	}
-	hd->master->homunculus.intimacy += intimacy;
-	if(hd->master->homunculus.intimacy < 0)
-		hd->master->homunculus.intimacy = 0;
-	if(hd->master->homunculus.intimacy > 100000)
-		hd->master->homunculus.intimacy = 100000;
 
-	//emotion = 5 ; // FIXME: why the code above and now always set emotion to Thanks? 
 	hd->master->homunculus.hunger += 10;	//dunno increase value for each food
 	if(hd->master->homunculus.hunger > 100)
 		hd->master->homunculus.hunger = 100;
@@ -617,14 +642,17 @@ int merc_hom_food(struct map_session_data *sd, struct homun_data *hd)
 	clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
 	clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100);
 	clif_hom_food(sd,hd->homunculusDB->foodID,1);
-
-	if(hd->master->homunculus.intimacy == 0) {
+       	
+	// Too much food :/
+	if(hd->master->homunculus.intimacy == 0) {  
 		merc_stop_walking(hd, 1);
 		merc_stop_attack(hd);
-		clif_emotion(&hd->master->bl, 23) ;	//omg
-		merc_hom_delete(hd,1) ;
-	}
-
+		// Send homunculus_dead to client
+		sd->homunculus.hp = 0;
+		clif_hominfo(sd, 0);
+		merc_hom_delete(hd,1);
+		clif_emotion(&hd->master->bl, 23);     //omg  
+  	}  
 	return 0;
 }
 
@@ -646,37 +674,38 @@ static int merc_hom_hungry(int tid,unsigned int tick,int id,int data)
 			ShowError("merc_hom_hungry_timer %d != %d\n",hd->hungry_timer,tid);
 		return 0 ;
 	}
+
+	hd->hungry_timer = -1;
+	
 	hd->master->homunculus.hunger-- ;
-	if(hd->master->homunculus.hunger >= 0 && hd->master->homunculus.hunger <= 10) {
+	if(hd->master->homunculus.hunger <= 10) {
 		clif_emotion(&hd->bl, 6) ;	//an
-	}
-	if(hd->master->homunculus.hunger == 25) {
+	} else if(hd->master->homunculus.hunger == 25) {
 		clif_emotion(&hd->bl, 20) ;	//hmm
-	}
-	if(hd->master->homunculus.hunger == 75) {
+	} else if(hd->master->homunculus.hunger == 75) {
 		clif_emotion(&hd->bl, 33) ;	//ok
 	}  
+	
 	if(hd->master->homunculus.hunger < 0) {
 		hd->master->homunculus.hunger = 0;
-		hd->master->homunculus.intimacy -= 100;
-		if(hd->master->homunculus.intimacy < 0)
-			hd->master->homunculus.intimacy = 0;
-		clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100);
-		if(hd->master->homunculus.intimacy == 0) {
+		// Delete the homunculus if intimacy <= 100
+		if ( !merc_hom_decrease_intimacy(hd, 100) ) {
 			merc_stop_walking(hd, 1);
 			merc_stop_attack(hd);
+			// Send homunculus_dead to client
+			sd->homunculus.hp = 0;
+			clif_hominfo(sd, 0);
+			merc_hom_delete(hd,1);
 			clif_emotion(&hd->master->bl, 23) ;	//omg
-			merc_hom_delete(hd,1) ;
+			return 0 ;
+		} else {
+			clif_send_homdata(sd,SP_INTIMATE,sd->homunculus.intimacy / 100);
 		}
-		return 0 ;
-	} else {
-		clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
-	
-		hd->hungry_timer = add_timer(tick+hd->homunculusDB->hungryDelay,merc_hom_hungry,sd->bl.id,0); //simple Fix albator
-		return 1 ;
 	}
 
-
+	clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
+	hd->hungry_timer = add_timer(tick+hd->homunculusDB->hungryDelay,merc_hom_hungry,sd->bl.id,0); //simple Fix albator
+	return 0;
 }
 
 int merc_hom_hungry_timer_delete(struct homun_data *hd)

+ 2 - 0
src/map/mercenary.h

@@ -76,3 +76,5 @@ int merc_natural_heal_timer_delete(struct homun_data *hd);
 #define merc_stop_walking(hd, type) { if((hd)->ud.walktimer != -1) unit_stop_walking(&(hd)->bl, type); }
 #define merc_stop_attack(hd) { if((hd)->ud.attacktimer != -1) unit_stop_attack(&(hd)->bl); hd->ud.target = 0; }
 int read_homunculusdb(void);
+int merc_hom_increase_intimacy(struct homun_data * hd, unsigned int value);
+int merc_hom_decrease_intimacy(struct homun_data * hd, unsigned int value);

+ 4 - 1
src/map/mob.c

@@ -1893,8 +1893,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 						pc_getzeny((struct map_session_data *)tmpbl[i], zeny);
 					break ;
 				case BL_HOMUNCULUS:
-					if(base_exp)
+					if(base_exp) {
 						merc_hom_gainexp((struct homun_data *)tmpbl[i], base_exp);
+						//homunculus give base_exp to master
+						pc_gainexp(((struct homun_data *)tmpbl[i])->master, &md->bl, base_exp,0);
+					}
 					if(zeny)	//homunculus give zeny to master
 						pc_getzeny((struct map_session_data *)((struct homun_data *)tmpbl[i])->master, zeny);
 					break ;

+ 31 - 33
src/map/skill.c

@@ -5546,56 +5546,54 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 	case AM_CALLHOMUN:	//[orn]
 	{
 		int i = 0;
-		if (sd && (sd->status.hom_id == 0 || sd->homunculus.vaporize == 1)) {
-			if (sd->status.hom_id == 0) {
-				i = pc_search_inventory(sd,7142);
-				if(i < 0) {
-					clif_skill_fail(sd,skillid,0,0);
-					break ;
+		if (sd)
+		{
+			if ((sd->status.hom_id == 0 || sd->homunculus.vaporize == 1)) {
+				if (sd->status.hom_id == 0) {
+					i = pc_search_inventory(sd,7142);
+					if(i < 0) {
+						clif_skill_fail(sd,skillid,0,0);
+						break ;
+					}
+					pc_delitem(sd,i,1,0);
 				}
-				pc_delitem(sd,i,1,0);
+				if (merc_call_homunculus(sd))
+					break;
 			}
-			if (merc_call_homunculus(sd))
-				break;
+			clif_skill_fail(sd,skillid,0,0);
 		}
-		
-		clif_skill_fail(sd,skillid,0,0);
 		break;
 	}
 	case AM_REST:	//[orn]
 	{
-		if (sd && sd->hd && ( sd->hd->battle_status.hp >= (sd->hd->battle_status.max_hp * 80 / 100 ) ) ) {
-			sd->homunculus.vaporize = 1;
-			clif_hominfo(sd, 0);
-			merc_hom_delete(sd->hd, 0) ;
-		} else if ( sd ) 
+		if (sd)
 		{
+			if (sd->hd && ( sd->hd->battle_status.hp >= (sd->hd->battle_status.max_hp * 80 / 100 ) ) ) {
+				sd->homunculus.vaporize = 1;
+				clif_hominfo(sd, 0);
+				merc_hom_delete(sd->hd, 0) ;
+			}
 			clif_skill_fail(sd,skillid,0,0);
 		}
-		
 		break;
 	}
 	case AM_RESURRECTHOMUN:	//[orn]
 	{
-		if ( sd && sd->status.hom_id ) {
-			if( map_flag_gvg(bl->m) )
-			{	//No reviving in WoE grounds!
-				clif_skill_fail(sd,skillid,0,0);
-				break;
-			}
-			if ( sd->homunculus.hp == 0 ) {
-				int per = 10 * skilllv;
-	
-				if (merc_hom_revive(sd, per) )
-				{
-					clif_skill_nodamage(src,&sd->hd->bl,AM_RESURRECTHOMUN,skilllv,1);
-				} else {
+		if (sd)
+		{
+			if (sd->status.hom_id && sd->homunculus.hp == 0)
+			{
+				if( map_flag_gvg(bl->m) )
+				{	//No reviving in WoE grounds!
 					clif_skill_fail(sd,skillid,0,0);
+					break;
 				}
-			} else {	
+				if (merc_hom_revive(sd, 10 * skilllv) )
+					clif_skill_nodamage(src,&sd->hd->bl,AM_RESURRECTHOMUN,skilllv,1);
+				else
+					clif_skill_fail(sd,skillid,0,0);
+			} else
 				clif_skill_fail(sd,skillid,0,0);
-			}
-
 		}
 		break;
 	}