Browse Source

Updated disablenpc/enablenpc (#7671)

* Updated disablenpc/enablenpc script commands using OPTION_HIDE instead of OPTION_INVISIBLE, to correctly display the effects when the npcs are disabled/enabled. The other behaviors are kept.
Atemo 2 years ago
parent
commit
801c3c782e
5 changed files with 24 additions and 21 deletions
  1. 5 3
      src/map/clif.cpp
  2. 1 1
      src/map/map.cpp
  3. 16 16
      src/map/npc.cpp
  4. 1 0
      src/map/npc.hpp
  5. 1 1
      src/map/unit.cpp

+ 5 - 3
src/map/clif.cpp

@@ -1676,7 +1676,7 @@ static inline bool clif_npc_mayapurple(block_list *bl) {
 		npc_data *nd = map_id2nd(bl->id);
 
 		// TODO: Confirm if waitingroom cause any special cases
-		if (/* nd->chat_id == 0 && */ nd->sc.option & OPTION_INVISIBLE)
+		if (/* nd->chat_id == 0 && */ nd->is_invisible)
 			return true;
 	}
 
@@ -4034,6 +4034,8 @@ void clif_changelook(struct block_list *bl, int type, int val) {
 		target = SELF;
 
 #if PACKETVER < 4
+	if (target != SELF && bl->type == BL_NPC && (((TBL_NPC*)bl)->is_invisible))
+		target = SELF;
 	clif_sprite_change(bl, bl->id, type, val, 0, target);
 #else
 	if (bl->type != BL_NPC) {
@@ -5647,7 +5649,7 @@ int clif_outsight(struct block_list *bl,va_list ap)
 			clif_clearchar_skillunit((struct skill_unit *)bl,tsd->fd);
 			break;
 		case BL_NPC:
-			if(!(((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
+			if(!(((TBL_NPC*)bl)->is_invisible))
 				clif_clearunit_single(bl->id,CLR_OUTSIGHT,tsd->fd);
 			break;
 		default:
@@ -5661,7 +5663,7 @@ int clif_outsight(struct block_list *bl,va_list ap)
 		if(tbl->type == BL_SKILL) //Trap knocked out of sight
 			clif_clearchar_skillunit((struct skill_unit *)tbl,sd->fd);
 		else if(((vd=status_get_viewdata(tbl)) && vd->class_ != JT_INVISIBLE) &&
-			!(tbl->type == BL_NPC && (((TBL_NPC*)tbl)->sc.option&OPTION_INVISIBLE)))
+			!(tbl->type == BL_NPC && (((TBL_NPC*)tbl)->is_invisible)))
 			clif_clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd);
 	}
 	return 0;

+ 1 - 1
src/map/map.cpp

@@ -571,7 +571,7 @@ int map_count_oncell(int16 m, int16 x, int16 y, int type, int flag)
 			if(bl->x == x && bl->y == y && bl->type&type) {
 				if (bl->type == BL_NPC) {	// Don't count hidden or invisible npc. Cloaked npc are counted
 					npc_data *nd = BL_CAST(BL_NPC, bl);
-					if (nd->bl.m < 0 || nd->sc.option&(OPTION_HIDE|OPTION_INVISIBLE) || nd->dynamicnpc.owner_char_id != 0)
+					if (nd->bl.m < 0 || nd->sc.option&OPTION_HIDE || nd->dynamicnpc.owner_char_id != 0)
 						continue;
 				}
 				if(flag&1) {

+ 16 - 16
src/map/npc.cpp

@@ -879,7 +879,7 @@ struct view_data* npc_get_viewdata(int class_) {
 int npc_isnear_sub(struct block_list* bl, va_list args) {
     struct npc_data *nd = (struct npc_data*)bl;
 
-    if (nd->sc.option & (OPTION_HIDE|OPTION_INVISIBLE))
+    if (nd->sc.option&OPTION_HIDE)
         return 0;
 
 	if( nd->dynamicnpc.owner_char_id != 0 ){
@@ -1017,16 +1017,16 @@ bool npc_enable_target(npc_data& nd, uint32 char_id, e_npcv_status flag)
 			nd.sc.option |= OPTION_CLOAK;
 
 		auto it = std::find(sd->cloaked_npc.begin(), sd->cloaked_npc.end(), nd.bl.id);
-	
+
 		if (it == sd->cloaked_npc.end() && option != nd.sc.option)
 			sd->cloaked_npc.push_back(nd.bl.id);
 		else if (it != sd->cloaked_npc.end() && option == nd.sc.option)
 			sd->cloaked_npc.erase(it);
-	
+
 		if (nd.class_ != JT_WARPNPC && nd.class_ != JT_GUILD_FLAG)
 			clif_changeoption_target(&nd.bl, &sd->bl);
 		else {
-			if (nd.sc.option&(OPTION_HIDE|OPTION_INVISIBLE|OPTION_CLOAK))
+			if (nd.sc.option&(OPTION_HIDE|OPTION_CLOAK))
 				clif_clearunit_single(nd.bl.id, CLR_OUTSIGHT, sd->fd);
 			else
 				clif_spawn(&nd.bl);
@@ -1035,8 +1035,8 @@ bool npc_enable_target(npc_data& nd, uint32 char_id, e_npcv_status flag)
 	}
 	else {
 		if (flag & NPCVIEW_ENABLE) {
-			nd.sc.option &= ~OPTION_INVISIBLE;
-			clif_spawn(&nd.bl);
+			nd.sc.option &= ~OPTION_HIDE;
+			nd.is_invisible = false;
 		}
 		else if (flag & NPCVIEW_HIDEOFF)
 			nd.sc.option &= ~OPTION_HIDE;
@@ -1047,13 +1047,13 @@ bool npc_enable_target(npc_data& nd, uint32 char_id, e_npcv_status flag)
 		else if (flag & NPCVIEW_CLOAKON)
 			nd.sc.option |= OPTION_CLOAK;
 		else {	//Can't change the view_data to invisible class because the view_data for all npcs is shared! [Skotlex]
-			nd.sc.option |= OPTION_INVISIBLE;
-			clif_clearunit_area(&nd.bl,CLR_OUTSIGHT);  // Hack to trick maya purple card [Xazax]
+			nd.sc.option |= OPTION_HIDE;
+			nd.is_invisible = true;
 		}
 		if (nd.class_ != JT_WARPNPC && nd.class_ != JT_GUILD_FLAG)	//Client won't display option changes for these classes [Toms]
 			clif_changeoption(&nd.bl);
 		else {
-			if (nd.sc.option&(OPTION_HIDE|OPTION_INVISIBLE|OPTION_CLOAK))
+			if (nd.sc.option&(OPTION_HIDE|OPTION_CLOAK))
 				clif_clearunit_area(&nd.bl,CLR_OUTSIGHT);
 			else
 				clif_spawn(&nd.bl);
@@ -1721,7 +1721,7 @@ int npc_event_sub(map_session_data* sd, struct event_data* ev, const char* event
 		ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
 		return 1;
 	}
-	if( ev->nd->sc.option&OPTION_INVISIBLE )
+	if( ev->nd->is_invisible )
 	{
 		//Disabled npc, shouldn't trigger event.
 		npc_event_dequeue(sd);
@@ -1861,7 +1861,7 @@ int npc_touch_areanpc(map_session_data* sd, int16 m, int16 x, int16 y, struct np
 	nullpo_retr(0, sd);
 	nullpo_retr(0, nd);
 
-	if (nd->sc.option&OPTION_INVISIBLE)
+	if (nd->is_invisible)
 		return 1; // a npc was found, but it is disabled
 	if (npc_is_cloaked(nd, sd))
 		return 1;
@@ -1967,7 +1967,7 @@ int npc_touch_areanpc2(struct mob_data *md)
 
 	for( i = 0; i < mapdata->npc_num_area; i++ )
 	{
-		if( mapdata->npc[i]->sc.option&(OPTION_INVISIBLE|OPTION_CLOAK) )
+		if( mapdata->npc[i]->is_invisible || mapdata->npc[i]->sc.option&OPTION_CLOAK )
 			continue;
 
 		if( mapdata->npc[i]->dynamicnpc.owner_char_id != 0 ){
@@ -2064,7 +2064,7 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range)
 	//Now check for the actual NPC on said range.
 	for (i = 0; i < mapdata->npc_num_area; i++)
 	{
-		if (mapdata->npc[i]->sc.option&OPTION_INVISIBLE)
+		if (mapdata->npc[i]->is_invisible)
 			continue;
 
 		if( mapdata->npc[i]->dynamicnpc.owner_char_id != 0 ){
@@ -2185,7 +2185,7 @@ int npc_click(map_session_data* sd, struct npc_data* nd)
 	if ((nd = npc_checknear(sd,&nd->bl)) == NULL)
 		return 1;
 	//Hidden/Disabled npc.
-	if (nd->class_ < 0 || nd->sc.option&(OPTION_INVISIBLE|OPTION_HIDE))
+	if (nd->class_ < 0 || nd->sc.option&OPTION_HIDE)
 		return 1;
 
 	if( npc_is_hidden_dynamicnpc( *nd, *sd ) ){
@@ -2362,7 +2362,7 @@ int npc_buysellsel(map_session_data* sd, int id, int type)
 			sd->npc_id=0;
 		return 1;
 	}
-	if (nd->sc.option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
+	if (nd->is_invisible) // can't buy if npc is not visible (hack?)
 		return 1;
 
 	if( npc_is_hidden_dynamicnpc( *nd, *sd ) ){
@@ -5021,7 +5021,7 @@ int npc_do_atcmd_event(map_session_data* sd, const char* command, const char* me
 		return 1;
 	}
 
-	if( ev->nd->sc.option&OPTION_INVISIBLE ) { // Disabled npc, shouldn't trigger event.
+	if( ev->nd->is_invisible ) { // Disabled npc, shouldn't trigger event.
 		npc_event_dequeue(sd);
 		return 2;
 	}

+ 1 - 0
src/map/npc.hpp

@@ -221,6 +221,7 @@ struct npc_data {
 	struct navi_link navi; // for warps and the src of npcs
 	std::vector<navi_link> links; // for extra links, like warper npc
 #endif
+	bool is_invisible;
 };
 
 struct eri;

+ 1 - 1
src/map/unit.cpp

@@ -553,7 +553,7 @@ static TIMER_FUNC(unit_walktoxy_timer)
 			}
 			break;
 		case BL_NPC:
-			if (nd->sc.option&OPTION_INVISIBLE)
+			if (nd->is_invisible)
 				break;
 
 			int xs = -1, ys = -1;