瀏覽代碼

- Cleaned up some of the pet related @/# commands, same for some script commands.
- Moved s_pet structure from map_session_data to pet_data, this enabled the removal of a few redundant values in the pet_data structure (name, class, equip)
- Pet offensive skills who's inf value is self will be casted on the pet now (for stuff like Grand Cross)


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

skotlex 19 年之前
父節點
當前提交
ee8298bb8a
共有 11 個文件被更改,包括 255 次插入254 次删除
  1. 7 0
      Changelog-Trunk.txt
  2. 34 31
      src/map/atcommand.c
  3. 41 39
      src/map/charcommand.c
  4. 13 10
      src/map/clif.c
  5. 1 4
      src/map/map.h
  6. 9 8
      src/map/pc.c
  7. 86 94
      src/map/pet.c
  8. 3 3
      src/map/pet.h
  9. 37 36
      src/map/script.c
  10. 15 16
      src/map/status.c
  11. 9 13
      src/map/unit.c

+ 7 - 0
Changelog-Trunk.txt

@@ -4,6 +4,13 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2006/08/15
+	* Moved s_pet structure from map_session_data to pet_data, this enabled the
+	  removal of a few redundant values in the pet_data structure (name, class,
+	  equip) [Skotlex]
+	* Cleaned up some of the pet related @/# commands, same for some script
+	  commands. [Skotlex]
+	* Pet offensive skills who's inf value is self will be casted on the pet
+	  now (for stuff like Grand Cross) [Skotlex]
 	* Added homun saving/loading support to char-TXT. Note that this is
 	  completely untested, so it may be as good as broken. [Skotlex]
 	* Added a crash-fix on status_calc_bl_sub_homun to abort in case the homun

+ 34 - 31
src/map/atcommand.c

@@ -2065,7 +2065,7 @@ int atcommand_save(
 
 	pc_setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y);
 	if (sd->status.pet_id > 0 && sd->pd)
-		intif_save_petdata(sd->status.account_id, &sd->pet);
+		intif_save_petdata(sd->status.account_id, &sd->pd->pet);
 
 	chrif_save(sd,0);
 	
@@ -4427,6 +4427,7 @@ int atcommand_petfriendly(
 	const char* command, const char* message)
 {
 	int friendly;
+	struct pet_data *pd;
 	nullpo_retr(-1, sd);
 
 	if (!message || !*message || (friendly = atoi(message)) < 0) {
@@ -4434,7 +4435,8 @@ int atcommand_petfriendly(
 		return -1;
 	}
 
-	if (!sd->pd) {
+	pd = sd->pd;
+	if (!pd) {
 		clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
 		return -1;
 	}
@@ -4445,11 +4447,11 @@ int atcommand_petfriendly(
 		return -1;
 	}
 	
-	if (friendly == sd->pet.intimate) {
+	if (friendly == pd->pet.intimate) {
 		clif_displaymessage(fd, msg_txt(183)); // Pet friendly is already the good value.
 		return -1;
 	}
-	sd->pet.intimate = friendly;
+	pd->pet.intimate = friendly;
 	clif_send_petstatus(sd);
 	clif_displaymessage(fd, msg_txt(182)); // Pet friendly value changed!
 	return 0;
@@ -4464,6 +4466,7 @@ int atcommand_pethungry(
 	const char* command, const char* message)
 {
 	int hungry;
+	struct pet_data *pd;
 	nullpo_retr(-1, sd);
 
 	if (!message || !*message || (hungry = atoi(message)) < 0) {
@@ -4471,24 +4474,23 @@ int atcommand_pethungry(
 		return -1;
 	}
 
-	if (sd->status.pet_id > 0 && sd->pd) {
-		if (hungry >= 0 && hungry <= 100) {
-			if (hungry != sd->pet.hungry) {
-				sd->pet.hungry = hungry;
-				clif_send_petstatus(sd);
-				clif_displaymessage(fd, msg_txt(185)); // Pet hungry value changed!
-			} else {
-				clif_displaymessage(fd, msg_txt(186)); // Pet hungry is already the good value.
-				return -1;
-			}
-		} else {
-			clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
-			return -1;
-		}
-	} else {
+	pd = sd->pd;
+	if (!sd->status.pet_id || !pd) {
 		clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
 		return -1;
 	}
+	if (hungry < 0 || hungry > 100) {
+		clif_displaymessage(fd, msg_txt(37)); // An invalid number was specified.
+		return -1;
+	}
+	if (hungry == pd->pet.hungry) {
+		clif_displaymessage(fd, msg_txt(186)); // Pet hungry is already the good value.
+		return -1;
+	}
+
+	pd->pet.hungry = hungry;
+	clif_send_petstatus(sd);
+	clif_displaymessage(fd, msg_txt(185)); // Pet hungry value changed!
 
 	return 0;
 }
@@ -4501,21 +4503,22 @@ int atcommand_petrename(
 	const int fd, struct map_session_data* sd,
 	const char* command, const char* message)
 {
+	struct pet_data *pd;
 	nullpo_retr(-1, sd);
-	if (sd->status.pet_id > 0 && sd->pd) {
-		if (sd->pet.rename_flag != 0) {
-			sd->pet.rename_flag = 0;
-			intif_save_petdata(sd->status.account_id, &sd->pet);
-			clif_send_petstatus(sd);
-			clif_displaymessage(fd, msg_txt(187)); // You can now rename your pet.
-		} else {
-			clif_displaymessage(fd, msg_txt(188)); // You can already rename your pet.
-			return -1;
-		}
-	} else {
+	if (!sd->status.pet_id || !sd->pd) {
 		clif_displaymessage(fd, msg_txt(184)); // Sorry, but you have no pet.
 		return -1;
 	}
+	pd = sd->pd;
+	if (pd->pet.rename_flag) {
+		clif_displaymessage(fd, msg_txt(188)); // You can already rename your pet.
+		return -1;
+	}
+
+	pd->pet.rename_flag = 0;
+	intif_save_petdata(sd->status.account_id, &pd->pet);
+	clif_send_petstatus(sd);
+	clif_displaymessage(fd, msg_txt(187)); // You can now rename your pet.
 
 	return 0;
 }
@@ -8466,7 +8469,7 @@ atcommand_pettalk(
 	if (sscanf(message, "%99[^\n]", mes) < 1)
 		return -1;
 
-	snprintf(temp, sizeof temp ,"%s : %s",sd->pet.name,mes);
+	snprintf(temp, sizeof temp ,"%s : %s",pd->pet.name,mes);
 	clif_message(&pd->bl, temp);
 
 	return 0;

+ 41 - 39
src/map/charcommand.c

@@ -362,6 +362,7 @@ int charcommand_petrename(
 {
 	char character[NAME_LENGTH];
 	struct map_session_data *pl_sd;
+	struct pet_data *pd;
 
 	memset(character, '\0', sizeof(character));
 
@@ -370,26 +371,26 @@ int charcommand_petrename(
 		return -1;
 	}
 
-	if ((pl_sd = map_nick2sd(character)) != NULL) {
-		if (pl_sd->status.pet_id > 0 && pl_sd->pd) {
-			if (pl_sd->pet.rename_flag != 0) {
-				pl_sd->pet.rename_flag = 0;
-				intif_save_petdata(pl_sd->status.account_id, &pl_sd->pet);
-				clif_send_petstatus(pl_sd);
-				clif_displaymessage(fd, msg_table[189]); // This player can now rename his/her pet.
-			} else {
-				clif_displaymessage(fd, msg_table[190]); // This player can already rename his/her pet.
-				return -1;
-			}
-		} else {
-			clif_displaymessage(fd, msg_table[191]); // Sorry, but this player has no pet.
-			return -1;
-		}
-	} else {
+	if ((pl_sd = map_nick2sd(character)) == NULL) {
 		clif_displaymessage(fd, msg_txt(3)); // Character not found.
 		return -1;
 	}
 
+	if (!pl_sd->status.pet_id || !pl_sd->pd) {
+		clif_displaymessage(fd, msg_table[191]); // Sorry, but this player has no pet.
+		return -1;
+	}
+
+	pd = pl_sd->pd;
+
+	if (pd->pet.rename_flag) {
+		clif_displaymessage(fd, msg_table[190]); // This player can already rename his/her pet.
+		return -1;
+	}
+	pd->pet.rename_flag = 0;
+	intif_save_petdata(pl_sd->status.account_id, &pd->pet);
+	clif_send_petstatus(pl_sd);
+	clif_displaymessage(fd, msg_table[189]); // This player can now rename his/her pet.
 	return 0;
 }
 
@@ -403,9 +404,9 @@ int charcommand_petfriendly(
 	const char* command, const char* message)
 {
 	int friendly = 0;
-	int t = 0;
 	char character[NAME_LENGTH];
 	struct map_session_data *pl_sd;
+	struct pet_data *pd;
 
 	memset(character, '\0', sizeof(character));
 	if (!message || !*message || sscanf(message,"%d %23s",&friendly,character) < 2) {
@@ -414,32 +415,33 @@ int charcommand_petfriendly(
 		return -1;
 	}
 
-	if (((pl_sd = map_nick2sd(character)) != NULL) && pc_isGM(sd)>pc_isGM(pl_sd)) {
-		if (pl_sd->status.pet_id > 0 && pl_sd->pd) {
-			if (friendly >= 0 && friendly <= 1000) {
-				if (friendly != pl_sd->pet.intimate) {
-					t = pl_sd->pet.intimate;
-					pl_sd->pet.intimate = friendly;
-					clif_send_petstatus(pl_sd);
-					clif_pet_emotion(pl_sd->pd,0);
-					clif_displaymessage(pl_sd->fd, msg_table[182]); // Pet friendly value changed!
-					clif_displaymessage(sd->fd, msg_table[182]); // Pet friendly value changed!
-				} else {
-					clif_displaymessage(fd, msg_table[183]); // Pet friendly is already the good value.
-					return -1;
-				}
-			} else {
-				clif_displaymessage(fd, msg_table[37]); // An invalid number was specified.
-				return -1;
-			}
-		} else {
-			return -1;
-		}
-	} else {
+	if (((pl_sd = map_nick2sd(character)) == NULL) ||
+		pc_isGM(sd)<pc_isGM(pl_sd)) {
 		clif_displaymessage(fd, msg_txt(3)); // Character not found.
 		return -1;
 	}
 
+	if (!pl_sd->status.pet_id  || !pl_sd->pd) {
+		clif_displaymessage(fd, msg_table[191]); // Sorry, but this player has no pet.
+		return -1;
+	}
+
+	if (friendly < 0 || friendly > 1000) {
+		clif_displaymessage(fd, msg_table[37]); // An invalid number was specified.
+		return -1;
+	}
+
+	pd = pl_sd->pd;
+	if (friendly == pd->pet.intimate) {
+		clif_displaymessage(fd, msg_table[183]); // Pet friendly is already the good value.
+		return -1;
+	}
+	
+	pd->pet.intimate = friendly;
+	clif_send_petstatus(pl_sd);
+	clif_pet_emotion(pd,0);
+	clif_displaymessage(pl_sd->fd, msg_table[182]); // Pet friendly value changed!
+	clif_displaymessage(sd->fd, msg_table[182]); // Pet friendly value changed!
 	return 0;
 }
 

+ 13 - 10
src/map/clif.c

@@ -6350,18 +6350,21 @@ int clif_send_petdata(struct map_session_data *sd,int type,int param)
 int clif_send_petstatus(struct map_session_data *sd)
 {
 	int fd;
+	struct s_pet *pet;
 
 	nullpo_retr(0, sd);
+	nullpo_retr(0, sd->pd);
 
 	fd=sd->fd;
+	pet = &sd->pd->pet;
 	WFIFOHEAD(fd,packet_len_table[0x1a2]);
 	WFIFOW(fd,0)=0x1a2;
-	memcpy(WFIFOP(fd,2),sd->pet.name,NAME_LENGTH);
-	WFIFOB(fd,26)=(battle_config.pet_rename == 1)? 0:sd->pet.rename_flag;
-	WFIFOW(fd,27)=sd->pet.level;
-	WFIFOW(fd,29)=sd->pet.hungry;
-	WFIFOW(fd,31)=sd->pet.intimate;
-	WFIFOW(fd,33)=sd->pet.equip;
+	memcpy(WFIFOP(fd,2),pet->name,NAME_LENGTH);
+	WFIFOB(fd,26)=(battle_config.pet_rename == 1)? 0:pet->rename_flag;
+	WFIFOW(fd,27)=pet->level;
+	WFIFOW(fd,29)=pet->hungry;
+	WFIFOW(fd,31)=pet->intimate;
+	WFIFOW(fd,33)=pet->equip;
 	WFIFOSET(fd,packet_len_table[0x1a2]);
 
 	return 0;
@@ -6385,7 +6388,7 @@ int clif_pet_emotion(struct pet_data *pd,int param)
 		if(pd->petDB->talk_convert_class < 0)
 			return 0;
 		else if(pd->petDB->talk_convert_class > 0) {
-			param -= (pd->class_ - 100)*100;
+			param -= (pd->pet.class_ - 100)*100;
 			param += (pd->petDB->talk_convert_class - 100)*100;
 		}
 	}
@@ -7824,7 +7827,7 @@ int clif_charnameack (int fd, struct block_list *bl)
 		memcpy(WBUFP(buf,6), ((struct homun_data*)bl)->master->homunculus.name, NAME_LENGTH);
 		break;
 	case BL_PET:
-		memcpy(WBUFP(buf,6), ((struct pet_data*)bl)->name, NAME_LENGTH);
+		memcpy(WBUFP(buf,6), ((struct pet_data*)bl)->pet.name, NAME_LENGTH);
 		break;
 	case BL_NPC:
 		memcpy(WBUFP(buf,6), ((struct npc_data*)bl)->name, NAME_LENGTH);
@@ -8315,8 +8318,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 				sc_start(&sd->bl, SC_KNOWLEDGE, 100, i, skill_get_time(SG_KNOWLEDGE, i));
 		}
 
-		if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 900)
-			clif_pet_emotion(sd->pd,(sd->pd->class_ - 100)*100 + 50 + pet_hungry_val(sd));
+		if(sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 900)
+			clif_pet_emotion(sd->pd,(sd->pd->pet.class_ - 100)*100 + 50 + pet_hungry_val(sd->pd));
 		//Removed, for some reason chars get stuck on map-change when you send this packet!? [Skotlex]
 		//[LuzZza]
 		//clif_guild_send_onlineinfo(sd);

+ 1 - 4
src/map/map.h

@@ -749,7 +749,6 @@ struct map_session_data {
 	char message[MESSAGE_SIZE];
 	struct vending vending[MAX_VENDING];
 
-	struct s_pet pet;
 	struct pet_data *pd;
 
 	struct s_homunculus homunculus ;	//[orn]
@@ -961,15 +960,13 @@ struct pet_data {
 	struct block_list bl;
 	struct unit_data ud;
 	struct view_data vd;
+	struct s_pet pet;
 	struct status_data status;
 	struct mob_db *db;
 	struct pet_db *petDB;
 	int pet_hungry_timer;
 	int target_id;
 	short n;
-	short class_;
-	short equip;
-	char name[NAME_LENGTH];
 	struct {
 		unsigned skillbonus : 1;
 	} state;

+ 9 - 8
src/map/pc.c

@@ -3300,12 +3300,12 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
 				sd->state.waitingdisconnect=1;
 				pc_clean_skilltree(sd);
 				if(sd->status.pet_id > 0 && sd->pd) {
+					intif_save_petdata(sd->status.account_id,&sd->pd->pet);
 					unit_remove_map(&sd->pd->bl, clrtype);
-					intif_save_petdata(sd->status.account_id,&sd->pet);
 				}
 				if(sd->status.hom_id > 0 && sd->hd) {	//orn
-					unit_remove_map(&sd->hd->bl, clrtype);
 					intif_homunculus_requestsave(sd->status.account_id, &sd->homunculus);
+					unit_remove_map(&sd->hd->bl, clrtype);
 				}
 				chrif_save(sd,2);
 				chrif_changemapserver(sd, mapindex, x, y, ip, (short)port);
@@ -3351,7 +3351,7 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
 	sd->bl.x = sd->ud.to_x = x;
 	sd->bl.y = sd->ud.to_y = y;
 
-	if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0) {
+	if(sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0) {
 		sd->pd->bl.m = m;
 		sd->pd->bl.x = sd->pd->ud.to_x = x;
 		sd->pd->bl.y = sd->pd->ud.to_y = y;
@@ -4773,11 +4773,12 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 
 	if(sd->status.pet_id > 0 && sd->pd)
 	{
+		struct s_pet *pet = &sd->pd->pet;
 		if(!map[sd->bl.m].flag.nopenalty){
-			sd->pet.intimate -= sd->pd->petDB->die;
-			if(sd->pet.intimate < 0)
-				sd->pet.intimate = 0;
-			clif_send_petdata(sd,1,sd->pet.intimate);
+			pet->intimate -= sd->pd->petDB->die;
+			if(pet->intimate < 0)
+				pet->intimate = 0;
+			clif_send_petdata(sd,1,pet->intimate);
 		}
 		if(sd->pd->target_id) // Unlock all targets...
 			pet_unlocktarget(sd->pd);
@@ -7149,7 +7150,7 @@ static int pc_autosave_sub(DBKey key,void * data,va_list app)
 
 	// pet
 	if(sd->status.pet_id > 0 && sd->pd)
-		intif_save_petdata(sd->status.account_id,&sd->pet);
+		intif_save_petdata(sd->status.account_id,&sd->pd->pet);
 
 	if(sd->state.finalsave)
   	{	//Save ack hasn't returned from char-server yet? Retry.

+ 86 - 94
src/map/pet.c

@@ -37,19 +37,17 @@ static struct eri *item_drop_list_ers;
 static int dirx[8]={0,-1,-1,-1,0,1,1,1};
 static int diry[8]={1,1,0,-1,-1,-1,0,1};
 
-int pet_hungry_val(struct map_session_data *sd)
+int pet_hungry_val(struct pet_data *pd)
 {
-	nullpo_retr(0, sd);
-
-	Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); 
+	nullpo_retr(0, pd);
 
-	if(sd->pet.hungry > 90)
+	if(pd->pet.hungry > 90)
 		return 4;
-	else if(sd->pet.hungry > 75)
+	else if(pd->pet.hungry > 75)
 		return 3;
-	else if(sd->pet.hungry > 25)
+	else if(pd->pet.hungry > 25)
 		return 2;
-	else if(sd->pet.hungry > 10)
+	else if(pd->pet.hungry > 10)
 		return 1;
 	else
 		return 0;
@@ -139,25 +137,27 @@ int pet_unlocktarget(struct pet_data *pd)
 int pet_attackskill(struct pet_data *pd, int target_id)
 {
 	struct block_list *bl;
+	int inf;
 
 	if (!battle_config.pet_status_support || !pd->a_skill || 
-		(battle_config.pet_equip_required && !pd->equip))
+		(battle_config.pet_equip_required && !pd->pet.equip))
 		return 0;
 
 	if (DIFF_TICK(pd->ud.canact_tick, gettick()) > 0)
 		return 0;
 	
-	if (rand()%100 < (pd->a_skill->rate +pd->msd->pet.intimate*pd->a_skill->bonusrate/1000))
+	if (rand()%100 < (pd->a_skill->rate +pd->pet.intimate*pd->a_skill->bonusrate/1000))
 	{	//Skotlex: Use pet's skill 
 		bl=map_id2bl(target_id);
 		if(bl == NULL || pd->bl.m != bl->m || bl->prev == NULL || status_isdead(bl) ||
 			!check_distance_bl(&pd->bl, bl, pd->db->range3))
 			return 0;
 
-		if (skill_get_inf(pd->a_skill->id) & INF_GROUND_SKILL)
+		inf = skill_get_inf(pd->a_skill->id);
+		if (inf & INF_GROUND_SKILL)
 			unit_skilluse_pos(&pd->bl, bl->x, bl->y, pd->a_skill->id, pd->a_skill->lv);
-		else
-			unit_skilluse_id(&pd->bl, bl->id, pd->a_skill->id, pd->a_skill->lv);
+		else	//Offensive self skill? Could be stuff like GX.
+			unit_skilluse_id(&pd->bl,(inf&INF_SELF_SKILL?pd->bl.id:bl->id), pd->a_skill->id, pd->a_skill->lv);
 		return 1; //Skill invoked.
 	}
 	return 0;
@@ -173,9 +173,9 @@ int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type)
 	Assert((pd->msd == 0) || (pd->msd->pd == pd));
 
 	if(bl == NULL || bl->type != BL_MOB || bl->prev == NULL ||
-		sd->pet.intimate < battle_config.pet_support_min_friendly ||
-		sd->pet.hungry < 1 ||
-		pd->class_ == status_get_class(bl))
+		pd->pet.intimate < battle_config.pet_support_min_friendly ||
+		pd->pet.hungry < 1 ||
+		pd->pet.class_ == status_get_class(bl))
 		return 0;
 
 	if(pd->bl.m != bl->m ||
@@ -216,7 +216,7 @@ int pet_sc_check(struct map_session_data *sd, int type)
 	pd = sd->pd;
 
 	if (pd == NULL ||
-		(battle_config.pet_equip_required && pd->equip == 0) ||
+		(battle_config.pet_equip_required && pd->pet.equip == 0) ||
 		pd->recovery == NULL ||
 		pd->recovery->timer != -1 ||
 		pd->recovery->type != type)
@@ -248,23 +248,23 @@ static int pet_hungry(int tid,unsigned int tick,int id,int data)
 	}
 	pd->pet_hungry_timer = -1;
 
-	if (sd->pet.intimate <= 0)
+	if (pd->pet.intimate <= 0)
 		return 1; //You lost the pet already, the rest is irrelevant.
 	
-	sd->pet.hungry--;
-	t = sd->pet.intimate;
-	if(sd->pet.hungry < 0) {
+	pd->pet.hungry--;
+	t = pd->pet.intimate;
+	if(pd->pet.hungry < 0) {
 		pet_stop_attack(pd);
-		sd->pet.hungry = 0;
-		sd->pet.intimate -= battle_config.pet_hungry_friendly_decrease;
-		if(sd->pet.intimate <= 0) {
-			sd->pet.intimate = 0;
+		pd->pet.hungry = 0;
+		pd->pet.intimate -= battle_config.pet_hungry_friendly_decrease;
+		if(pd->pet.intimate <= 0) {
+			pd->pet.intimate = 0;
 			pd->status.speed = pd->db->status.speed;
 		}
 		status_calc_pet(pd, 0);
-		clif_send_petdata(sd,1,sd->pet.intimate);
+		clif_send_petdata(sd,1,pd->pet.intimate);
 	}
-	clif_send_petdata(sd,2,sd->pet.hungry);
+	clif_send_petdata(sd,2,pd->pet.hungry);
 
 	if(battle_config.pet_hungry_delay_rate != 100)
 		interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100;
@@ -327,9 +327,9 @@ static int pet_performance(struct map_session_data *sd, struct pet_data *pd)
 {
 	int val;
 
-	if (sd->pet.intimate > 900)
+	if (pd->pet.intimate > 900)
 		val = (pd->petDB->s_perfor > 0)? 4:3;
-	else if(sd->pet.intimate > 750)
+	else if(pd->pet.intimate > 750)
 		val = 2;
 	else
 		val = 1;
@@ -350,27 +350,27 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
 	tmp_item.nameid = pd->petDB->EggID;
 	tmp_item.identify = 1;
 	tmp_item.card[0] = CARD0_PET;
-	tmp_item.card[1] = GetWord(sd->pet.pet_id,0);
-	tmp_item.card[2] = GetWord(sd->pet.pet_id,1);
-	tmp_item.card[3] = sd->pet.rename_flag;
+	tmp_item.card[1] = GetWord(pd->pet.pet_id,0);
+	tmp_item.card[2] = GetWord(pd->pet.pet_id,1);
+	tmp_item.card[3] = pd->pet.rename_flag;
 	if((flag = pc_additem(sd,&tmp_item,1))) {
 		clif_additem(sd,0,0,flag);
 		map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
 	}
-	sd->pet.incuvate = 1;
-	intif_save_petdata(sd->status.account_id,&sd->pet);
+	pd->pet.incuvate = 1;
+	//No need, pet is saved on unit_free below.
+	//intif_save_petdata(sd->status.account_id,&pd->pet);
 	if(pd->state.skillbonus) {
 		pd->state.skillbonus = 0;
 		status_calc_pc(sd,0);
 	}
 	unit_free(&pd->bl);
-	memset(&sd->pet, 0, sizeof(struct s_pet));
 	sd->status.pet_id = 0;
 
 	return 1;
 }
 
-int pet_data_init(struct map_session_data *sd)
+int pet_data_init(struct map_session_data *sd, struct s_pet *pet)
 {
 	struct pet_data *pd;
 	int i=0,interval=0;
@@ -379,29 +379,30 @@ int pet_data_init(struct map_session_data *sd)
 
 	Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); 
 
-	if(sd->status.account_id != sd->pet.account_id || sd->status.char_id != sd->pet.char_id) {
+	if(sd->status.account_id != pet->account_id || sd->status.char_id != pet->char_id) {
 		sd->status.pet_id = 0;
 		return 1;
 	}
-	if (sd->status.pet_id != sd->pet.pet_id) {
+	if (sd->status.pet_id != pet->pet_id) {
 		if (sd->status.pet_id) {
 			//Wrong pet?? Set incuvate to no and send it back for saving.
-			sd->pet.incuvate = 1;
-			intif_save_petdata(sd->status.account_id,&sd->pet);
+			pet->incuvate = 1;
+			intif_save_petdata(sd->status.account_id,pet);
 			sd->status.pet_id = 0;
 			return 1;
 		}
 		//The pet_id value was lost? odd... restore it.
-		sd->status.pet_id = sd->pet.pet_id;
+		sd->status.pet_id = pet->pet_id;
 	}
 	
-	i = search_petDB_index(sd->pet.class_,PET_CLASS);
+	i = search_petDB_index(pet->class_,PET_CLASS);
 	if(i < 0) {
 		sd->status.pet_id = 0;
 		return 1;
 	}
 	sd->pd = pd = (struct pet_data *)aCalloc(1,sizeof(struct pet_data));
 	pd->petDB = &pet_db[i];
+	memcpy(&pd->pet, pet, sizeof(pet));
 	pd->bl.m = sd->bl.m;
 	pd->bl.x = sd->bl.x;
 	pd->bl.y = sd->bl.y;
@@ -409,14 +410,11 @@ int pet_data_init(struct map_session_data *sd)
 	pd->bl.x = pd->ud.to_x;
 	pd->bl.y = pd->ud.to_y;
 	pd->bl.id = npc_get_new_npc_id();
-	memcpy(pd->name, sd->pet.name, NAME_LENGTH-1);
-	pd->class_ = sd->pet.class_;
-	pd->db = mob_db(pd->class_);
-	pd->equip = sd->pet.equip;
+	pd->db = mob_db(pd->pet.class_);
 	pd->bl.subtype = MONS;
 	pd->bl.type = BL_PET;
 	pd->msd = sd;
-	status_set_viewdata(&pd->bl, pd->class_);
+	status_set_viewdata(&pd->bl, pd->pet.class_);
 	unit_dataset(&pd->bl);
 	pd->ud.dir = sd->ud.dir;
 	pd->last_thinktime = gettick();
@@ -440,30 +438,27 @@ int pet_data_init(struct map_session_data *sd)
 	return 0;
 }
 
-int pet_birth_process(struct map_session_data *sd)
+int pet_birth_process(struct map_session_data *sd, struct s_pet *pet)
 {
 	nullpo_retr(1, sd);
 
 	Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); 
 
-	if(sd->status.pet_id && sd->pet.incuvate == 1) {
+	if(sd->status.pet_id && pet->incuvate == 1) {
 		sd->status.pet_id = 0;
 		return 1;
 	}
 
-	sd->pet.incuvate = 0;
-	sd->pet.account_id = sd->status.account_id;
-	sd->pet.char_id = sd->status.char_id;
-	sd->status.pet_id = sd->pet.pet_id;
-	if(pet_data_init(sd)) {
+	pet->incuvate = 0;
+	pet->account_id = sd->status.account_id;
+	pet->char_id = sd->status.char_id;
+	sd->status.pet_id = pet->pet_id;
+	if(pet_data_init(sd, pet)) {
 		sd->status.pet_id = 0;
-		sd->pet.incuvate = 1;
-		sd->pet.account_id = 0;
-		sd->pet.char_id = 0;
 		return 1;
 	}
 
-	intif_save_petdata(sd->status.account_id,&sd->pet);
+	intif_save_petdata(sd->status.account_id,pet);
 	if (save_settings&8)
 		chrif_save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex]
 
@@ -490,8 +485,7 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag)
 		sd->status.pet_id = 0;
 		return 1;
 	}
-	memcpy(&sd->pet,p,sizeof(struct s_pet));
-	if(sd->pet.incuvate == 1) {
+	if(p->incuvate == 1) {
 		int i;
 		//Delete egg from inventory. [Skotlex]
 		for (i = 0; i < MAX_INVENTORY; i++) {
@@ -503,14 +497,12 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag)
 		  	if (battle_config.error_log)
 				ShowError("pet_recv_petdata: Hatching pet (%d:%s) aborted, couldn't find egg in inventory for removal!\n",p->pet_id, p->name);
 			sd->status.pet_id = 0;
-			memset(&sd->pet,0,sizeof(struct s_pet));
-			sd->pet.incuvate = 1;
 			return 1;
 		}
-		if (!pet_birth_process(sd)) //Pet hatched. Delete egg.
+		if (!pet_birth_process(sd,p)) //Pet hatched. Delete egg.
 			pc_delitem(sd,i,1,0);
 	} else {
-		pet_data_init(sd);
+		pet_data_init(sd,p);
 		if(sd->pd && sd->bl.prev != NULL) {
 			map_addblock(&sd->pd->bl);
 			clif_spawn(&sd->pd->bl);
@@ -674,7 +666,7 @@ int pet_menu(struct map_session_data *sd,int menunum)
 		return 1;
 	
 	//You lost the pet already.
-	if(sd->pet.intimate <= 0 || !sd->status.pet_id)
+	if(!sd->status.pet_id || sd->pd->pet.intimate <= 0)
 		return 1;
 	
 	switch(menunum) {
@@ -700,10 +692,11 @@ int pet_menu(struct map_session_data *sd,int menunum)
 int pet_change_name(struct map_session_data *sd,char *name, int flag) //flag 0 = check name, 1 = good name
 {
 	int i;
-	
+	struct pet_data *pd;
 	nullpo_retr(1, sd);
 
-	if((sd->pd == NULL) || (sd->pet.rename_flag == 1 && battle_config.pet_rename == 0))
+	pd = sd->pd;
+	if((pd == NULL) || (pd->pet.rename_flag == 1 && !battle_config.pet_rename))
 		return 1;
 
 	for(i=0;i<NAME_LENGTH && name[i];i++){
@@ -714,14 +707,13 @@ int pet_change_name(struct map_session_data *sd,char *name, int flag) //flag 0 =
 	if (!flag)
 		return intif_rename_pet(sd, name);
 	
-	pet_stop_walking(sd->pd,1);
+	pet_stop_walking(pd,1);
 	
-	memcpy(sd->pet.name, name, NAME_LENGTH-1);
-	memcpy(sd->pd->name, name, NAME_LENGTH-1);
+	memcpy(pd->pet.name, name, NAME_LENGTH-1);
 
-	clif_charnameack (0,&sd->pd->bl);
-	sd->pet.rename_flag = 1;
-	clif_pet_equip(sd->pd);
+	clif_charnameack (0,&pd->bl);
+	pd->pet.rename_flag = 1;
+	clif_pet_equip(pd);
 	clif_send_petstatus(sd);
 
 	return 0;
@@ -738,13 +730,13 @@ int pet_equipitem(struct map_session_data *sd,int index)
 	
 	nameid = sd->status.inventory[index].nameid;
 	
-	if(pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || sd->pet.equip != 0) {
+	if(pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || pd->pet.equip != 0) {
 		clif_equipitemack(sd,0,0,0);
 		return 1;
 	}
 
 	pc_delitem(sd,index,1,0);
-	sd->pet.equip = pd->equip = nameid;
+	pd->pet.equip = nameid;
 	status_set_viewdata(&pd->bl, pd->vd.class_); //Updates view_data.
 	clif_pet_equip(pd);
 	if (battle_config.pet_equip_required)
@@ -769,11 +761,11 @@ static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd)
 	struct item tmp_item;
 	int nameid,flag;
 
-	if(sd->pet.equip == 0)
+	if(pd->pet.equip == 0)
 		return 1;
 
-	nameid = sd->pet.equip;
-	sd->pet.equip = pd->equip = 0;
+	nameid = pd->pet.equip;
+	pd->pet.equip = 0;
 	status_set_viewdata(&pd->bl, pd->vd.class_);
 	clif_pet_equip(pd);
 	memset(&tmp_item,0,sizeof(tmp_item));
@@ -819,34 +811,34 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
 	}
 	pc_delitem(sd,i,1,0);
 
-	if(sd->pet.hungry > 90)
-		sd->pet.intimate -= pd->petDB->r_full;
+	if(pd->pet.hungry > 90)
+		pd->pet.intimate -= pd->petDB->r_full;
 	else {
 		if(battle_config.pet_friendly_rate != 100)
 			k = (pd->petDB->r_hungry * battle_config.pet_friendly_rate)/100;
 		else
 			k = pd->petDB->r_hungry;
-		if(sd->pet.hungry > 75) {
+		if(pd->pet.hungry > 75) {
 			k = k >> 1;
 			if(k <= 0)
 				k = 1;
 		}
-		sd->pet.intimate += k;
+		pd->pet.intimate += k;
 	}
-	if(sd->pet.intimate <= 0) {
-		sd->pet.intimate = 0;
+	if(pd->pet.intimate <= 0) {
+		pd->pet.intimate = 0;
 		pet_stop_attack(pd);
 		pd->status.speed = pd->db->status.speed;
 	}
-	else if(sd->pet.intimate > 1000)
-		sd->pet.intimate = 1000;
+	else if(pd->pet.intimate > 1000)
+		pd->pet.intimate = 1000;
 	status_calc_pet(pd, 0);
-	sd->pet.hungry += pd->petDB->fullness;
-	if(sd->pet.hungry > 100)
-		sd->pet.hungry = 100;
+	pd->pet.hungry += pd->petDB->fullness;
+	if(pd->pet.hungry > 100)
+		pd->pet.hungry = 100;
 
-	clif_send_petdata(sd,2,sd->pet.hungry);
-	clif_send_petdata(sd,1,sd->pet.intimate);
+	clif_send_petdata(sd,2,pd->pet.hungry);
+	clif_send_petdata(sd,1,pd->pet.intimate);
 	clif_pet_food(sd,pd->petDB->FoodID,1);
 
 	return 0;
@@ -875,7 +867,7 @@ static int pet_randomwalk(struct pet_data *pd,unsigned int tick)
 				pd->move_fail_count++;
 				if(pd->move_fail_count>1000){
 					if(battle_config.error_log)
-						ShowWarning("PET cant move. hold position %d, class = %d\n",pd->bl.id,pd->class_);
+						ShowWarning("PET cant move. hold position %d, class = %d\n",pd->bl.id,pd->pet.class_);
 					pd->move_fail_count=0;
 					pd->ud.canmove_tick = tick + 60000;
 					return 0;
@@ -912,7 +904,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns
 	if(pd->ud.walktimer != -1 && pd->ud.walkpath.path_pos <= 3)
 		return 0; //No thinking when you just started to walk.
 
-	if(sd->pet.intimate <= 0) {
+	if(pd->pet.intimate <= 0) {
 		//Pet should just... well, random walk.
 		pet_randomwalk(pd,tick);
 		return 0;
@@ -1137,7 +1129,7 @@ int pet_skill_bonus_timer(int tid,unsigned int tick,int id,int data)
 		timer = pd->bonus->delay*1000;	// the duration until pet bonuses will be reactivated again
 		if (timer <= 0) //Always active bonus
 			timer = MIN_PETTHINKTIME; 
-	} else if (sd->pet.intimate) {
+	} else if (pd->pet.intimate) {
 		pd->state.skillbonus = 1;
 		timer = pd->bonus->duration*1000;	// the duration for pet bonuses to be in effect
 	} else { //Lost pet...

+ 3 - 3
src/map/pet.h

@@ -34,14 +34,14 @@ extern struct pet_db pet_db[MAX_PET_DB];
 enum { PET_CLASS,PET_CATCH,PET_EGG,PET_EQUIP,PET_FOOD };
 
 int pet_create_egg(struct map_session_data *sd, int item_id);
-int pet_hungry_val(struct map_session_data *sd);
+int pet_hungry_val(struct pet_data *pd);
 int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type);
 int pet_unlocktarget(struct pet_data *pd);
 int pet_sc_check(struct map_session_data *sd, int type); //Skotlex
 int search_petDB_index(int key,int type);
 int pet_hungry_timer_delete(struct pet_data *pd);
-int pet_data_init(struct map_session_data *sd);
-int pet_birth_process(struct map_session_data *sd);
+int pet_data_init(struct map_session_data *sd, struct s_pet *pet);
+int pet_birth_process(struct map_session_data *sd, struct s_pet *pet);
 int pet_recv_petdata(int account_id,struct s_pet *p,int flag);
 int pet_select_egg(struct map_session_data *sd,short egg_index);
 int pet_catch_process1(struct map_session_data *sd,int target_class);

+ 37 - 36
src/map/script.c

@@ -9435,7 +9435,7 @@ int buildin_petskillbonus(struct script_state *st)
 		pd->state.skillbonus=0;	// waiting state
 
 	// wait for timer to start
-	if (battle_config.pet_equip_required && pd->equip == 0)
+	if (battle_config.pet_equip_required && pd->pet.equip == 0)
 		pd->bonus->timer=-1;
 	else
 		pd->bonus->timer=add_timer(gettick()+pd->bonus->delay*1000, pet_skill_bonus_timer, sd->bl.id, 0);
@@ -9760,7 +9760,7 @@ int buildin_petheal(struct script_state *st)
 	pd->s_skill->sp=conv_num(st,& (st->stack->stack_data[st->start+5]));
 
 	//Use delay as initial offset to avoid skill/heal exploits
-	if (battle_config.pet_equip_required && pd->equip == 0)
+	if (battle_config.pet_equip_required && pd->pet.equip == 0)
 		pd->s_skill->timer=-1;
 	else
 		pd->s_skill->timer=add_timer(gettick()+pd->s_skill->delay*1000,pet_heal_timer,sd->bl.id,0);
@@ -9850,7 +9850,7 @@ int buildin_petskillsupport(struct script_state *st)
 	pd->s_skill->sp=conv_num(st,& (st->stack->stack_data[st->start+6]));
 
 	//Use delay as initial offset to avoid skill/heal exploits
-	if (battle_config.pet_equip_required && pd->equip == 0)
+	if (battle_config.pet_equip_required && pd->pet.equip == 0)
 		pd->s_skill->timer=-1;
 	else
 		pd->s_skill->timer=add_timer(gettick()+pd->s_skill->delay*1000,pet_skill_support_timer,sd->bl.id,0);
@@ -10055,29 +10055,29 @@ int buildin_recovery(struct script_state *st)
 int buildin_getpetinfo(struct script_state *st)
 {
 	struct map_session_data *sd=script_rid2sd(st);
+	struct pet_data *pd;
 	int type=conv_num(st,& (st->stack->stack_data[st->start+2]));
 
-	if(sd && sd->status.pet_id){
+	if(sd && sd->status.pet_id && sd->pd){
+		pd = sd->pd;
 		switch(type){
 			case 0:
 				push_val(st->stack,C_INT,sd->status.pet_id);
 				break;
 			case 1:
-				push_val(st->stack,C_INT,sd->pet.class_);
+				push_val(st->stack,C_INT,pd->pet.class_);
 				break;
 			case 2:
-				if(sd->pet.name)
-					push_str(st->stack,C_CONSTSTR,(unsigned char *) sd->pet.name);
+				if(pd->pet.name)
+					push_str(st->stack,C_CONSTSTR,(unsigned char *) pd->pet.name);
 				else
 					push_str(st->stack,C_CONSTSTR, (unsigned char *) "null");
 				break;
 			case 3:
-				//if(sd->pet.intimate)
-				push_val(st->stack,C_INT,sd->pet.intimate);
+				push_val(st->stack,C_INT,pd->pet.intimate);
 				break;
 			case 4:
-				//if(sd->pet.hungry)
-				push_val(st->stack,C_INT,sd->pet.hungry);
+				push_val(st->stack,C_INT,pd->pet.hungry);
 				break;
 			default:
 				push_val(st->stack,C_INT,0);
@@ -11288,37 +11288,38 @@ int buildin_getd (struct script_state *st)
 // Pet stat [Lance]
 int buildin_petstat(struct script_state *st){
 	struct map_session_data *sd = NULL;
+	struct pet_data *pd;
 	char *tmp;
 	int flag = conv_num(st, & (st->stack->stack_data[st->start+2]));
 	sd = script_rid2sd(st);
-	if(!sd || !sd->pet.pet_id){
+	if(!sd || !sd->status.pet_id || !sd->pd){
 		if(flag == 2)
 			push_str(st->stack, C_CONSTSTR, "");
 		else
 			push_val(st->stack, C_INT, 0);
+		return 0;
 	}
-	else {
-		switch(flag){
-			case 1:
-				push_val(st->stack, C_INT, (int)sd->pet.class_);
-				break;
-			case 2:
-				tmp = aStrdup(sd->pet.name);
-				push_str(st->stack, C_STR, tmp);
-				break;
-			case 3:
-				push_val(st->stack, C_INT, (int)sd->pet.level);
-				break;
-			case 4:
-				push_val(st->stack, C_INT, (int)sd->pet.hungry);
-				break;
-			case 5:
-				push_val(st->stack, C_INT, (int)sd->pet.intimate);
-				break;
-			default:
-				push_val(st->stack, C_INT, 0);
-				break;
-		}
+	pd = sd->pd;
+	switch(flag){
+		case 1:
+			push_val(st->stack, C_INT, (int)pd->pet.class_);
+			break;
+		case 2:
+			tmp = aStrdup(pd->pet.name);
+			push_str(st->stack, C_STR, tmp);
+			break;
+		case 3:
+			push_val(st->stack, C_INT, (int)pd->pet.level);
+			break;
+		case 4:
+			push_val(st->stack, C_INT, (int)pd->pet.hungry);
+			break;
+		case 5:
+			push_val(st->stack, C_INT, (int)pd->pet.intimate);
+			break;
+		default:
+			push_val(st->stack, C_INT, 0);
+			break;
 	}
 	return 0;
 }
@@ -11681,7 +11682,7 @@ int buildin_rid2name(struct script_state *st){
 				push_str(st->stack,C_CONSTSTR,((struct npc_data *)bl)->exname);
 				break;
 			case BL_PET:
-				push_str(st->stack,C_CONSTSTR,((struct pet_data *)bl)->name);
+				push_str(st->stack,C_CONSTSTR,((struct pet_data *)bl)->pet.name);
 				break;
 			case BL_HOM:
 				push_str(st->stack,C_CONSTSTR,((struct homun_data *)bl)->master->homunculus.name);
@@ -12112,7 +12113,7 @@ int buildin_unittalk(struct script_state *st)
 				memcpy(message, ((TBL_HOM *)bl)->master->homunculus.name, NAME_LENGTH);
 				break;
 			case BL_PET:
-				memcpy(message, ((TBL_PET *)bl)->name, NAME_LENGTH);
+				memcpy(message, ((TBL_PET *)bl)->pet.name, NAME_LENGTH);
 				break;
 			default:
 				strcpy(message, "Unknown");

+ 15 - 16
src/map/status.c

@@ -1361,28 +1361,26 @@ int status_calc_mob(struct mob_data* md, int first)
 //Skotlex: Calculates the stats of the given pet.
 int status_calc_pet(struct pet_data *pd, int first)
 {
-	struct map_session_data *sd;
-	int lv;
 	
 	nullpo_retr(0, pd);
-	sd = pd->msd;
-	if(!sd || sd->status.pet_id == 0 || sd->pd == NULL)
-		return 0;
 
 	if (first) {
 		memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
 		pd->status.speed = pd->petDB->speed;
 	}
 
-	if (battle_config.pet_lv_rate)
+	if (battle_config.pet_lv_rate && pd->msd)
 	{
+		struct map_session_data *sd = pd->msd;
+		int lv;
+
 		lv =sd->status.base_level*battle_config.pet_lv_rate/100;
 		if (lv < 0)
 			lv = 1;
-		if (lv != sd->pet.level || first)
+		if (lv != pd->pet.level || first)
 		{
 			struct status_data *bstat = &pd->db->status, *status = &pd->status;
-			sd->pet.level = lv;
+			pd->pet.level = lv;
 			if (!first) //Lv Up animation
 				clif_misceffect(&pd->bl, 0);
 			status->rhw.atk = (bstat->rhw.atk*lv)/pd->db->lv;
@@ -1415,7 +1413,7 @@ int status_calc_pet(struct pet_data *pd, int first)
 	}
 	
 	//Support rate modifier (1000 = 100%)
-	pd->rate_fix = 1000*(sd->pet.intimate - battle_config.pet_support_min_friendly)/(1000- battle_config.pet_support_min_friendly) +500;
+	pd->rate_fix = 1000*(pd->pet.intimate - battle_config.pet_support_min_friendly)/(1000- battle_config.pet_support_min_friendly) +500;
 	if(battle_config.pet_support_rate != 100)
 		pd->rate_fix = pd->rate_fix*battle_config.pet_support_rate/100;
 	return 1;
@@ -1793,10 +1791,11 @@ int status_calc_pc(struct map_session_data* sd,int first)
 		}
 	}
 	
-	if(sd->status.pet_id > 0 && battle_config.pet_status_support && sd->pet.intimate > 0)
+	if(sd->pd && battle_config.pet_status_support)
 	{ // Pet
 		struct pet_data *pd=sd->pd;
-		if(pd && (!battle_config.pet_equip_required || pd->equip > 0) &&
+		if(pd && pd->pet.intimate > 0 &&
+			(!battle_config.pet_equip_required || pd->pet.equip > 0) &&
 			pd->state.skillbonus == 1 && pd->bonus) //Skotlex: Readjusted for pets
 			pc_bonus(sd,pd->bonus->type, pd->bonus->val);
 	}
@@ -3736,7 +3735,7 @@ int status_get_class(struct block_list *bl)
 	if(bl->type==BL_PC)
 		return ((struct map_session_data *)bl)->status.class_;
 	if(bl->type==BL_PET)
-		return ((struct pet_data *)bl)->class_;
+		return ((struct pet_data *)bl)->pet.class_;
 	if(bl->type==BL_HOM)
 		return ((struct homun_data *)bl)->master->homunculus.class_;
 	return 0;
@@ -3754,7 +3753,7 @@ int status_get_lv(struct block_list *bl)
 	if(bl->type==BL_PC)
 		return ((TBL_PC*)bl)->status.base_level;
 	if(bl->type==BL_PET)
-		return ((TBL_PET*)bl)->msd->pet.level;
+		return ((TBL_PET*)bl)->pet.level;
 	if(bl->type==BL_HOM)
 		return ((TBL_HOM*)bl)->master->homunculus.level;
 	return 1;
@@ -4014,10 +4013,10 @@ void status_set_viewdata(struct block_list *bl, int class_)
 				memcpy(&pd->vd, vd, sizeof(struct view_data));
 				if (!pcdb_checkid(vd->class_)) {
 					pd->vd.hair_style = battle_config.pet_hair_style;
-					if(pd->equip) {
-						pd->vd.head_bottom = itemdb_viewid(pd->equip);
+					if(pd->pet.equip) {
+						pd->vd.head_bottom = itemdb_viewid(pd->pet.equip);
 						if (!pd->vd.head_bottom)
-							pd->vd.head_bottom = pd->equip;
+							pd->vd.head_bottom = pd->pet.equip;
 					}
 				}
 			} else if (battle_config.error_log)

+ 9 - 13
src/map/unit.c

@@ -443,7 +443,7 @@ int unit_movepos(struct block_list *bl,int dst_x,int dst_y, int easy, int checkp
 				return 0;
 		} else
 			sd->areanpc_id=0;
-		if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0)
+		if(sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0)
 		{	//Check if pet needs to be teleported. [Skotlex]
 			int flag = 0;
 			bl = &sd->pd->bl; //Note that bl now points to the pet! 
@@ -1585,9 +1585,7 @@ int unit_remove_map(struct block_list *bl, int clrtype) {
 		md->state.skillstate= MSS_IDLE;
 	} else if (bl->type == BL_PET) {
 		struct pet_data *pd = (struct pet_data*)bl;
-		struct map_session_data *sd = pd->msd;
-		
-		if(!sd || sd->pet.intimate <= 0) {
+		if(pd->pet.intimate <= 0) {
 			clif_clearchar_area(bl,clrtype);
 			map_delblock(bl);
 			unit_free(bl);
@@ -1738,16 +1736,14 @@ int unit_free(struct block_list *bl) {
 			aFree (pd->loot);
 			pd->loot = NULL;
 		}
-		if (sd) {
-			sd->pd = NULL;
-			if(sd->pet.intimate > 0)
-				intif_save_petdata(sd->status.account_id,&sd->pet);
-			else
-			{	//Remove pet.
-				intif_delete_petdata(sd->status.pet_id);
-				sd->status.pet_id = 0;
-			}
+		if(pd->pet.intimate > 0)
+			intif_save_petdata(pd->pet.account_id,&pd->pet);
+		else
+		{	//Remove pet.
+			intif_delete_petdata(pd->pet.pet_id);
+			if (sd) sd->status.pet_id = 0;
 		}
+		if (sd) sd->pd = NULL;
 	} else if(bl->type == BL_MOB) {
 		struct mob_data *md = (struct mob_data*)bl;
 		if(md->deletetimer!=-1) {