From ea449a7a5720335ff1b19ef0f3b97361c606355e Mon Sep 17 00:00:00 2001 From: KirieZ Date: Sun, 18 Dec 2016 18:54:40 -0200 Subject: Changed behavior when party leader leaves it from party being disbanded to leader being changed to the second user. Closes #1107 --- src/char/int_party.c | 42 ++++++++++++++++++++++++------------------ src/map/party.c | 12 ++++++++++++ 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/char/int_party.c b/src/char/int_party.c index 2fc39c328..a7adea30d 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -614,6 +614,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) { struct party_data *p; int i,j; + unsigned int leader; p = inter_party->fromsql(party_id); if( p == NULL ) @@ -634,25 +635,30 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) mapif->party_withdraw(party_id, account_id, char_id); - if (p->party.member[i].leader){ - p->party.member[i].account_id = 0; - for (j = 0; j < MAX_PARTY; j++) { - if (!p->party.member[j].account_id) - continue; - mapif->party_withdraw(party_id, p->party.member[j].account_id, p->party.member[j].char_id); - p->party.member[j].account_id = 0; + leader = p->party.member[i].leader; // member's leader state + + inter_party->tosql(&p->party,PS_DELMEMBER,i); + j = p->party.member[i].lv; + if(p->party.member[i].online) p->party.count--; + memset(&p->party.member[i], 0, sizeof(struct party_member)); + p->size--; + if (j == p->min_lv || j == p->max_lv || p->family) + { + if(p->family) p->family = 0; //Family state broken. + inter_party->check_lv(p); + } + + if( leader ) { + // Member was party leader, pick a new leader + i = 0; + while (i < MAX_PARTY && p->party.member[i].account_id == 0) { + i++; } - //Party gets deleted on the check_empty call below. - } else { - inter_party->tosql(&p->party,PS_DELMEMBER,i); - j = p->party.member[i].lv; - if(p->party.member[i].online) p->party.count--; - memset(&p->party.member[i], 0, sizeof(struct party_member)); - p->size--; - if (j == p->min_lv || j == p->max_lv || p->family) - { - if(p->family) p->family = 0; //Family state broken. - inter_party->check_lv(p); + + if( i < MAX_PARTY ) { + // Update party's leader + p->party.member[i].leader = 1; + inter_party->tosql(&p->party, PS_LEADER, i); } } diff --git a/src/map/party.c b/src/map/party.c index 3bf9542c7..1a9ac1cbe 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -300,6 +300,18 @@ int party_recv_info(const struct party *sp, int char_id) if (i == MAX_PARTY) added[added_count++] = member_id; } + + ARR_FIND(0, MAX_PARTY, j, p->party.member[j].leader == 1); + if( j == MAX_PARTY ) { + // Leader has changed + int i; + ARR_FIND(0, MAX_PARTY, i, sp->member[i].leader == 1); + if( i < MAX_PARTY ) { + clif->PartyLeaderChanged(map->id2sd(sp->member[i].account_id), 0, sp->member[i].account_id); + } else { + party->broken(p->party.party_id); // Should not happen, Party is leaderless, disband + } + } } else { for( member_id = 0; member_id < MAX_PARTY; ++member_id ) if( sp->member[member_id].char_id != 0 ) -- cgit v1.2.3-60-g2f50 From 19c07f43a7d58462a6437ab92d5690302304c592 Mon Sep 17 00:00:00 2001 From: KirieZ Date: Tue, 20 Dec 2016 19:22:18 -0200 Subject: Follow-up ea449a7, fixed coding-style --- src/char/int_party.c | 13 +++++-------- src/map/party.c | 10 +++++----- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/char/int_party.c b/src/char/int_party.c index a7adea30d..df1d339cf 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -639,23 +639,20 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) inter_party->tosql(&p->party,PS_DELMEMBER,i); j = p->party.member[i].lv; - if(p->party.member[i].online) p->party.count--; + if (p->party.member[i].online > 0) p->party.count--; memset(&p->party.member[i], 0, sizeof(struct party_member)); p->size--; - if (j == p->min_lv || j == p->max_lv || p->family) - { + if (j == p->min_lv || j == p->max_lv || p->family) { if(p->family) p->family = 0; //Family state broken. inter_party->check_lv(p); } - if( leader ) { + if (leader) { // Member was party leader, pick a new leader i = 0; - while (i < MAX_PARTY && p->party.member[i].account_id == 0) { - i++; - } + while (i < MAX_PARTY && p->party.member[i].account_id == 0) i++; - if( i < MAX_PARTY ) { + if (i < MAX_PARTY) { // Update party's leader p->party.member[i].leader = 1; inter_party->tosql(&p->party, PS_LEADER, i); diff --git a/src/map/party.c b/src/map/party.c index 1a9ac1cbe..aad38efa5 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -302,12 +302,12 @@ int party_recv_info(const struct party *sp, int char_id) } ARR_FIND(0, MAX_PARTY, j, p->party.member[j].leader == 1); - if( j == MAX_PARTY ) { + if (j == MAX_PARTY) { // Leader has changed - int i; - ARR_FIND(0, MAX_PARTY, i, sp->member[i].leader == 1); - if( i < MAX_PARTY ) { - clif->PartyLeaderChanged(map->id2sd(sp->member[i].account_id), 0, sp->member[i].account_id); + int k; + ARR_FIND(0, MAX_PARTY, k, sp->member[k].leader == 1); + if (i < MAX_PARTY) { + clif->PartyLeaderChanged(map->id2sd(sp->member[k].account_id), 0, sp->member[k].account_id); } else { party->broken(p->party.party_id); // Should not happen, Party is leaderless, disband } -- cgit v1.2.3-60-g2f50 From 946b7f8490e952fbd90c6760f256ddfdd1e98137 Mon Sep 17 00:00:00 2001 From: KirieZ Date: Fri, 23 Dec 2016 10:31:27 -0200 Subject: Follow-up 19c07f4 --- src/char/int_party.c | 6 +++--- src/map/party.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/char/int_party.c b/src/char/int_party.c index df1d339cf..43583828d 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -639,7 +639,8 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) inter_party->tosql(&p->party,PS_DELMEMBER,i); j = p->party.member[i].lv; - if (p->party.member[i].online > 0) p->party.count--; + if (p->party.member[i].online > 0) + p->party.count--; memset(&p->party.member[i], 0, sizeof(struct party_member)); p->size--; if (j == p->min_lv || j == p->max_lv || p->family) { @@ -649,8 +650,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) if (leader) { // Member was party leader, pick a new leader - i = 0; - while (i < MAX_PARTY && p->party.member[i].account_id == 0) i++; + ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id != 0); if (i < MAX_PARTY) { // Update party's leader diff --git a/src/map/party.c b/src/map/party.c index aad38efa5..0a5b791fe 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -306,7 +306,7 @@ int party_recv_info(const struct party *sp, int char_id) // Leader has changed int k; ARR_FIND(0, MAX_PARTY, k, sp->member[k].leader == 1); - if (i < MAX_PARTY) { + if (k < MAX_PARTY) { clif->PartyLeaderChanged(map->id2sd(sp->member[k].account_id), 0, sp->member[k].account_id); } else { party->broken(p->party.party_id); // Should not happen, Party is leaderless, disband -- cgit v1.2.3-60-g2f50 From 2ce4c3e261f59df22ff23259574b6bfccc11bf3b Mon Sep 17 00:00:00 2001 From: KirieZ Date: Sun, 12 Feb 2017 12:08:49 -0200 Subject: Follow-up 946b7f8490e952fbd90c6760f256ddfdd1e98137 --- src/char/int_party.c | 19 +++--------------- src/map/party.c | 54 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/char/int_party.c b/src/char/int_party.c index 43583828d..921bf6d9d 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -614,7 +614,6 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) { struct party_data *p; int i,j; - unsigned int leader; p = inter_party->fromsql(party_id); if( p == NULL ) @@ -634,10 +633,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) return 0; //Member not found? mapif->party_withdraw(party_id, account_id, char_id); - - leader = p->party.member[i].leader; // member's leader state - inter_party->tosql(&p->party,PS_DELMEMBER,i); j = p->party.member[i].lv; if (p->party.member[i].online > 0) p->party.count--; @@ -648,19 +644,10 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) inter_party->check_lv(p); } - if (leader) { - // Member was party leader, pick a new leader - ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id != 0); - - if (i < MAX_PARTY) { - // Update party's leader - p->party.member[i].leader = 1; - inter_party->tosql(&p->party, PS_LEADER, i); - } - } - - if (inter_party->check_empty(p) == 0) + if (inter_party->check_empty(p) == 0) { + inter_party->tosql(&p->party, PS_DELMEMBER, i); mapif->party_info(-1, &p->party, 0); + } return 0; } // When member goes to other map or levels up. diff --git a/src/map/party.c b/src/map/party.c index 0a5b791fe..26b4bae8b 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -274,6 +274,7 @@ int party_recv_info(const struct party *sp, int char_id) int added_count = 0; int j; int member_id; + int leader_account_id = 0, leader_char_id = 0; nullpo_ret(sp); @@ -287,8 +288,12 @@ int party_recv_info(const struct party *sp, int char_id) ARR_FIND(0, MAX_PARTY, i, sp->member[i].account_id == member->account_id && sp->member[i].char_id == member->char_id); - if (i == MAX_PARTY) + if (i == MAX_PARTY) { removed[removed_count++] = member_id; + } else if (member->leader != 0) { + leader_account_id = member->account_id; + leader_char_id = member->char_id; + } } for (member_id = 0; member_id < MAX_PARTY; ++member_id) { member = &sp->member[member_id]; @@ -300,18 +305,6 @@ int party_recv_info(const struct party *sp, int char_id) if (i == MAX_PARTY) added[added_count++] = member_id; } - - ARR_FIND(0, MAX_PARTY, j, p->party.member[j].leader == 1); - if (j == MAX_PARTY) { - // Leader has changed - int k; - ARR_FIND(0, MAX_PARTY, k, sp->member[k].leader == 1); - if (k < MAX_PARTY) { - clif->PartyLeaderChanged(map->id2sd(sp->member[k].account_id), 0, sp->member[k].account_id); - } else { - party->broken(p->party.party_id); // Should not happen, Party is leaderless, disband - } - } } else { for( member_id = 0; member_id < MAX_PARTY; ++member_id ) if( sp->member[member_id].char_id != 0 ) @@ -328,6 +321,7 @@ int party_recv_info(const struct party *sp, int char_id) continue;// not online party->member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id); } + memcpy(&p->party, sp, sizeof(struct party)); memset(&p->state, 0, sizeof(p->state)); memset(&p->data, 0, sizeof(p->data)); @@ -336,6 +330,8 @@ int party_recv_info(const struct party *sp, int char_id) if ( member->char_id == 0 ) continue;// empty p->data[member_id].sd = party->sd_check(sp->party_id, member->account_id, member->char_id); + if (member->account_id == leader_account_id && member->char_id == leader_char_id) + p->party.member[member_id].leader = 1; } party->check_state(p); while( added_count > 0 ) { // new in party @@ -603,11 +599,43 @@ int party_member_withdraw(int party_id, int account_id, int char_id) int i; ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id ); if( i < MAX_PARTY ) { + bool was_leader = false; + int prev_leader_accountId = 0; + if (p->party.member[i].leader != 0) { + was_leader = true; + prev_leader_accountId = p->party.member[i].account_id; + } + clif->party_withdraw(p,sd,account_id,p->party.member[i].name,0x0); memset(&p->party.member[i], 0, sizeof(p->party.member[0])); memset(&p->data[i], 0, sizeof(p->data[0])); p->party.count--; party->check_state(p); + + if (was_leader) { + int k; + // Member was party leader, try to pick a new leader from online members + ARR_FIND(0, MAX_PARTY, k, p->party.member[k].account_id != 0 && p->party.member[k].online == 1); + + if (k == MAX_PARTY) { + // No online members, get an offline one + ARR_FIND(0, MAX_PARTY, k, p->party.member[k].account_id != 0); + } + + if (k < MAX_PARTY) { + // Update party's leader + p->party.member[k].leader = 1; + + if (p->data[k].sd != NULL) { + /** update members **/ + clif->PartyLeaderChanged(p->data[k].sd, prev_leader_accountId, p->data[k].sd->status.account_id); + } + + //Update info. + intif->party_leaderchange(p->party.party_id, p->party.member[k].account_id, p->party.member[k].char_id); + clif->party_info(p, NULL); + } + } } } -- cgit v1.2.3-60-g2f50