浏览代码

Fix wedding skill checks (#5579)

* Fixes #5576 and fixes #7475.
* Fix WE_CALLPARTNER, WE_CALLPARENT and WE_CALLBABY fallthrough check.
* Adds usage of packet struct.
* Add autotrade check for WE_CALLPARTNER.
Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
Co-authored-by: aleos <aleos89@users.noreply.github.com>
lighta 2 年之前
父节点
当前提交
f7dbe79c34
共有 4 个文件被更改,包括 34 次插入19 次删除
  1. 10 13
      src/map/clif.cpp
  2. 1 1
      src/map/clif.hpp
  3. 6 0
      src/map/packets.hpp
  4. 17 5
      src/map/skill.cpp

+ 10 - 13
src/map/clif.cpp

@@ -9378,26 +9378,23 @@ void clif_wedding_effect(struct block_list *bl)
 
 /// Notifies the client of the name of the partner character (ZC_COUPLENAME).
 /// 01e6 <partner name>.24B
-void clif_callpartner(struct map_session_data *sd)
+void clif_callpartner(struct map_session_data& sd)
 {
-	unsigned char buf[26];
+	PACKET_ZC_COUPLENAME p = { 0 };
 
-	nullpo_retv(sd);
-
-	WBUFW(buf,0) = 0x1e6;
+	p.packetType = HEADER_ZC_COUPLENAME;
 
-	if( sd->status.partner_id ) {
-		const char *p = map_charid2nick(sd->status.partner_id);
-		struct map_session_data *p_sd = pc_get_partner(sd);
-		if( p != NULL && p_sd != NULL && !p_sd->state.autotrade )
-			safestrncpy(WBUFCP(buf,2), p, NAME_LENGTH);
+	if( sd.status.partner_id ) {
+		struct map_session_data *p_sd = pc_get_partner(&sd);
+		if (p_sd != nullptr && !p_sd->state.autotrade)
+			safestrncpy(p.name, p_sd->status.name, NAME_LENGTH);
 		else
-			WBUFB(buf,2) = 0;
+			p.name[0] = 0;
 	} else {// Send zero-length name if no partner, to initialize the client buffer.
-		WBUFB(buf,2) = 0;
+		p.name[0] = 0;
 	}
 
-	clif_send(buf, packet_len(0x1e6), &sd->bl, AREA);
+	clif_send(&p, sizeof(p), &sd.bl, AREA);
 }
 
 

+ 1 - 1
src/map/clif.hpp

@@ -687,7 +687,7 @@ void clif_emotion(struct block_list *bl,int type);
 void clif_talkiebox(struct block_list* bl, const char* talkie);
 void clif_wedding_effect(struct block_list *bl);
 void clif_divorced(struct map_session_data* sd, const char* name);
-void clif_callpartner(struct map_session_data *sd);
+void clif_callpartner(struct map_session_data& sd);
 void clif_playBGM( struct map_session_data& sd, const char* name );
 void clif_soundeffect( struct block_list& bl, const char* name, int type, enum send_target target );
 void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, t_tick tick);

+ 6 - 0
src/map/packets.hpp

@@ -413,6 +413,11 @@ struct PACKET_ZC_ACK_ADD_EXCHANGE_ITEM {
 	uint8 result;
 } __attribute__((packed));
 
+struct PACKET_ZC_COUPLENAME {
+	int16 packetType;
+	char name[NAME_LENGTH];
+} __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 )
@@ -439,6 +444,7 @@ DEFINE_PACKET_HEADER(ZC_BROADCAST2, 0x1c3)
 #else
 	DEFINE_PACKET_HEADER(ZC_CHANGE_GUILD, 0x1b4)
 #endif
+DEFINE_PACKET_HEADER(ZC_COUPLENAME, 0x1e6);
 DEFINE_PACKET_HEADER(ZC_FRIENDS_LIST, 0x201)
 DEFINE_PACKET_HEADER(ZC_NOTIFY_WEAPONITEMLIST, 0x221)
 DEFINE_PACKET_HEADER(ZC_ACK_WEAPONREFINE, 0x223)

+ 17 - 5
src/map/skill.cpp

@@ -12799,25 +12799,37 @@ TIMER_FUNC(skill_castend_id){
 		//These should become skill_castend_pos
 		switch (ud->skill_id) {
 			case WE_CALLPARTNER:
-				if (sd)
-					clif_callpartner(sd);
+				if (sd) {
+					map_session_data *p_sd = pc_get_partner(sd);
+
+					if (p_sd && p_sd->state.autotrade) {
+						fail = true;
+						break;
+					} else
+						clif_callpartner(*sd);
+				}
+				break;
 			case WE_CALLPARENT:
 				if (sd) {
-					struct map_session_data *f_sd = pc_get_father(sd);
-					struct map_session_data *m_sd = pc_get_mother(sd);
+					map_session_data *f_sd = pc_get_father(sd);
+					map_session_data *m_sd = pc_get_mother(sd);
+
 					if ((f_sd && f_sd->state.autotrade) || (m_sd && m_sd->state.autotrade)) {
 						fail = true;
 						break;
 					}
 				}
+				break;
 			case WE_CALLBABY:
 				if (sd) {
-					struct map_session_data *c_sd = pc_get_child(sd);
+					map_session_data *c_sd = pc_get_child(sd);
+
 					if (c_sd && c_sd->state.autotrade) {
 						fail = true;
 						break;
 					}
 				}
+				break;
 			case AM_RESURRECTHOMUN:
 			case PF_SPIDERWEB:
 				{