// When member goes to other map or levels up. int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv) { struct party_data *p; int i; p = inter_party_fromsql(party_id); if (p == NULL) return 0; for(i = 0; i < MAX_PARTY && (p->party.member[i].account_id != account_id || p->party.member[i].char_id != char_id); i++); if (i == MAX_PARTY) return 0; if (p->party.member[i].online != online) { p->party.member[i].online = online; if (online) p->party.count++; else p->party.count--; // Even share check situations: Family state (always breaks) // character logging on/off is max/min level (update level range) // or character logging on/off has a different level (update level range using new level) if (p->family || (p->party.member[i].lv <= p->min_lv || p->party.member[i].lv >= p->max_lv) || (p->party.member[i].lv != lv && (lv <= p->min_lv || lv >= p->max_lv)) ) { p->party.member[i].lv = lv; int_party_check_lv(p); } //Send online/offline update. mapif_party_membermoved(&p->party, i); } if (p->party.member[i].lv != lv) { if(p->party.member[i].lv == p->min_lv || p->party.member[i].lv == p->max_lv) { p->party.member[i].lv = lv; int_party_check_lv(p); } else p->party.member[i].lv = lv; //There is no need to send level update to map servers //since they do nothing with it. } if (p->party.member[i].map != map) { p->party.member[i].map = map; mapif_party_membermoved(&p->party, i); } return 0; }
// パ?ティ?退要求 int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id) { struct party_data *p; int i,lv; p = idb_get(party_db, party_id); if (!p) return 0; for(i = 0; i < MAX_PARTY; i++) { if(p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id) { mapif_party_leaved(party_id, account_id, char_id); lv = 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 (lv == p->min_lv || lv == p->max_lv || p->family) { if(p->family) p->family = 0; //Family state broken. int_party_check_lv(p); } if (party_check_empty(&p->party) == 0) mapif_party_info(-1, &p->party); return 0; } } return 0; }
// パ?ティ追加要求 int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member) { struct party_data *p; int i; p = idb_get(party_db, party_id); if (p == NULL || p->size == MAX_PARTY) { mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1); return 0; } for(i = 0; i < MAX_PARTY; i++) { if (p->party.member[i].account_id == 0) { memcpy(&p->party.member[i], member, sizeof(struct party_member)); p->party.member[i].leader = 0; if (p->party.member[i].online) p->party.count++; p->size++; if (p->size == 3) //Check family state. int_party_calc_state(p); else //Check even share range. if (member->lv < p->min_lv || member->lv > p->max_lv || p->family) { if (p->family) p->family = 0; //Family state broken. int_party_check_lv(p); } mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 0); mapif_party_info(-1, &p->party); return 0; } } mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1); return 0; }
int inter_party_CharOnline (int char_id, int party_id) { struct party_data *p; int i; if (party_id == -1) { // Get party_id from the database char *data; if (SQL_ERROR == Sql_Query (sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id)) { Sql_ShowDebug (sql_handle); return 0; } if (SQL_SUCCESS != Sql_NextRow (sql_handle)) return 0; //Eh? No party? Sql_GetData (sql_handle, 0, &data, NULL); party_id = atoi (data); Sql_FreeResult (sql_handle); } if (party_id == 0) return 0; //No party... p = inter_party_fromsql (party_id); if (!p) { ShowError ("Character %d's party %d not found!\n", char_id, party_id); return 0; } //Set member online for (i = 0; i < MAX_PARTY; i++) { if (p->party.member[i].char_id == char_id) { if (!p->party.member[i].online) { p->party.member[i].online = 1; p->party.count++; if (p->party.member[i].lv < p->min_lv || p->party.member[i].lv > p->max_lv) int_party_check_lv (p); } break; } } return 1; }
int inter_party_CharOffline (int char_id, int party_id) { struct party_data *p = NULL; int i; if (party_id == -1) { // Get guild_id from the database char *data; if (SQL_ERROR == Sql_Query (sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id)) { Sql_ShowDebug (sql_handle); return 0; } if (SQL_SUCCESS != Sql_NextRow (sql_handle)) return 0; //Eh? No party? Sql_GetData (sql_handle, 0, &data, NULL); party_id = atoi (data); Sql_FreeResult (sql_handle); } if (party_id == 0) return 0; //No party... //Character has a party, set character offline and check if they were the only member online if ( (p = inter_party_fromsql (party_id)) == NULL) return 0; //Set member offline for (i = 0; i < MAX_PARTY; i++) { if (p->party.member[i].char_id == char_id) { p->party.member[i].online = 0; p->party.count--; if (p->party.member[i].lv == p->min_lv || p->party.member[i].lv == p->max_lv) int_party_check_lv (p); break; } } if (!p->party.count) //Parties don't have any data that needs be saved at this point... so just remove it from memory. idb_remove (party_db_, party_id); return 1; }
//Request leave party int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type) { struct party_data *p; int i,j=-1; p = inter_party_fromsql(party_id); if( p == NULL ) {// Party does not exists? if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", schema_config.char_db, party_id) ) Sql_ShowDebug(sql_handle); return 0; } for (i = 0; i < MAX_PARTY; i++) { if(p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id) { break; } } if (i >= MAX_PARTY) return 0; //Member not found? mapif_party_withdraw(party_id, account_id, char_id, name, type); if (p->party.member[i].leader){ // TODO: Official allow 'leaderless' party 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].name, type); p->party.member[j].account_id = 0; } //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. int_party_check_lv(p); } } if (party_check_empty(p) == 0) mapif_party_info(-1, &p->party, 0); return 0; }
// パーティ追加要求 int mapif_parse_PartyAddMember (int fd, int party_id, struct party_member *member) { struct party_data *p; int i; p = inter_party_fromsql (party_id); if (p == NULL || p->size == MAX_PARTY) { mapif_party_memberadded (fd, party_id, member->account_id, member->char_id, 1); return 0; } ARR_FIND (0, MAX_PARTY, i, p->party.member[i].account_id == 0); if (i == MAX_PARTY) { // Party full mapif_party_memberadded (fd, party_id, member->account_id, member->char_id, 1); return 0; } memcpy (&p->party.member[i], member, sizeof (struct party_member)); p->party.member[i].leader = 0; if (p->party.member[i].online) p->party.count++; p->size++; if (p->size == 3) //Check family state. int_party_calc_state (p); else //Check even share range. if (member->lv < p->min_lv || member->lv > p->max_lv || p->family) { if (p->family) p->family = 0; //Family state broken. int_party_check_lv (p); } mapif_party_info (-1, &p->party, 0); mapif_party_memberadded (fd, party_id, member->account_id, member->char_id, 0); inter_party_tosql (&p->party, PS_ADDMEMBER, i); return 0; }