소스 검색

- Updated firepillar so it cannot be placed on top of others.
- Updated the firepillar code so it behaves like the other traps.
- Changed the default format for @me and @main to avoid crashes on the newer clients.
- Fixed the char-sql server so it returns a valid 'not found' packet when attempting to load a non-existing homunculus.
- Fixed jump to use 0,0 for random coordinates rather than -1,-1
- Added missing \n to error reporting in getmonsterinfo
- Additional status changes now only get triggered if the attack did damage, not if they get absorbed.
- Fixed a logical comparison in unit_free to properly remove pets/homuncs when their intimacy is reduced to 0.
- Properly set the opt3 value for Moonlight, Changeundead and Soul Link
- Fixed the "no equip" flag of cards not being properly applied when attemting to equip items.
- Added a check to avoid invoking pet menu entries when the pet is incuvated.
- Fixed the session_data de-association in chrif_auth_delete
- Cleaned chrif_auth_ok so that the latest received char info is kept when previous char login data was already in there.
- Corrected docs mentioning non-existing flag 'mf_nopvp'


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

skotlex 17 년 전
부모
커밋
8ae4bd12ad
15개의 변경된 파일126개의 추가작업 그리고 82개의 파일을 삭제
  1. 8 0
      Changelog-Trunk.txt
  2. 2 2
      conf/msg_athena.conf
  3. 3 0
      db/Changelog.txt
  4. 1 1
      db/skill_unit_db.txt
  5. 2 2
      doc/script_commands.txt
  6. 46 25
      src/char_sql/int_homun.c
  7. 8 5
      src/map/atcommand.c
  8. 2 2
      src/map/battle.c
  9. 13 9
      src/map/chrif.c
  10. 9 4
      src/map/pc.c
  11. 1 1
      src/map/pet.c
  12. 1 1
      src/map/script.c
  13. 6 18
      src/map/skill.c
  14. 22 10
      src/map/status.c
  15. 2 2
      src/map/unit.c

+ 8 - 0
Changelog-Trunk.txt

@@ -3,6 +3,14 @@ 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.
 
+2008/03/04
+	* Updated the firepillar code so it behaves like the other traps.
+	* Additional status changes now only get triggered if the attack did
+	  damage, not if they get absorbed.
+	* Properly set the opt3 value for Moonlight, Changeundead and Soul Link.
+	* Fixed the "no equip" flag of cards not being properly applied when
+	  attemting to equip items.
+	* Some corections to the new auth db system. [Skotlex]
 2008/03/02
 	* New optimizations for mail system and adjust to use it on Auctions. [Zephyrus]
 	- Added a Sql patch to clear all deleted mails. (There is no need to keep that data)

+ 2 - 2
conf/msg_athena.conf

@@ -284,7 +284,7 @@
 268: Reloaded the Message of the Day.
 269: Displaying first %d out of %d matches
 //@me output format
-270: *%s %s*
+270: *:%s %s:*
 271: You can't drop items on this map
 272: You can't trade on this map
 273: Commands available:
@@ -390,7 +390,7 @@
 383: Main chat already disabled.
 384: Main chat is currently enabled. Usage: @main <on|off>, @main <message>.
 385: Main chat is currently disabled. Usage: @main <on|off>, @main <message>.
-386: Main@%s : %s
+386: %s :Main: %s
 387: You cannot use Main chat while muted.
 388: You should enable main chat with "@main on" command.
 //NoAsk

+ 3 - 0
db/Changelog.txt

@@ -44,6 +44,9 @@
 
 =======================
 2008/03/04
+	* Updated firepillar so it cannot be placed on top of others.
+	* Changed the default format for @me and @main to avoid crashes on the
+	  newer clients. [Skotlex]
 	* Rev. 12292 Added a slot drooping ninetails. (bugreport:1089) [L0ne_W0lf]
 	* Rev. 12291 Corrected Field Manual 100% box. (bugreport:1104) [L0ne_W0lf]
 2008/03/03

+ 1 - 1
db/skill_unit_db.txt

@@ -31,7 +31,7 @@
  47,0x86,    ,  0, 2,1000,enemy, 0x080	//AC_SHOWER
  70,0x83,    , -1, 1,1000,all,   0x008	//PR_SANCTUARY
  79,0x84,    , -1, 1,3000,enemy, 0x008	//PR_MAGNUS
- 80,0x87,0x88,  0, 1,2000,enemy, 0x002	//WZ_FIREPILLAR
+ 80,0x87,0x88,  0, 1,2000,enemy, 0x006	//WZ_FIREPILLAR
  83,0x86,    ,  0, 3,1000,enemy, 0x000	//WZ_METEOR
  85,0x86,    ,  0, 6:6:6:6:6:6:6:6:6:6:8,1250,enemy,0x008	//WZ_VERMILION
  87,0x8d,    , -1, 0,  -1,all,   0x000	//WZ_ICEWALL

+ 2 - 2
doc/script_commands.txt

@@ -5391,10 +5391,10 @@ behavior of the map, you can see the list of the available ones in
 'db/const.txt' under 'mf_'.
 
 The map flags alter the behavior of the map regarding teleporting (mf_nomemo, 
-mf_noteleport, mf_nowarp, mf_nogo) storing location when disconnected 
+mf_noteleport, mf_nowarp, mf_nogo), storing location when disconnected 
 (mf_nosave), dead branch usage (mf_nobranch), penalties upon death 
 (mf_nopenalty, mf_nozenypenalty), PVP behavior (mf_pvp, mf_pvp_noparty, 
-mf_pvp_noguild, mf_nopvp), WoE behavior (mf_gvg,mf_gvg_noparty), ability to use 
+mf_pvp_noguild), WoE behavior (mf_gvg,mf_gvg_noparty), ability to use 
 skills or open up trade deals (mf_notrade, mf_novending, mf_noskill, mf_noicewall),
 current weather effects (mf_snow, mf_fog, mf_sakura, mf_leaves, mf_rain, mf_clouds, 
 mf_fireworks) and whether day/night will be in effect on this map (mf_indoors).

+ 46 - 25
src/char_sql/int_homun.c

@@ -49,6 +49,18 @@ int mapif_info_homunculus(int fd, int account_id, struct s_homunculus *hd)
 	return 0;
 }
 
+int mapif_noinfo_homunculus(int fd, int account_id)
+{
+	WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
+	WFIFOW(fd,0) = 0x3891;
+	WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
+	WFIFOL(fd,4) = account_id;
+	WFIFOB(fd,8) = 0; // not found.
+	memset(WFIFOP(fd,9), 0, sizeof(struct s_homunculus));
+	WFIFOSET(fd, sizeof(struct s_homunculus)+9);
+	return 0;
+}
+
 int mapif_homunculus_deleted(int fd, int flag)
 {
 	WFIFOHEAD(fd, 3);
@@ -157,34 +169,43 @@ int mapif_load_homunculus(int fd)
 		Sql_ShowDebug(sql_handle);
 		return 0;
 	}
-	if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
-	{
-		homun_pt->hom_id = RFIFOL(fd,6);
-		Sql_GetData(sql_handle,  1, &data, NULL); homun_pt->char_id = atoi(data);
-		Sql_GetData(sql_handle,  2, &data, NULL); homun_pt->class_ = atoi(data);
-		Sql_GetData(sql_handle,  3, &data, &len); memcpy(homun_pt->name, data, min(len, NAME_LENGTH));
-		Sql_GetData(sql_handle,  4, &data, NULL); homun_pt->level = atoi(data);
-		Sql_GetData(sql_handle,  5, &data, NULL); homun_pt->exp = atoi(data);
-		Sql_GetData(sql_handle,  6, &data, NULL); homun_pt->intimacy = (unsigned int)strtoul(data, NULL, 10);
-		homun_pt->intimacy = cap_value(homun_pt->intimacy, 0, 100000);
-		Sql_GetData(sql_handle,  7, &data, NULL); homun_pt->hunger = atoi(data);
-		homun_pt->hunger = cap_value(homun_pt->hunger, 0, 100);
-		Sql_GetData(sql_handle,  8, &data, NULL); homun_pt->str = atoi(data);
-		Sql_GetData(sql_handle,  9, &data, NULL); homun_pt->agi = atoi(data);
-		Sql_GetData(sql_handle, 10, &data, NULL); homun_pt->vit = atoi(data);
-		Sql_GetData(sql_handle, 11, &data, NULL); homun_pt->int_ = atoi(data);
-		Sql_GetData(sql_handle, 12, &data, NULL); homun_pt->dex = atoi(data);
-		Sql_GetData(sql_handle, 13, &data, NULL); homun_pt->luk = atoi(data);
-		Sql_GetData(sql_handle, 14, &data, NULL); homun_pt->hp = atoi(data);
-		Sql_GetData(sql_handle, 15, &data, NULL); homun_pt->max_hp = atoi(data);
-		Sql_GetData(sql_handle, 16, &data, NULL); homun_pt->sp = atoi(data);
-		Sql_GetData(sql_handle, 17, &data, NULL); homun_pt->max_sp = atoi(data);
-		Sql_GetData(sql_handle, 18, &data, NULL); homun_pt->skillpts = atoi(data);
-		Sql_GetData(sql_handle, 19, &data, NULL); homun_pt->rename_flag = atoi(data);
-		Sql_GetData(sql_handle, 20, &data, NULL); homun_pt->vaporize = atoi(data);
 
+	if( !Sql_NumRows(sql_handle) )
+	{	//No homunculus found.
+		mapif_noinfo_homunculus(fd, RFIFOL(fd,2));
+		Sql_FreeResult(sql_handle);
+		return 0;
+	}
+	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+	{
+		Sql_ShowDebug(sql_handle);
 		Sql_FreeResult(sql_handle);
+		return 0;
 	}
+	homun_pt->hom_id = RFIFOL(fd,6);
+	Sql_GetData(sql_handle,  1, &data, NULL); homun_pt->char_id = atoi(data);
+	Sql_GetData(sql_handle,  2, &data, NULL); homun_pt->class_ = atoi(data);
+	Sql_GetData(sql_handle,  3, &data, &len); memcpy(homun_pt->name, data, min(len, NAME_LENGTH));
+	Sql_GetData(sql_handle,  4, &data, NULL); homun_pt->level = atoi(data);
+	Sql_GetData(sql_handle,  5, &data, NULL); homun_pt->exp = atoi(data);
+	Sql_GetData(sql_handle,  6, &data, NULL); homun_pt->intimacy = (unsigned int)strtoul(data, NULL, 10);
+	homun_pt->intimacy = cap_value(homun_pt->intimacy, 0, 100000);
+	Sql_GetData(sql_handle,  7, &data, NULL); homun_pt->hunger = atoi(data);
+	homun_pt->hunger = cap_value(homun_pt->hunger, 0, 100);
+	Sql_GetData(sql_handle,  8, &data, NULL); homun_pt->str = atoi(data);
+	Sql_GetData(sql_handle,  9, &data, NULL); homun_pt->agi = atoi(data);
+	Sql_GetData(sql_handle, 10, &data, NULL); homun_pt->vit = atoi(data);
+	Sql_GetData(sql_handle, 11, &data, NULL); homun_pt->int_ = atoi(data);
+	Sql_GetData(sql_handle, 12, &data, NULL); homun_pt->dex = atoi(data);
+	Sql_GetData(sql_handle, 13, &data, NULL); homun_pt->luk = atoi(data);
+	Sql_GetData(sql_handle, 14, &data, NULL); homun_pt->hp = atoi(data);
+	Sql_GetData(sql_handle, 15, &data, NULL); homun_pt->max_hp = atoi(data);
+	Sql_GetData(sql_handle, 16, &data, NULL); homun_pt->sp = atoi(data);
+	Sql_GetData(sql_handle, 17, &data, NULL); homun_pt->max_sp = atoi(data);
+	Sql_GetData(sql_handle, 18, &data, NULL); homun_pt->skillpts = atoi(data);
+	Sql_GetData(sql_handle, 19, &data, NULL); homun_pt->rename_flag = atoi(data);
+	Sql_GetData(sql_handle, 20, &data, NULL); homun_pt->vaporize = atoi(data);
+	Sql_FreeResult(sql_handle);
 
 	// Load Homunculus Skill
 	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `skill_homunculus` WHERE `homun_id`=%d", homun_pt->hom_id) )

+ 8 - 5
src/map/atcommand.c

@@ -545,14 +545,17 @@ int atcommand_jump(const int fd, struct map_session_data* sd, const char* comman
 
 	sscanf(message, "%d %d", &x, &y);
 
-	if (x <= 0) //If coordinates are 'wrong', random jump.
-		x = -1;
-	if (y <= 0)
-		y = -1;
-	if (sd->bl.m >= 0 && map[sd->bl.m].flag.noteleport && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+	if (map[sd->bl.m].flag.noteleport && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
 		clif_displaymessage(fd, msg_txt(248));	// You are not authorized to warp from your current map.
 		return -1;
 	}
+
+	if ((x || y) && map_getcell(sd->bl.m, x, y, CELL_CHKNOPASS))
+  	{	//This is to prevent the pc_setpos call from printing an error.
+		clif_displaymessage(fd, msg_txt(2));
+		x = y = 0; //Invalid cell, use random spot.
+	}
+
 	pc_setpos(sd, sd->mapindex, x, y, 3);
 	sprintf(atcmd_output, msg_txt(5), sd->bl.x, sd->bl.y); // Jumped to %d %d
 	clif_displaymessage(fd, atcmd_output);

+ 2 - 2
src/map/battle.c

@@ -158,7 +158,7 @@ int battle_delay_damage_sub (int tid, unsigned int tick, int id, int data)
 	{
 		map_freeblock_lock();
 		status_fix_damage(dat->src, target, dat->damage, dat->delay);
-		if ((dat->dmg_lv == ATK_DEF || dat->damage > 0) && dat->attack_type)
+		if (dat->damage > 0 && dat->attack_type)
 		{
 			if (!status_isdead(target))
 				skill_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
@@ -179,7 +179,7 @@ int battle_delay_damage (unsigned int tick, struct block_list *src, struct block
 	if (!battle_config.delay_battle_damage) {
 		map_freeblock_lock();
 		status_fix_damage(src, target, damage, ddelay);
-		if ((damage > 0 || dmg_lv == ATK_DEF) && attack_type)
+		if (damage > 0 && attack_type)
 		{
 			if (!status_isdead(target))
 				skill_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());

+ 13 - 9
src/map/chrif.c

@@ -116,9 +116,9 @@ bool chrif_auth_delete(int account_id, int char_id, enum sd_state state) {
 	struct auth_node *node;
 	if ((node=chrif_auth_check(account_id, char_id, state)))
 	{
-		if (node->fd && session[node->fd] && node->sd &&
-			session[node->fd]->session_data == node->sd)
-			session[node->fd]->session_data = NULL;
+		int fd = node->sd?node->sd->fd:node->fd;
+		if (session[fd] && session[fd]->session_data == node->sd)
+			session[fd]->session_data = NULL;
 		if (node->char_dat) aFree(node->char_dat);
 		if (node->sd) aFree(node->sd);
 		ers_free(auth_db_ers, node);
@@ -558,7 +558,9 @@ void chrif_authok(int fd)
 	
 	if ((node = chrif_search(account_id)))
 	{	//Is the character already awaiting authorization?
-		if (node->state == ST_LOGIN && node->sd)
+		if (node->state != ST_LOGIN)
+			return; //character in logout phase, do not touch that data.
+		if (node->sd)
 		{
 			sd = node->sd;
 			if(node->char_dat == NULL &&
@@ -566,16 +568,18 @@ void chrif_authok(int fd)
 				node->char_id == char_id &&
 				node->login_id1 == RFIFOL(fd, 8))
 			{ //Auth Ok
-				if (!pc_authok(sd, RFIFOL(fd, 16), RFIFOL(fd, 12), status))
-					chrif_auth_delete(account_id, char_id, ST_LOGIN);
+				if (pc_authok(sd, RFIFOL(fd, 16), RFIFOL(fd, 12), status))
+					return;
 			} else { //Auth Failed
 				pc_authfail(sd);
 				chrif_char_offline(sd); //Set him offline, the char server likely has it set as online already.
-				chrif_auth_delete(account_id, char_id, ST_LOGIN);
 			}
+			chrif_auth_delete(account_id, char_id, ST_LOGIN);
+			return;
 		}
-		//Otherwise discard the entry received as we already have information.
-		return;
+		//When we receive double login info and the client has not connected yet,
+		//discard the older one and keep the new one.
+		chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
 	}
 
 	// Awaiting for client to connect.

+ 9 - 4
src/map/pc.c

@@ -555,12 +555,17 @@ int pc_isequip(struct map_session_data *sd,int n)
 		return 0;
 	if(item->sex != 2 && sd->status.sex != item->sex)
 		return 0;
-	if(map[sd->bl.m].flag.pvp && item->flag.no_equip&1)
+	if(map[sd->bl.m].flag.pvp && ((item->flag.no_equip&1) || !pc_isAllowedCardOn(sd,item->slot,n,1)))
 		return 0;
-	if(map_flag_gvg(sd->bl.m) && item->flag.no_equip&2)
+	if(map_flag_gvg(sd->bl.m) && ((item->flag.no_equip&2) || !pc_isAllowedCardOn(sd,item->slot,n,2)))
 		return 0; 
-	if(map[sd->bl.m].flag.restricted && item->flag.no_equip&map[sd->bl.m].zone)
-		return 0;
+	if(map[sd->bl.m].flag.restricted)
+	{
+		int flag =map[sd->bl.m].zone;
+		if (item->flag.no_equip&flag || !pc_isAllowedCardOn(sd,item->slot,n,flag))
+			return 0;
+	}
+
 	if (sd->sc.count) {
 			
 		if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG]

+ 1 - 1
src/map/pet.c

@@ -624,7 +624,7 @@ int pet_menu(struct map_session_data *sd,int menunum)
 		return 1;
 	
 	//You lost the pet already.
-	if(!sd->status.pet_id || sd->pd->pet.intimate <= 0)
+	if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incuvate)
 		return 1;
 	
 	switch(menunum) {

+ 1 - 1
src/map/script.c

@@ -12152,7 +12152,7 @@ BUILDIN_FUNC(getmonsterinfo)
 
 	mob_id	= script_getnum(st,2);
 	if (!mobdb_checkid(mob_id)) {
-		ShowError("buildin_getmonsterinfo: Wrong Monster ID: %i", mob_id);
+		ShowError("buildin_getmonsterinfo: Wrong Monster ID: %i\n", mob_id);
 		if ( !script_getnum(st,3) ) //requested a string
 			script_pushconststr(st,"null");
 		else

+ 6 - 18
src/map/skill.c

@@ -1630,7 +1630,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 
 	if (!dmg.amotion) {
 		status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
-		if (dmg.dmg_lv == ATK_DEF || damage > 0) {
+		if (damage > 0) {
 			if (!status_isdead(bl))
 				skill_additional_effect(src,bl,skillid,skilllv,attack_type,tick);
 			//Counter status effects [Skotlex] 
@@ -6824,15 +6824,6 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 			skill_delunit(src);
 			break;
 
-		case UNT_FIREPILLAR_ACTIVE:
-			skill_area_temp[1] = 0;
-			map_foreachinrange(skill_attack_area,bl,
-				skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag,
-				BF_MAGIC,ss,&src->bl,sg->skill_id,sg->skill_lv,tick,0,BCT_ENEMY);  // area damage [Celest]
-			sg->interval = -1; //Mark it used up so others can't trigger it for massive splash damage. [Skotlex]
-			sg->limit=DIFF_TICK(tick,sg->tick) + 1500;
-			break;
-
 		case UNT_SKIDTRAP:
 			{
 				skill_blown(&src->bl,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0);
@@ -6874,8 +6865,10 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 		case UNT_SANDMAN:
 		case UNT_FLASHER:
 		case UNT_FREEZINGTRAP:
+		case UNT_FIREPILLAR_ACTIVE:
 			map_foreachinrange(skill_trap_splash,&src->bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
-			clif_changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
+			if (sg->unit_id != UNT_FIREPILLAR_ACTIVE)
+				clif_changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
 			src->range = -1; //Disable range so it does not invoke a for each in area again.
 			sg->limit=DIFF_TICK(tick,sg->tick)+1500;
 			break;
@@ -9056,12 +9049,6 @@ int skill_trap_splash (struct block_list *bl, va_list ap)
 		case UNT_FLASHER:        
 			skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,tick);
 			break;
-		case UNT_LANDMINE:
-		case UNT_BLASTMINE:
-		case UNT_CLAYMORETRAP:
-		case UNT_FREEZINGTRAP:
-			skill_attack(skill_get_type(sg->skill_id),ss,src,bl,sg->skill_id,sg->skill_lv,tick,0);
-			break;
 		case UNT_GROUNDDRIFT_WIND:
 			if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
 				sc_start(bl,SC_STUN,5,sg->skill_lv,skill_get_time2(sg->skill_id, sg->skill_lv));
@@ -9083,7 +9070,8 @@ int skill_trap_splash (struct block_list *bl, va_list ap)
 				skill_blown(src,bl,skill_get_blewcount(sg->skill_id,sg->skill_lv),-1,0);
 			break;
 		default:
-			return 0;
+			skill_attack(skill_get_type(sg->skill_id),ss,src,bl,sg->skill_id,sg->skill_lv,tick,0);
+			break;
 	}
 	return 1;
 }

+ 22 - 10
src/map/status.c

@@ -6026,11 +6026,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			opt_flag = 0;
 			break;
 		//0x100 missing?
-//	TODO:
-//		case SC_MOONLIT:
-//			sc->opt3 |= 0x200;
-//			opt_flag = 0;
-//			break;
+		case SC_DANCING:
+			if ((val1&0xFFFF) == CG_MOONLIT)
+				sc->opt3 |= 0x200;
+			opt_flag = 0;
+			break;
 		case SC_MARIONETTE:
 		case SC_MARIONETTE2:
 			sc->opt3 |= 0x400;
@@ -6056,11 +6056,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 			sc->opt3 |= 0x8000;
 			opt_flag = 0;
 			break;
-//	TODO:
-//		case SC_BIOLABAURA:
-//			sc->opt3 |= 0x10000;
-//			opt_flag = 0;
-//			break;
+		case SC_CHANGEUNDEAD:
+			sc->opt3 |= 0x10000;
+			opt_flag = 0;
+			break;
 		//OPTION
 		case SC_HIDING:
 			sc->option |= OPTION_HIDE;
@@ -6613,6 +6612,11 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
 		sc->opt3 &= ~0x80;
 		opt_flag = 0;
 		break;
+	case SC_DANCING:
+		if ((sce->val1&0xFFFF) == CG_MOONLIT)
+			sc->opt3 &= ~0x200;
+		opt_flag = 0;
+		break;
 	case SC_MARIONETTE:
 	case SC_MARIONETTE2:
 		sc->opt3 &= ~0x400;
@@ -6630,6 +6634,14 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
 		sc->opt3 &= ~0x2000;
 		opt_flag = 0;
 		break;
+	case SC_SPIRIT:
+		sc->opt3 &= ~0x8000;
+		opt_flag = 0;
+		break;
+	case SC_CHANGEUNDEAD:
+		sc->opt3 &= ~0x10000;
+		opt_flag = 0;
+		break;
 	default:
 		opt_flag = 0;
 	}

+ 2 - 2
src/map/unit.c

@@ -1706,7 +1706,7 @@ int unit_remove_map(struct block_list *bl, int clrtype)
 	case BL_PET:
 	{
 		struct pet_data *pd = (struct pet_data*)bl;
-		if( pd->pet.intimate <= 0 && !(pd->msd && pd->msd->state.active) )
+		if( pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active) )
 		{	//If logging out, this is deleted on unit_free
 			clif_clearunit_area(bl,clrtype);
 			map_delblock(bl);
@@ -1721,7 +1721,7 @@ int unit_remove_map(struct block_list *bl, int clrtype)
 	{
 		struct homun_data *hd = (struct homun_data *) bl;
 		ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick.
-		if(!hd->homunculus.intimacy && !(hd->master && hd->master->state.active) )
+		if(!hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) )
 		{	//If logging out, this is deleted on unit_free
 			clif_emotion(bl, 28) ;	//sob
 			clif_clearunit_area(bl,clrtype);