Browse Source

Fixed dynamic NPC timeout (#7497)

Fixes #7473
Updates the last interaction time on end; and close;
Additionally added the official dynamic NPC result packet.

Thanks to @eppc0330
Lemongrass3110 2 years ago
parent
commit
165e0d668f
5 changed files with 40 additions and 2 deletions
  1. 11 0
      src/map/clif.cpp
  2. 10 1
      src/map/clif.hpp
  3. 1 1
      src/map/npc.cpp
  4. 6 0
      src/map/packets.hpp
  5. 12 0
      src/map/script.cpp

+ 11 - 0
src/map/clif.cpp

@@ -24794,6 +24794,17 @@ void clif_macro_reporter_status(map_session_data &sd, e_macro_report_status styp
 #endif
 }
 
+void clif_dynamicnpc_result( map_session_data& sd, e_dynamicnpc_result result ){
+#if PACKETVER_MAIN_NUM >= 20140430 || PACKETVER_RE_NUM >= 20140430 || defined(PACKETVER_ZERO)
+	struct PACKET_ZC_DYNAMICNPC_CREATE_RESULT p = {};
+
+	p.packetType = HEADER_ZC_DYNAMICNPC_CREATE_RESULT;
+	p.result = result;
+
+	clif_send( &p, sizeof( p ), &sd.bl, SELF );
+#endif
+}
+
 /*==========================================
  * Main client packet processing function
  *------------------------------------------*/

+ 10 - 1
src/map/clif.hpp

@@ -542,7 +542,6 @@ enum clif_messages : uint16_t {
 	MSG_ATTENDANCE_DISABLED = 0xd92,
 
 	// Unofficial names
-	C_DYNAMICNPC_TWICE = 0xa47, /// <"Is already in service. Please try again in a few minutes."
 	C_ITEM_EQUIP_SWITCH = 0xbc7,
 	C_ITEM_NOEQUIP = 0x174,	/// <"You can't put this item on."
 	C_ENCHANT_OVERWEIGHT = 0xEFD,
@@ -604,6 +603,14 @@ enum e_exitem_add_result : uint8 {
 	EXITEM_ADD_FAILED_EACHITEM_OVERCOUNT,
 };
 
+enum e_dynamicnpc_result : int32{
+	DYNAMICNPC_RESULT_SUCCESS,
+	DYNAMICNPC_RESULT_UNKNOWN,
+	DYNAMICNPC_RESULT_UNKNOWNNPC,
+	DYNAMICNPC_RESULT_DUPLICATE,
+	DYNAMICNPC_RESULT_OUTOFTIME
+};
+
 int clif_setip(const char* ip);
 void clif_setbindip(const char* ip);
 void clif_setport(uint16 port);
@@ -1235,4 +1242,6 @@ void clif_macro_detector_status(map_session_data &sd, e_macro_detect_status styp
 void clif_macro_reporter_select(map_session_data &sd, const std::vector<uint32> &aid_list);
 void clif_macro_reporter_status(map_session_data &sd, e_macro_report_status stype);
 
+void clif_dynamicnpc_result( map_session_data& sd, e_dynamicnpc_result result );
+
 #endif /* CLIF_HPP */

+ 1 - 1
src/map/npc.cpp

@@ -5816,7 +5816,7 @@ struct npc_data* npc_duplicate_npc_for_player( struct npc_data& nd, map_session_
 
 		// Check if the source NPC id of currently active duplicates already exists.
 		if( src_nd != nullptr && src_nd->src_id == src_id ){
-			clif_msg_color( &sd, C_DYNAMICNPC_TWICE, color_table[COLOR_LIGHT_YELLOW] );
+			clif_dynamicnpc_result( sd, DYNAMICNPC_RESULT_DUPLICATE );
 			return nullptr;
 		}
 	}

+ 6 - 0
src/map/packets.hpp

@@ -418,6 +418,11 @@ struct PACKET_ZC_COUPLENAME {
 	char name[NAME_LENGTH];
 } __attribute__((packed));
 
+struct PACKET_ZC_DYNAMICNPC_CREATE_RESULT{
+	int16 packetType;
+	int32 result;
+} __attribute__((packed));
+
 // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
 #if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
 	#pragma pack( pop )
@@ -469,6 +474,7 @@ DEFINE_PACKET_HEADER(ZC_ACK_OPEN_BANKING, 0x9b7)
 DEFINE_PACKET_HEADER(ZC_ACK_CLOSE_BANKING, 0x9b9)
 DEFINE_PACKET_HEADER(ZC_ACK_COUNT_BARGAIN_SALE_ITEM, 0x9c4)
 DEFINE_PACKET_HEADER(ZC_ACK_GUILDSTORAGE_LOG, 0x9da)
+DEFINE_PACKET_HEADER(ZC_DYNAMICNPC_CREATE_RESULT, 0xa17)
 DEFINE_PACKET_HEADER(CZ_REQ_APPLY_BARGAIN_SALE_ITEM2, 0xa3d)
 DEFINE_PACKET_HEADER(CZ_REQ_STYLE_CHANGE, 0xa46)
 DEFINE_PACKET_HEADER(ZC_STYLE_CHANGE_RES, 0xa47)

+ 12 - 0
src/map/script.cpp

@@ -4982,6 +4982,12 @@ BUILDIN_FUNC(close)
 	if( !script_rid2sd(sd) )
 		return SCRIPT_CMD_SUCCESS;
 
+	npc_data* nd = map_id2nd( st->oid );
+
+	if( nd != nullptr && nd->dynamicnpc.owner_char_id != 0 ){
+		nd->dynamicnpc.last_interaction = gettick();
+	}
+
 	const char* command = script_getfuncname( st );
 
 	if( !st->mes_active ) {
@@ -10345,6 +10351,12 @@ BUILDIN_FUNC(end)
 
 	st->state = END;
 
+	npc_data* nd = map_id2nd( st->oid );
+
+	if( nd != nullptr && nd->dynamicnpc.owner_char_id != 0 ){
+		nd->dynamicnpc.last_interaction = gettick();
+	}
+
 	if( st->mes_active )
 		st->mes_active = 0;