소스 검색

- Expanded the autospell structure to hold a flag, which contains the required Battle Flag conditions required for a skill to trigger.
- Added the required constants to const.txt to specify the autospell trigger properties.
- Added bonus5 bAutoSpell/bAutoSpellWhenHit. The new parameter is used to specify when the spell should trigger (melee/range + weapon/magic/misc attack), see item_bonus for details.
- Applied use of packet 0x28a (clif_changeoption2) to transmit opt3 changes.


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

skotlex 18 년 전
부모
커밋
bdaf348a6d
11개의 변경된 파일163개의 추가작업 그리고 43개의 파일을 삭제
  1. 3 0
      Changelog-Trunk.txt
  2. 6 0
      db/const.txt
  3. 29 0
      doc/item_bonus.txt
  4. 32 3
      src/map/clif.c
  5. 1 0
      src/map/clif.h
  6. 1 1
      src/map/map.h
  7. 29 5
      src/map/pc.c
  8. 1 0
      src/map/pc.h
  9. 12 0
      src/map/script.c
  10. 11 4
      src/map/skill.c
  11. 38 30
      src/map/status.c

+ 3 - 0
Changelog-Trunk.txt

@@ -4,6 +4,9 @@ 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.
 
 2007/04/18
+	* Added bonus5 bAutoSpell/bAutoSpellWhenHit. The new parameter is used to
+	  specify when the spell should trigger (melee/range + weapon/magic/misc
+	  attack), see doc/item_bonus.txt for details. [Skotlex]
 	* Changed some %lu to %u in login_sql/login.c because uint32 is now 
 	  an unsigned int [Toms]
 	* Discarded extra deflate function needed for afm reading [ultramage]

+ 6 - 0
db/const.txt

@@ -441,6 +441,12 @@ RC_Dragon	9
 RC_Boss	10
 RC_NonBoss	11
 
+BF_WEAPON	0x0001
+BF_MAGIC	0x0002
+BF_MISC	0x0004
+BF_SHORT	0x0010
+BF_LONG	0x0040
+
 IG_BlueBox	1
 IG_VioletBox	2
 IG_CardAlbum	3

+ 29 - 0
doc/item_bonus.txt

@@ -184,6 +184,35 @@ bonus4 bAutoSpellWhenHit,x,y,n,i;	n/10% chance to cast skill x of level y when
                                            2=use random skill lv in [1..y]
                                            3=1+2 (random lv on enemy)
 
+bonus5 bAutoSpell,x,y,n,t,i;		n/10% chance to cast skill x of level y when
+                                        attacking
+                                        i: 1=cast on enemy, not on self
+                                           2=use random skill lv in [1..y]
+                                           3=1+2 (random lv on enemy)
+                                        t: Trigger criteria:
+                                           BF_SHORT: Trigger on melee attack
+                                           BF_LONG: Trigger on ranged attack
+                                           BF_WEAPON: Trigger on weapon skills 
+                                           BF_MAGIC: Trigger on magic skills 
+                                           BF_MISC: Trigger on misc skills 
+                                           (the default for the other
+                                           bAutoSpell modes is
+                                           BF_WEAPON|BF_LONG|BF_SHORT)
+
+bonus5 bAutoSpellWhenHit,x,y,n,t,i;	n/10% chance to cast skill x of level y when
+                                        being hit by a direct attack. Target
+													 must be within spell's range to go
+													 off.
+                                        i: 1=cast on enemy, not on self
+                                           2=use random skill lv in [1..y]
+                                           3=1+2 (random lv on enemy)
+                                        t: Trigger criteria:
+                                           BF_SHORT: Trigger on melee attack
+                                           BF_LONG: Trigger on ranged attack
+                                           BF_WEAPON: Trigger on weapon skills 
+                                           BF_MAGIC: Trigger on magic skills 
+                                           BF_MISC: Trigger on misc skills 
+
 //---- 2/22 new card effects ----
 
 bonus2 bAddItemHealRate,n,x;		Increases HP recovered by n type items by x%,

+ 32 - 3
src/map/clif.c

@@ -3119,6 +3119,31 @@ int clif_changeoption(struct block_list* bl)
 	return 0;
 }
 
+int clif_changeoption2(struct block_list* bl)
+{
+	unsigned char buf[20];
+	struct status_change *sc;
+	
+	sc = status_get_sc(bl);
+	if (!sc) return 0; //How can an option change if there's no sc?
+
+	WBUFW(buf,0) = 0x28a;
+	WBUFL(buf,2) = bl->id;
+	WBUFL(buf,6) = sc->option;
+	WBUFL(buf,10) = clif_setlevel(status_get_lv(bl));
+	WBUFL(buf,14) = sc->opt3;
+	if(disguised(bl)) {
+		clif_send(buf,packet_len(0x28a),bl,AREA_WOS);
+		WBUFL(buf,2) = -bl->id;
+		clif_send(buf,packet_len(0x28a),bl,SELF);
+		WBUFL(buf,2) = bl->id;
+		WBUFL(buf,6) = OPTION_INVISIBLE;
+		clif_send(buf,packet_len(0x28a),bl,SELF);
+	} else
+		clif_send(buf,packet_len(0x28a),bl,AREA);
+	return 0;
+}
+
 /*==========================================
  *
  *------------------------------------------
@@ -12012,7 +12037,7 @@ static int packetdb_readdb(void)
 	int skip_ver = 0;
 	int warned = 0;
 	char *str[64],*p,*str2[64],*p2,w1[64],w2[64];
-	int packet_len_table[0x260] = {
+	int packet_len_table[0x290] = {
 	   10,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
 	    0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
 	    0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
@@ -12067,7 +12092,11 @@ static int packetdb_readdb(void)
 	   12, 26,   9, 11, -1, -1, 10,  2, 282, 11,  4, 36, -1,-1,  4,  2,
 	//#0x0240
 	   -1, -1,  -1, -1, -1,  3,  4,  8,  -1,  3, 70,  4,  8,12,  4, 10,
-	    3, 32,  -1,  3,  3,  5,  5,  8,   2,  3, -1, -1,  4,-1,  4,  0
+	    3, 32,  -1,  3,  3,  5,  5,  8,   2,  3, -1, -1,  4,-1,  4,  0,
+		 0,  0,   0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0, 0,  0,  0,
+		 0,  0,   0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0, 0,  0,  0,
+	//#0x0280
+		 0,  0,   0,  0,  0,  0,  0,  0,   0,  0, 18,  0,  0, 0,  0,  0
 	};
 	struct {
 		void (*func)(int, struct map_session_data *);
@@ -12212,7 +12241,7 @@ static int packetdb_readdb(void)
 
 	// Set server packet lengths - packet_db[SERVER]
 	memset(packet_db,0,sizeof(packet_db));
-	for( i = 0; i < 0x260; ++i )
+	for( i = 0; i < sizeof(packet_len_table)/sizeof(packet_len_table[0]); ++i )
 		packet_len(i) = packet_len_table[i];
 
 	sprintf(line, "%s/packet_db.txt", db_path);

+ 1 - 0
src/map/clif.h

@@ -109,6 +109,7 @@ int clif_unequipitemack(struct map_session_data *,int,int,int);	// self
 int clif_misceffect(struct block_list*,int);	// area
 int clif_misceffect2(struct block_list *bl,int type);
 int clif_changeoption(struct block_list*);	// area
+int clif_changeoption2(struct block_list*);	// area
 int clif_useitemack(struct map_session_data*,int,int,int);	// self
 void clif_GlobalMessage(struct block_list* bl, const char* message);
 int clif_createchat(struct map_session_data*,int);	// self

+ 1 - 1
src/map/map.h

@@ -658,7 +658,7 @@ struct map_session_data {
 	// zeroed arrays end here.
 	// zeroed structures start here
 	struct s_autospell{
-		short id, lv, rate, card_id;
+		short id, lv, rate, card_id, flag;
 	} autospell[MAX_PC_BONUS], autospell2[MAX_PC_BONUS];
 	struct s_addeffect{
 		short id, rate, arrow_rate;

+ 29 - 5
src/map/pc.c

@@ -1236,7 +1236,7 @@ static int pc_bonus_autospell_del(struct s_autospell *spell, int max, short id,
 	return rate;
 }
 
-static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short card_id) {
+static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id) {
 	int i;
 	if (rate < 0) return //Remove the autobonus.
 		pc_bonus_autospell_del(spell, max, id, lv, -rate, card_id);
@@ -1260,6 +1260,7 @@ static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, shor
 	spell[i].id = id;
 	spell[i].lv = lv;
 	spell[i].rate = rate;
+	spell[i].flag|= flag;
 	spell[i].card_id = card_id;
 	return 1;
 }
@@ -2328,11 +2329,11 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
 		break;
 	case SP_AUTOSPELL:
 		if(sd->state.lr_flag != 2)
-			pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, type2, type3, val, current_equip_card_id);
+			pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, type2, type3, val, BF_WEAPON|BF_SHORT|BF_LONG, current_equip_card_id);
 		break;
 	case SP_AUTOSPELL_WHENHIT:
 		if(sd->state.lr_flag != 2)
-			pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, type2, type3, val, current_equip_card_id);
+			pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, type2, type3, val, BF_WEAPON|BF_SHORT|BF_LONG, current_equip_card_id);
 		break;
 	case SP_HP_LOSS_RATE:
 		if(sd->state.lr_flag != 2) {
@@ -2421,12 +2422,12 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4
 	switch(type){
 	case SP_AUTOSPELL:
 		if(sd->state.lr_flag != 2)
-			pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, current_equip_card_id);
+			pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, BF_WEAPON|BF_SHORT|BF_LONG, current_equip_card_id);
 		break;
 
 	case SP_AUTOSPELL_WHENHIT:
 		if(sd->state.lr_flag != 2)
-			pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, current_equip_card_id);
+			pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, BF_WEAPON|BF_SHORT|BF_LONG, current_equip_card_id);
 		break;
 	default:
 		if(battle_config.error_log)
@@ -2437,6 +2438,29 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4
 	return 0;
 }
 
+int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4,int type5,int val)
+{
+	nullpo_retr(0, sd);
+
+	switch(type){
+	case SP_AUTOSPELL:
+		if(sd->state.lr_flag != 2)
+			pc_bonus_autospell(sd->autospell, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
+		break;
+
+	case SP_AUTOSPELL_WHENHIT:
+		if(sd->state.lr_flag != 2)
+			pc_bonus_autospell(sd->autospell2, MAX_PC_BONUS, (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
+		break;
+	default:
+		if(battle_config.error_log)
+			ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val);
+		break;
+	}
+
+	return 0;
+}
+
 /*==========================================
  *	Grants a player a given skill. Flag values are:
  *	0 - Grant skill unconditionally and forever (only this one invokes status_calc_pc,

+ 1 - 0
src/map/pc.h

@@ -165,6 +165,7 @@ int pc_bonus(struct map_session_data*,int,int);
 int pc_bonus2(struct map_session_data *sd,int,int,int);
 int pc_bonus3(struct map_session_data *sd,int,int,int,int);
 int pc_bonus4(struct map_session_data *sd,int,int,int,int,int);
+int pc_bonus5(struct map_session_data *sd,int,int,int,int,int,int);
 int pc_skill(struct map_session_data* sd, int id, int level, int flag);
 
 int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip);

+ 12 - 0
src/map/script.c

@@ -3615,6 +3615,7 @@ BUILDIN_FUNC(bonus);
 BUILDIN_FUNC(bonus2);
 BUILDIN_FUNC(bonus3);
 BUILDIN_FUNC(bonus4);
+BUILDIN_FUNC(bonus5);
 BUILDIN_FUNC(skill);
 BUILDIN_FUNC(addtoskill); // [Valaris]
 BUILDIN_FUNC(guildskill);
@@ -3946,6 +3947,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF2(bonus,"bonus2","iii"),
 	BUILDIN_DEF2(bonus,"bonus3","iiii"),
 	BUILDIN_DEF2(bonus,"bonus4","iiiii"),
+	BUILDIN_DEF2(bonus,"bonus5","iiiiii"),
 	BUILDIN_DEF(skill,"ii?"),
 	BUILDIN_DEF(addtoskill,"ii?"), // [Valaris]
 	BUILDIN_DEF(guildskill,"ii"),
@@ -6558,12 +6560,14 @@ BUILDIN_FUNC(statusup2)
 /// bonus2 <bonus type>,<val1>,<val2>
 /// bonus3 <bonus type>,<val1>,<val2>,<val3>
 /// bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4>
+/// bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4>,<val5>
 BUILDIN_FUNC(bonus)
 {
 	int type;
 	int type2;
 	int type3;
 	int type4;
+	int type5;
 	int val;
 	TBL_PC* sd;
 
@@ -6595,6 +6599,14 @@ BUILDIN_FUNC(bonus)
 		val   = script_getnum(st,6);
 		pc_bonus4(sd, type, type2, type3, type4, val);
 		break;
+	case 7:
+		type2 = script_getnum(st,3);
+		type3 = script_getnum(st,4);
+		type4 = script_getnum(st,5);
+		type5 = script_getnum(st,6);
+		val   = script_getnum(st,7);
+		pc_bonus5(sd, type, type2, type3, type4, type5, val);
+		break;
 	default:
 		ShowDebug("buildin_bonus: unexpected last data (%d)\n", script_lastdata(st));
 	}

+ 11 - 4
src/map/skill.c

@@ -1413,14 +1413,16 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 	//Reports say that autospell effects get triggered on skills and pretty much everything including splash attacks. [Skotlex]
 	//But Gravity Patched this silently, and it now seems to trigger only on
 	//weapon attacks.
-	if(sd && !status_isdead(bl) && src != bl && attack_type&BF_WEAPON
-//		!(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)
-	) {
+	if(sd && !status_isdead(bl) && src != bl && sd->autospell[0].id) {
 		struct block_list *tbl;
 		struct unit_data *ud;
 		int i, skilllv;
 		for (i = 0; i < MAX_PC_BONUS && sd->autospell[i].id; i++) {
 
+			if(!(sd->autospell[i].flag&attack_type&BF_RANGEMASK &&
+				sd->autospell[i].flag&attack_type&BF_WEAPONMASK))
+				continue; //Attack type or range type did not match.
+
 			skill = (sd->autospell[i].id > 0) ? sd->autospell[i].id : -sd->autospell[i].id;
 
 			if (skillnotok(skill, sd))
@@ -1582,7 +1584,8 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
 	}
 
 	//Trigger counter-spells to retaliate against damage causing skills. [Skotlex]
-	if(dstsd && !status_isdead(bl) && src != bl && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)) 
+	if(dstsd && !status_isdead(bl) && src != bl && dstsd->autospell2[0].id &&
+		!(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)) 
 	{
 		struct block_list *tbl;
 		struct unit_data *ud;
@@ -1590,6 +1593,10 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
 
 		for (i = 0; i < MAX_PC_BONUS && dstsd->autospell2[i].id; i++) {
 
+			if(!(dstsd->autospell2[i].flag&attack_type&BF_RANGEMASK &&
+				dstsd->autospell2[i].flag&attack_type&BF_WEAPONMASK))
+				continue; //Attack type or range type did not match.
+
 			skillid = (dstsd->autospell2[i].id > 0) ? dstsd->autospell2[i].id : -dstsd->autospell2[i].id;
 			skilllv = dstsd->autospell2[i].lv?dstsd->autospell2[i].lv:1;
 			if (skilllv < 0) skilllv = 1+rand()%(-skilllv);

+ 38 - 30
src/map/status.c

@@ -5861,18 +5861,18 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 		case SC_SPEARQUICKEN:
 		case SC_CONCENTRATION:
 			sc->opt3 |= 0x1;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		case SC_MAXOVERTHRUST:
 		case SC_OVERTHRUST:
 		case SC_SWOO:	//Why does it shares the same opt as Overthrust? Perhaps we'll never know...
 			sc->opt3 |= 0x2;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		case SC_ENERGYCOAT:
 		case SC_SKE:
 			sc->opt3 |= 0x4;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		case SC_INCATKRATE:
 			//Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex]
@@ -5882,39 +5882,39 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 			}
 		case SC_EXPLOSIONSPIRITS:
 			sc->opt3 |= 0x8;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		case SC_STEELBODY:
 		case SC_SKA:
 			sc->opt3 |= 0x10;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		case SC_BLADESTOP:
 			sc->opt3 |= 0x20;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		//0x40 missing?
 		case SC_BERSERK:
 			sc->opt3 |= 0x80;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		//0x100, 0x200 missing?
 		case SC_MARIONETTE:
 		case SC_MARIONETTE2:
 			sc->opt3 |= 0x400;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		case SC_ASSUMPTIO:
 			sc->opt3 |= 0x800;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		case SC_WARM: //SG skills [Komurka]
 			sc->opt3 |= 0x1000;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		case SC_KAITE:
 			sc->opt3 |= 0x2000;
-			opt_flag = 0;
+			opt_flag = 2;
 			break;
 		//OPTION
 		case SC_HIDING:
@@ -5950,8 +5950,12 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 
 	//On Aegis, when turning on a status change, first goes the option packet,
 	// then the sc packet.
-	if(opt_flag)
-		clif_changeoption(bl);
+	if(opt_flag) {
+		if (opt_flag == 2)
+			clif_changeoption2(bl);
+		else
+			clif_changeoption(bl);
+	}
 
 	if (calc_flag&SCB_DYE)
 	{	//Reset DYE color
@@ -6371,15 +6375,15 @@ int status_change_end( struct block_list* bl , int type,int tid )
 
 	case SC_HIDING:
 		sc->option &= ~OPTION_HIDE;
-		opt_flag|= 2|4; //Check for warp trigger + AoE trigger
+		opt_flag|= 8|4; //Check for warp trigger + AoE trigger
 		break;
 	case SC_CLOAKING:
 		sc->option &= ~OPTION_CLOAK;
-		opt_flag|= 2;
+		opt_flag|= 8;
 		break;
 	case SC_CHASEWALK:
 		sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
-		opt_flag|= 2;
+		opt_flag|= 8;
 		break;
 	case SC_SIGHT:
 		sc->option &= ~OPTION_SIGHT;
@@ -6405,55 +6409,55 @@ int status_change_end( struct block_list* bl , int type,int tid )
 	case SC_SPEARQUICKEN:
 	case SC_CONCENTRATION:
 		sc->opt3 &= ~0x1;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_OVERTHRUST:
 	case SC_MAXOVERTHRUST:
 	case SC_SWOO:
 		sc->opt3 &= ~0x2;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_ENERGYCOAT:
 	case SC_SKE:
 		sc->opt3 &= ~0x4;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_INCATKRATE: //Simulated Explosion spirits effect.
 		if (bl->type != BL_MOB)
 			break;
 	case SC_EXPLOSIONSPIRITS:
 		sc->opt3 &= ~0x8;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_STEELBODY:
 	case SC_SKA:
 		sc->opt3 &= ~0x10;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_BLADESTOP:
 		sc->opt3 &= ~0x20;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_BERSERK:
 		sc->opt3 &= ~0x80;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_MARIONETTE:
 	case SC_MARIONETTE2:
 		sc->opt3 &= ~0x400;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_ASSUMPTIO:
 		sc->opt3 &= ~0x800;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_WARM: //SG skills [Komurka]
 		sc->opt3 &= ~0x1000;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	case SC_KAITE:
 		sc->opt3 &= ~0x2000;
-		opt_flag = 0;
+		opt_flag = 2;
 		break;
 	default:
 		opt_flag = 0;
@@ -6472,8 +6476,12 @@ int status_change_end( struct block_list* bl , int type,int tid )
 	else if (sd)
 		clif_status_load(bl,StatusIconChangeTable[type],0);
 
-	if(opt_flag)
-		clif_changeoption(bl);
+	if(opt_flag) {
+		if (opt_flag & 2)
+			clif_changeoption2(bl);
+		else
+			clif_changeoption(bl);
+	}
 
 	if (calc_flag)
 		status_calc_bl(bl,calc_flag);
@@ -6481,7 +6489,7 @@ int status_change_end( struct block_list* bl , int type,int tid )
 	if(opt_flag&4) //Out of hiding, invoke on place.
 		skill_unit_move(bl,gettick(),1);
 
-	if(opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
+	if(opt_flag&8 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
 		npc_touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event.
 
 	return 1;