From d450f9fd7b5d4fd71d4f7e244ef9d0786d0f745a Mon Sep 17 00:00:00 2001
From: MadCamel <madcamel@gmail.com>
Date: Mon, 16 Mar 2009 19:40:12 +0000
Subject: Now possible to divorce when partner is offline

---
 src/char/char.c  | 58 ++++++++++++++++++++++++++++++++++++++------------------
 src/map/chrif.c  | 30 +++++++++++++++++++++++++----
 src/map/pc.c     | 13 +++++++------
 src/map/script.c |  3 +++
 4 files changed, 76 insertions(+), 28 deletions(-)

diff --git a/src/char/char.c b/src/char/char.c
index 2719c03..185a412 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -1384,21 +1384,33 @@ int set_account_reg2(int acc, int num, struct global_reg *reg) {
 	return c;
 }
 
-// ����(char�폜���Ɏg�p)
+// Divorce a character from it's partner and let the map server know
 int char_divorce(struct mmo_charstatus *cs) {
+	int i;
+	char buf[10];
+
 	if (cs == NULL)
 		return 0;
 
-	if (cs->partner_id > 0){
-		int i;
-		for(i = 0; i < char_num; i++) {
-			if (char_dat[i].char_id == cs->partner_id && char_dat[i].partner_id == cs->char_id) {
-				cs->partner_id = 0;
-				char_dat[i].partner_id = 0;
-				return 0;
-			}
+	if (cs->partner_id <= 0)
+		return 0;
+
+	WBUFW(buf,0) = 0x2b12;
+	WBUFL(buf,2) = cs->char_id;
+
+	for(i = 0; i < char_num; i++) {
+		if (char_dat[i].char_id == cs->partner_id && char_dat[i].partner_id == cs->char_id) {
+			WBUFL(buf,6) = cs->partner_id;
+			mapif_sendall(buf,10);
+			cs->partner_id = 0;
+			char_dat[i].partner_id = 0;
+			return 0;
 		}
 	}
+
+	WBUFL(buf,6) = 0; // partner id 0 means failure
+	mapif_sendall(buf,10);
+
 	return 0;
 }
 
@@ -1472,16 +1484,9 @@ static int char_delete(struct mmo_charstatus *cs) {
 	if (cs->party_id)
 		inter_party_leave(cs->party_id, cs->account_id);
 	// ����
-	if (cs->partner_id){
-		// ��������map�ɒʒm
-		char buf[10];
-		WBUFW(buf,0) = 0x2b12;
-		WBUFL(buf,2) = cs->char_id;
-		WBUFL(buf,6) = cs->partner_id;
-		mapif_sendall(buf,10);
-		// ����
+	if (cs->partner_id)
 		char_divorce(cs);
-	}
+
 	return 0;
 }
 
@@ -2285,6 +2290,23 @@ int parse_frommap(int fd) {
 			break;
 		  }
 
+		// Map server is requesting a divorce
+		case 0x2b16:
+			if (RFIFOREST(fd) < 4)
+                                return 0;
+		  {
+			for (i = 0; i < char_num; i++)
+				if (char_dat[i].char_id == RFIFOL(fd, 2))
+					break;
+
+			if (i != char_num)
+				char_divorce(&char_dat[i]);
+
+			RFIFOSKIP(fd,6);
+			break;
+
+		  }
+			
 		default:
 			// inter server�����ɓn��
 			{
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 4f8edf6..ef681b7 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -676,7 +676,9 @@ int chrif_accountreg2(int fd)
 }
 
 /*==========================================
- * ������񓯊��v��
+ * Divorce request from char server
+ * triggered on account deletion or as an
+ * ack from a map-server divorce request
  *------------------------------------------
  */
 int chrif_divorce(int char_id, int partner_id) 
@@ -686,12 +688,32 @@ int chrif_divorce(int char_id, int partner_id)
 	if (!char_id || !partner_id)
 		return 0;
 
-	nullpo_retr(0, sd = map_nick2sd(map_charid2nick(partner_id)));
-	if (sd->status.partner_id == char_id) {
-		int i;
+
+	sd = map_nick2sd(map_charid2nick(char_id));
+	if (sd && sd->status.partner_id == partner_id) {
 		sd->status.partner_id = 0;
+		map_scriptcont(sd, sd->npc_id);
 	}
 
+	nullpo_retr(0, sd = map_nick2sd(map_charid2nick(partner_id)));
+	if (sd->status.partner_id == char_id)
+		sd->status.partner_id = 0;
+
+	return 0;
+}
+
+/*==========================================
+ * Tell character server someone is divorced
+ * Needed to divorce when partner is not connected to map server
+ *-------------------------------------
+ */
+int chrif_send_divorce(int char_id) {
+        if (char_fd < 0)
+                return -1;
+
+	WFIFOW(char_fd, 0) = 0x2b16;
+	WFIFOL(char_fd, 2) = char_id;
+	WFIFOSET(char_fd,6);
 	return 0;
 }
 
diff --git a/src/map/pc.c b/src/map/pc.c
index b900bd0..8dfdf47 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -6687,18 +6687,19 @@ int pc_divorce(struct map_session_data *sd)
 	if(sd == NULL || !pc_ismarried(sd))
 		return -1;
 
-	if( (p_sd=map_nick2sd(map_charid2nick(sd->status.partner_id))) !=NULL){
+	// If both are on map server we don't need to bother the char server
+	if( (p_sd=map_nick2sd(map_charid2nick(sd->status.partner_id))) !=NULL) { 
 		if(p_sd->status.partner_id != sd->status.char_id || sd->status.partner_id != p_sd->status.char_id){
 			printf("pc_divorce: Illegal partner_id sd=%d p_sd=%d\n",sd->status.partner_id,p_sd->status.partner_id);
 			return -1;
 		}
-		sd->status.partner_id=0;
 		p_sd->status.partner_id=0;
-
-	}else{
-		printf("pc_divorce: p_sd nullpo\n");
-		return -1;
+		sd->status.partner_id=0;
+		map_scriptcont(sd, sd->npc_id);
 	}
+	else
+		chrif_send_divorce(sd->status.char_id);
+
 	return 0;
 }
 
diff --git a/src/map/script.c b/src/map/script.c
index c5bcae1..287b4f6 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -5263,6 +5263,9 @@ int buildin_wedding_effect(struct script_state *st)
 int buildin_divorce(struct script_state *st)
 {
 	struct map_session_data *sd=script_rid2sd(st);
+
+	st->state=STOP; // rely on pc_divorce to restart
+	
 	if(sd==NULL || pc_divorce(sd) < 0){
 		push_val(st->stack,C_INT,0);
 		return 0;
-- 
cgit v1.2.3-70-g09d2