int party_member_leaved(int party_id,int account_id,int char_id) { struct map_session_data *sd=map_id2sd(account_id); struct party_data *p=party_search(party_id); int i; if (sd && sd->status.char_id != char_id) //Wrong target sd = NULL; if(p!=NULL){ for(i=0;i<MAX_PARTY;i++) if(p->party.member[i].account_id==account_id && p->party.member[i].char_id==char_id){ clif_party_leaved(p,sd,account_id,p->party.member[i].name,0x00); 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); break; } } if(sd!=NULL && sd->status.party_id==party_id){ sd->status.party_id=0; sd->state.party_sent=0; clif_charnameupdate(sd); //Update name display [Skotlex] //TODO: hp bars should be cleared too } return 0; }
/// Invoked (from char-server) when a party member leaves the party. int party_member_withdraw(int party_id, int account_id, int char_id) { struct map_session_data* sd = map_id2sd(account_id); struct party_data* p = party_search(party_id); if( p ) { 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 ) { 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( sd && sd->status.party_id == party_id && sd->status.char_id == char_id ) { int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion int j,i; j = pc_bound_chk(sd,3,idxlist); for(i=0;i<j;i++) pc_delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_OTHER); sd->status.party_id = 0; clif_charnameupdate(sd); //Update name display [Skotlex] //TODO: hp bars should be cleared too if( p->instance_id ) instance_check_kick(sd); } return 0; }
int party_removemember2(struct map_session_data *sd,int char_id,int party_id) { if( sd ) { if( !sd->status.party_id ) return -3; party_trade_bound_cancel(sd); intif_party_leave(sd->status.party_id,sd->status.account_id,sd->status.char_id); return 1; } else { int i; struct party_data *p = party_search(party_id); if( !p ) return -2; ARR_FIND(0,MAX_PARTY,i,p->party.member[i].char_id == char_id); if( i >= MAX_PARTY ) return -1; intif_party_leave(party_id,p->party.member[i].account_id,char_id); return 1; } return 0; }
// パーティメッセージ受信 void party_recv_message(int party_id, int account_id, XString mes) { struct party *p; if ((p = party_search(party_id)) == NULL) return; clif_party_message(p, account_id, mes); }
int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv) { struct party_data *p; int i; if( (p=party_search(party_id))==NULL) return 0; for(i=0;i<MAX_PARTY;i++){ struct map_session_data *sd; struct party_member *m=&p->party.member[i]; if(m->account_id==account_id && m->char_id==char_id){ m->map = map; m->online=online; m->lv=lv; //Check if they still exist on this map server sd = map_id2sd(m->account_id); p->data[i].sd = (sd!=NULL && sd->status.party_id==p->party.party_id && sd->status.char_id == m->char_id && !sd->state.waitingdisconnect)?sd:NULL; break; } } if(i==MAX_PARTY){ if(battle_config.error_log) ShowError("party: not found member %d/%d on %d[%s]",account_id,char_id,party_id,p->party.name); return 0; } clif_party_info(p,NULL); return 0; }
/// Invoked (from char-server) when a party is disbanded. int party_broken(int party_id) { struct party_data* p; int i; p = party_search(party_id); if( p == NULL ) return 0; if( p->instance_id ) { instance[p->instance_id].party_id = 0; instance_destroy( p->instance_id ); } for( i = 0; i < MAX_PARTY; i++ ) { if( p->data[i].sd!=NULL ) { clif_party_withdraw(p,p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,0x10); p->data[i].sd->status.party_id=0; } } idb_remove(party_db,party_id); return 0; }
// パーティ除名要求 int party_removemember(dumb_ptr<map_session_data> sd, int account_id) { struct party *p; int i; nullpo_ret(sd); if ((p = party_search(sd->status.party_id)) == NULL) return 0; for (i = 0; i < MAX_PARTY; i++) { // リーダーかどうかチェック if (p->member[i].account_id == sd->status.account_id) if (p->member[i].leader == 0) return 0; } for (i = 0; i < MAX_PARTY; i++) { // 所属しているか調べる if (p->member[i].account_id == account_id) { intif_party_leave(p->party_id, account_id); return 0; } } return 0; }
void party_send_movemap(struct map_session_data *sd) { int i; struct party_data *p; if( sd->status.party_id==0 ) return; intif_party_changemap(sd,1); p=party_search(sd->status.party_id); if (!p) return; if(sd->state.connect_new) { //Note that this works because this function is invoked before connect_new is cleared. clif_party_option(p,sd,0x100); clif_party_info(p,sd); clif_party_member_info(p,sd); } if (sd->fd) { // synchronize minimap positions with the rest of the party for(i=0; i < MAX_PARTY; i++) { if (p->data[i].sd && p->data[i].sd != sd && p->data[i].sd->bl.m == sd->bl.m) { clif_party_xy_single(sd->fd, p->data[i].sd); clif_party_xy_single(p->data[i].sd->fd, sd); } } } return; }
// パーティメンバの移動 int party_send_movemap(dumb_ptr<map_session_data> sd) { struct party *p; nullpo_ret(sd); if (sd->status.party_id == 0) return 0; intif_party_changemap(sd, 1); if (sd->party_sended != 0) // もうパーティデータは送信済み return 0; // 競合確認 party_check_conflict(sd); // あるならパーティ情報送信 if ((p = party_search(sd->status.party_id)) != NULL) { party_check_member(p); // 所属を確認する if (sd->status.party_id == p->party_id) { clif_party_info(p, sd->fd); clif_party_option(p, sd, 0x100); sd->party_sended = 1; } } return 0; }
void party_booking_update(struct map_session_data *sd, short* job) { int i; struct party_data *p=party_search(sd->status.party_id); struct party_booking_ad_info *pb_ad; if (!check_party_leader(sd, p)) { return; } pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, p->party.party_id); if( pb_ad == NULL ) return; pb_ad->starttime = (int)time(NULL);// Update time. for(i=0;i<6;i++) if(job[i] != 0xFF) pb_ad->p_detail.job[i] = job[i]; else pb_ad->p_detail.job[i] = -1; clif_PartyBookingUpdateNotify(sd, pb_ad); return; }
void party_booking_register(struct map_session_data *sd, short level, short mapid, short* job) { struct party_booking_ad_info *pb_ad; struct party_data *p=party_search(sd->status.party_id); int i; if (!check_party_leader(sd, p)) { clif_PartyBookingRegisterAck(sd, 1); return; } pb_ad = (struct party_booking_ad_info*)idb_get(party_booking_db, p->party.party_id); if( pb_ad == NULL ) { pb_ad = create_party_booking_data(p->party.party_id); idb_put(party_booking_db, pb_ad->index, pb_ad); } memcpy(pb_ad->charname,sd->status.name,NAME_LENGTH); pb_ad->starttime = (int)time(NULL); pb_ad->p_detail.level = level; pb_ad->p_detail.mapid = mapid; for(i=0;i<6;i++) if(job[i] != 0xFF) pb_ad->p_detail.job[i] = job[i]; else pb_ad->p_detail.job[i] = -1; clif_PartyBookingRegisterAck(sd, 0); clif_PartyBookingInsertNotify(sd, pb_ad); // Notice clif_PartyBookingSearchAck(sd->fd, &pb_ad->index, 1, false); // Update Client! return; }
/// Party member 'sd' requesting kick of member with <account_id, name>. int party_removemember(struct map_session_data* sd, uint32 account_id, char* name) { struct party_data *p; int i; p = party_search(sd->status.party_id); if( p == NULL ) return 0; // check the requesting char's party membership ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id ); if( i == MAX_PARTY ) return 0; // request from someone not in party? o.O if( !p->party.member[i].leader ) return 0; // only party leader may remove members ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && strncmp(p->party.member[i].name,name,NAME_LENGTH) == 0 ); if( i == MAX_PARTY ) return 0; // no such char in party party_trade_bound_cancel(sd); intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id); return 1; }
/// Invoked (from char-server) when a party member leaves the party. int party_member_withdraw(int party_id, int account_id, int char_id) { struct map_session_data* sd = map_id2sd(account_id); struct party_data* p = party_search(party_id); int i; if( p ) { 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 ) { clif_party_withdraw(p,sd,account_id,p->party.member[i].name,0x00); 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); clif_party_info(p, NULL); } } if( sd && sd->status.party_id == party_id && sd->status.char_id == char_id ) { sd->status.party_id = 0; if( sd->state.spb ) { sd->state.spb = 0; clif_displaymessage(sd->fd, msg_txt(1451)); } clif_charnameupdate(sd); //Update name display [Skotlex] //TODO: hp bars should be cleared too if( p->instance_id ) instance_check_kick(sd); } return 0; }
// パーティ除名要求 int party_removemember(struct map_session_data *sd,int account_id,char *name) { struct party *p; int i; nullpo_retr(0, sd); if( (p = party_search(sd->status.party_id)) == NULL ) return 0; for(i=0;i<MAX_PARTY;i++){ // リーダーかどうかチェック if(p->member[i].account_id==sd->status.account_id && p->member[i].char_id==sd->status.char_id) { if(p->member[i].leader) break; return 0; } } if (i >= MAX_PARTY) //Request from someone not in party? o.O return 0; for(i=0;i<MAX_PARTY;i++){ // 所属しているか調べる if(p->member[i].account_id==account_id && strncmp(p->member[i].name,name,NAME_LENGTH)==0) { intif_party_leave(p->party_id,account_id,p->member[i].char_id); return 1; } } return 0; }
/// Invoked (from char-server) when a party member /// - changes maps /// - logs in or out /// - gains a level (disabled) int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv) { struct party_member* m; struct party_data* p; int i; p = party_search(party_id); if( p == NULL ) return 0; 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 ) { ShowError("party_recv_movemap: char %d/%d not found in party %s (id:%d)",account_id,char_id,p->party.name,party_id); return 0; } m = &p->party.member[i]; m->map = map; m->online = online; m->lv = lv; //Check if they still exist on this map server p->data[i].sd = party_sd_check(party_id, account_id, char_id); clif_party_info(p,NULL); return 0; }
/// Executes 'func' for each party member on the same map and in range (0:whole map) int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...) { struct party_data *p = NULL; struct battleground_data *bg = NULL; struct map_session_data *psd; int i,x0,y0,x1,y1; struct block_list *list[MAX_BG_MEMBERS]; int blockcount=0; int total = 0; //Return value. nullpo_retr(0,sd); if( map[sd->bl.m].flag.battleground && (bg = bg_team_search(sd->state.bg_id)) == NULL ) return 0; else if( !map[sd->bl.m].flag.battleground && (p = party_search(sd->status.party_id)) == NULL ) return 0; x0 = sd->bl.x-range; y0 = sd->bl.y-range; x1 = sd->bl.x+range; y1 = sd->bl.y+range; if( bg ) { for( i = 0; i < MAX_BG_MEMBERS; i++ ) { if( (psd = bg->members[i].sd) == NULL ) continue; if( psd->bl.m != sd->bl.m || !psd->bl.prev ) continue; if( range && (psd->bl.x < x0 || psd->bl.y < y0 || psd->bl.x > x1 || psd->bl.y > y1) ) continue; list[blockcount++] = &psd->bl; } } else if( p ) { for( i = 0; i < MAX_PARTY; i++ ) { if( (psd = p->data[i].sd) == NULL ) continue; if( psd->bl.m != sd->bl.m || !psd->bl.prev ) continue; if( range && (psd->bl.x < x0 || psd->bl.y < y0 || psd->bl.x > x1 || psd->bl.y > y1) ) continue; list[blockcount++] = &psd->bl; } } else return 0; map_freeblock_lock(); for( i = 0; i < blockcount; i++ ) { va_list ap; va_start(ap, range); total += func(list[i], ap); va_end(ap); } map_freeblock_unlock(); return total; }
int party_invite (struct map_session_data *sd, struct map_session_data *tsd) { struct party_data *p; int i; nullpo_ret (sd); if ( (p = party_search (sd->status.party_id)) == NULL) return 0; // confirm if this player is a party leader ARR_FIND (0, MAX_PARTY, i, p->data[i].sd == sd); if (i == MAX_PARTY || !p->party.member[i].leader) { clif_displaymessage (sd->fd, msg_txt (282)); return 0; } // confirm if there is an open slot in the party ARR_FIND (0, MAX_PARTY, i, p->party.member[i].account_id == 0); if (i == MAX_PARTY) { clif_party_inviteack (sd, (tsd ? tsd->status.name : ""), 3); return 0; } // confirm whether the account has the ability to invite before checking the player if (!pc_has_permission (sd, PC_PERM_PARTY) || (tsd && !pc_has_permission (tsd, PC_PERM_PARTY))) { clif_displaymessage (sd->fd, msg_txt (81)); // "Your GM level doesn't authorize you to preform this action on the specified player." return 0; } if (tsd == NULL) { clif_party_inviteack (sd, "", 7); return 0; } if (!battle_config.invite_request_check) { if (tsd->guild_invite > 0 || tsd->trade_partner || tsd->adopt_invite) { clif_party_inviteack (sd, tsd->status.name, 0); return 0; } } if (!tsd->fd) { //You can't invite someone who has already disconnected. clif_party_inviteack (sd, tsd->status.name, 1); return 0; } if (tsd->status.party_id > 0 || tsd->party_invite > 0) { // already associated with a party clif_party_inviteack (sd, tsd->status.name, 0); return 0; } tsd->party_invite = sd->status.party_id; tsd->party_invite_account = sd->status.account_id; clif_party_invite (sd, tsd); return 1; }
int party_changeleader(struct map_session_data *sd, struct map_session_data *tsd, struct party_data *p) { int mi, tmi; if ( !p ) { if (!sd || !sd->status.party_id) return -1; if (!tsd || tsd->status.party_id != sd->status.party_id) { clif_displaymessage(sd->fd, msg_txt(sd,283)); return -3; } if ( map[sd->bl.m].flag.partylock ) { clif_displaymessage(sd->fd, msg_txt(sd,287)); return 0; } if ((p = party_search(sd->status.party_id)) == NULL ) return -1; ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd ); if (mi == MAX_PARTY) return 0; // Shouldn't happen if (!p->party.member[mi].leader) { // Need to be a party leader. clif_displaymessage(sd->fd, msg_txt(sd,282)); return 0; } ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd); if (tmi == MAX_PARTY) return 0; // Shouldn't happen } else { ARR_FIND(0,MAX_PARTY,mi,p->party.member[mi].leader); if (mi == MAX_PARTY) return 0; // Shouldn't happen ARR_FIND(0,MAX_PARTY,tmi,p->data[tmi].sd == tsd); if (tmi == MAX_PARTY) return 0; // Shouldn't happen } // Change leadership. p->party.member[mi].leader = 0; p->party.member[tmi].leader = 1; // Update members clif_party_leaderchanged(p->data[mi].sd, p->data[mi].sd->status.account_id, p->data[tmi].sd->status.account_id); // Update info. intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id); clif_party_info(p,NULL); return 1; }
int party_recv_message(int party_id,int account_id,const char *mes,int len) { struct party_data *p; if( (p=party_search(party_id))==NULL) return 0; clif_party_message(p,account_id,mes,len); return 0; }
/// Invoked (from char-server) when a new member is added to the party. /// flag: 0-success, 1-failure int party_member_added (int party_id, int account_id, int char_id, int flag) { struct map_session_data *sd = map_id2sd (account_id), *sd2; struct party_data *p = party_search (party_id); int i; if (sd == NULL || sd->status.char_id != char_id || !sd->party_joining) { if (!flag) //Char logged off before being accepted into party. intif_party_leave (party_id, account_id, char_id); return 0; } sd2 = map_id2sd (sd->party_invite_account); sd->party_joining = false; sd->party_invite = 0; sd->party_invite_account = 0; if (!p) { ShowError ("party_member_added: party %d not found.\n", party_id); intif_party_leave (party_id, account_id, char_id); return 0; } if (flag) { // failed if (sd2 != NULL) clif_party_inviteack (sd2, sd->status.name, 3); return 0; } sd->status.party_id = party_id; clif_party_member_info (p, sd); clif_party_option (p, sd, 0x100); clif_party_info (p, sd); if (sd2 != NULL) clif_party_inviteack (sd2, sd->status.name, 2); for (i = 0; i < ARRAYLENGTH (p->data); ++i) { // hp of the other party members sd2 = p->data[i].sd; if (sd2 && sd2->status.account_id != account_id && sd2->status.char_id != char_id) clif_hpmeter_single (sd->fd, sd2->bl.id, sd2->battle_status.hp, sd2->battle_status.max_hp); } clif_party_hp (sd); clif_party_xy (sd); clif_charnameupdate (sd); //Update char name's display [Skotlex] if (p->instance_id) clif_instance_join (sd->fd, p->instance_id); return 0; }
bool party_booking_delete(struct map_session_data *sd, bool force_delete) { struct party_data *p=party_search(sd->status.party_id); if (!check_party_leader(sd, p) && !force_delete) { return false; } clif_PartyBookingDeleteNotify(sd, sd->status.party_id); idb_remove(party_booking_db,sd->status.party_id); return true; }
// パーティの設定変更要求 int party_changeoption(struct map_session_data *sd,int exp,int item) { struct party *p; nullpo_retr(0, sd); if( sd->status.party_id==0 || (p=party_search(sd->status.party_id))==NULL ) return 0; intif_party_changeoption(sd->status.party_id,sd->status.account_id,exp,item); return 0; }
int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id, uint16 skill_lv) { struct party_data *p; struct map_session_data *p_sd; int i; if(!party_id || (p = party_search(party_id)) == NULL) return 0; party_check_state(p); switch(skill_id) { case TK_COUNTER: //Increase Triple Attack rate of Monks. if (!p->state.monk) return 0; break; case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators if (!p->state.sg) return 0; break; case AM_TWILIGHT2: //Twilight Pharmacy, requires Super Novice return p->state.snovice; case AM_TWILIGHT3: //Twilight Pharmacy, Requires Taekwon return p->state.tk; default: return 0; //Unknown case? } for(i = 0; i < MAX_PARTY; i++) { if ((p_sd = p->data[i].sd) == NULL) continue; if (sd->bl.m != p_sd->bl.m) continue; switch(skill_id) { case TK_COUNTER: //Increase Triple Attack rate of Monks. if((p_sd->class_&MAPID_UPPERMASK) == MAPID_MONK && pc_checkskill(p_sd,MO_TRIPLEATTACK)) { sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK, 50+50*skill_lv, //+100/150/200% rate 0,0,skill_get_time(SG_FRIEND, 1)); } break; case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR && sd->sc.data[SC_READYCOUNTER] && pc_checkskill(p_sd,SG_FRIEND)) { sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER, 50+50*pc_checkskill(p_sd,SG_FRIEND), //+100/150/200% rate 0,0,skill_get_time(SG_FRIEND, 1)); } break; } } return 0; }
// パーティの設定変更通知 int party_optionchanged(int party_id,int account_id,int exp,int item,int flag) { struct party *p; struct map_session_data *sd=map_id2sd(account_id); if( (p=party_search(party_id))==NULL) return 0; if(!(flag&0x01)) p->exp=exp; if(!(flag&0x10)) p->item=item; clif_party_option(p,sd,flag); return 0; }
bool party_changeleader(struct map_session_data *sd, struct map_session_data *tsd) { struct party_data *p; int mi, tmi; if (!sd || !sd->status.party_id) return false; if (!tsd || tsd->status.party_id != sd->status.party_id) { clif_displaymessage(sd->fd, msg_txt(283)); return false; } if( map[sd->bl.m].flag.partylock ) { clif_displaymessage(sd->fd, "You cannot change party leaders on this map."); return false; } if ((p = party_search(sd->status.party_id)) == NULL) return false; ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd ); if (mi == MAX_PARTY) return false; //Shouldn't happen if (!p->party.member[mi].leader) { //Need to be a party leader. clif_displaymessage(sd->fd, msg_txt(282)); return false; } ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd); if (tmi == MAX_PARTY) return false; //Shouldn't happen //Change leadership. p->party.member[mi].leader = 0; if (p->data[mi].sd->fd) clif_displaymessage(p->data[mi].sd->fd, msg_txt(284)); p->party.member[tmi].leader = 1; if (p->data[tmi].sd->fd) clif_displaymessage(p->data[tmi].sd->fd, msg_txt(285)); //Update info. intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id); clif_party_info(p,NULL); party_booking_delete(sd, true); // Party Booking [Spiria] clif_PartyBookingDeleteAck(sd, 0); // Close small window return true; }
// パーティの設定変更要求 int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item) { PartyPair p; nullpo_retz(sd); if (!sd->status.party_id || !(p = party_search(sd->status.party_id))) return 0; intif_party_changeoption(sd->status.party_id, sd->status_key.account_id, exp, item); return 0; }
/*-------------------------------------- * Adds maps to the instance *--------------------------------------*/ int instance_addmap(short instance_id) { int i, m; int cnt_map = 0; struct instance_data *im; struct instance_db *db; struct party_data *p; if(instance_id <= 0) return 0; im = &instance_data[instance_id]; // If the instance isn't idle, we can't do anything if(im->state != INSTANCE_IDLE) return 0; if((db = instance_searchtype_db(im->type)) == NULL) return 0; // Set to busy, update timers im->state = INSTANCE_BUSY; im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT / 1000; im->idle_timer = add_timer(gettick() + INSTANCE_LIMIT, instance_delete_timer, instance_id, 0); // Add the maps for(i = 0; i < db->maplist_count; i++) { if(strlen(StringBuf_Value(db->maplist[i])) < 1) continue; else if((m = map_addinstancemap(StringBuf_Value(db->maplist[i]), instance_id)) < 0) { // An error occured adding a map ShowError("instance_addmap: No maps added to instance %d.\n",instance_id); return 0; } else { im->map[cnt_map].m = m; im->map[cnt_map].src_m = map_mapname2mapid(StringBuf_Value(db->maplist[i])); cnt_map++; } } im->cnt_map = cnt_map; // Create NPCs on all maps instance_addnpc(im); // Inform party members of the created instance if((p = party_search(im->party_id)) != NULL) clif_instance_status(party_getavailablesd(p), StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 1); return cnt_map; }
bool party_changeleader(struct map_session_data *sd, struct map_session_data *tsd) { struct party_data *p; int mi, tmi; if (!sd || !sd->status.party_id) return false; if (!tsd || tsd->status.party_id != sd->status.party_id) { clif->message(sd->fd, msg_txt(283)); return false; } if( map[sd->bl.m].flag.partylock ) { clif->message(sd->fd, msg_txt(287)); return false; } if ((p = party_search(sd->status.party_id)) == NULL) return false; ARR_FIND( 0, MAX_PARTY, mi, p->data[mi].sd == sd ); if (mi == MAX_PARTY) return false; //Shouldn't happen if (!p->party.member[mi].leader) { //Need to be a party leader. clif->message(sd->fd, msg_txt(282)); return false; } ARR_FIND( 0, MAX_PARTY, tmi, p->data[tmi].sd == tsd); if (tmi == MAX_PARTY) return false; //Shouldn't happen //Change leadership. p->party.member[mi].leader = 0; if (p->data[mi].sd->fd) clif->message(p->data[mi].sd->fd, msg_txt(284)); p->party.member[tmi].leader = 1; if (p->data[tmi].sd->fd) clif->message(p->data[tmi].sd->fd, msg_txt(285)); //Update info. intif_party_leaderchange(p->party.party_id,p->party.member[tmi].account_id,p->party.member[tmi].char_id); clif->party_info(p,NULL); return true; }
/// Executes 'func' for each party member on the same map and in range (0:whole map) int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...) { struct party_data *p; int i; int x0,y0,x1,y1; struct block_list *list[MAX_PARTY]; int blockcount=0; int total = 0; //Return value. nullpo_ret(sd); if((p = party_search(sd->status.party_id)) == NULL) return 0; x0 = sd->bl.x-range; y0 = sd->bl.y-range; x1 = sd->bl.x+range; y1 = sd->bl.y+range; for(i = 0; i < MAX_PARTY; i++) { struct map_session_data *psd = p->data[i].sd; if(!psd) continue; if(psd->bl.m!=sd->bl.m || !psd->bl.prev) continue; if(range && (psd->bl.x<x0 || psd->bl.y<y0 || psd->bl.x>x1 || psd->bl.y>y1 ) ) continue; list[blockcount++]=&psd->bl; } map_freeblock_lock(); for(i = 0; i < blockcount; i++) { va_list ap; va_start(ap, range); total += func(list[i], ap); va_end(ap); } map_freeblock_unlock(); return total; }
/*-------------------------------------- * Removes a instance, all its maps and npcs. *--------------------------------------*/ void instance_destroy(int instance_id) { int last = 0, type; struct party_data *p; time_t now = time(NULL); if( !instance_is_valid(instance_id) ) return; // nothing to do if( instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now ) type = 1; else if( instance[instance_id].idle_timeout && instance[instance_id].idle_timeout <= now ) type = 2; else type = 3; clif_instance(instance_id, 5, type); // Report users this instance has been destroyed while( instance[instance_id].num_map && last != instance[instance_id].map[0] ) { // Remove all maps from instance last = instance[instance_id].map[0]; instance_del_map( instance[instance_id].map[0] ); } if( instance[instance_id].ivar ) linkdb_final( &instance[instance_id].ivar ); // Remove numeric vars if( instance[instance_id].svar ) { // Remove string vars linkdb_foreach( &instance[instance_id].svar, instance_destroy_freesvar ); linkdb_final( &instance[instance_id].svar ); } if( instance[instance_id].progress_timer != INVALID_TIMER ) delete_timer( instance[instance_id].progress_timer, instance_destroy_timer); if( instance[instance_id].idle_timer != INVALID_TIMER ) delete_timer( instance[instance_id].idle_timer, instance_destroy_timer); instance[instance_id].ivar = NULL; instance[instance_id].svar = NULL; if( instance[instance_id].party_id && (p = party_search(instance[instance_id].party_id)) != NULL ) p->instance_id = 0; // Update Party information ShowInfo("[Instance] Destroyed %s.\n", instance[instance_id].name); memset( &instance[instance_id], 0x00, sizeof(instance[0]) ); instance[instance_id].state = INSTANCE_FREE; }