/*========================================== * Divorce players * only used if 'partner_id' is offline *------------------------------------------*/ int chrif_divorceack(int char_id, int partner_id) { struct map_session_data* sd; int i; if( !char_id || !partner_id ) return 0; if( (sd = map_charid2sd(char_id)) != NULL && sd->status.partner_id == partner_id ) { sd->status.partner_id = 0; for(i = 0; i < MAX_INVENTORY; i++) if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); } if( (sd = map_charid2sd(partner_id)) != NULL && sd->status.partner_id == char_id ) { sd->status.partner_id = 0; for(i = 0; i < MAX_INVENTORY; i++) if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); } return 0; }
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr data) { struct party_data* p; DBIterator* iter = party_db->iterator(party_db); // for each existing party, for( p = (struct party_data*)iter->first(iter,NULL); iter->exists(iter); p = (struct party_data*)iter->next(iter,NULL) ) { int i; // for each member of this party, for( i = 0; i < MAX_PARTY; i++ ) { //struct map_session_data* sd = p->data[i].sd; struct map_session_data* sd = map_charid2sd(p->party.member[i].char_id); //temporary crashfix if( !sd ) continue; if( p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y ) {// perform position update clif_party_xy(sd); p->data[i].x = sd->bl.x; p->data[i].y = sd->bl.y; } if (battle_config.party_hp_mode && p->data[i].hp != sd->battle_status.hp) {// perform hp update clif_party_hp(sd); p->data[i].hp = sd->battle_status.hp; } } } iter->destroy(iter); return 0; }
/** * Inter-serv has sent us the elemental data from sql, fill it in map-serv memory * @param ele : The elemental data received from char-serv * @param flag : 0:not created, 1:was saved/loaded * @return 0:failed, 1:sucess */ int elemental_data_received(struct s_elemental *ele, bool flag) { struct map_session_data *sd; struct elemental_data *ed; struct s_elemental_db *db; int i = elemental_search_index(ele->class_); if( (sd = map_charid2sd(ele->char_id)) == NULL ) return 0; if( !flag || i < 0 ) { // Not created - loaded - DB info sd->status.ele_id = 0; return 0; } db = &elemental_db[i]; if( !sd->ed ) { // Initialize it after first summon. sd->ed = ed = (struct elemental_data*)aCalloc(1,sizeof(struct elemental_data)); ed->bl.type = BL_ELEM; ed->bl.id = npc_get_new_npc_id(); ed->master = sd; ed->db = db; memcpy(&ed->elemental, ele, sizeof(struct s_elemental)); status_set_viewdata(&ed->bl, ed->elemental.class_); ed->vd->head_mid = 10; // Why? status_change_init(&ed->bl); unit_dataset(&ed->bl); ed->ud.dir = sd->ud.dir; ed->bl.m = sd->bl.m; ed->bl.x = sd->bl.x; ed->bl.y = sd->bl.y; unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir); ed->bl.x = ed->ud.to_x; ed->bl.y = ed->ud.to_y; map_addiddb(&ed->bl); status_calc_elemental(ed,SCO_FIRST); ed->last_spdrain_time = ed->last_thinktime = gettick(); ed->summon_timer = INVALID_TIMER; ed->masterteleport_timer = INVALID_TIMER; elemental_summon_init(ed); } else { memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental)); ed = sd->ed; } sd->status.ele_id = ele->elemental_id; if( ed->bl.prev == NULL && sd->bl.prev != NULL ) { if(map_addblock(&ed->bl)) return 0; clif_spawn(&ed->bl); clif_elemental_info(sd); clif_elemental_updatestatus(sd,SP_HP); clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.max_hp); clif_elemental_updatestatus(sd,SP_SP); } return 1; }
/** * Received mercenary data from char-serv * @param merc : mercenary datas * @param flag : if inter-serv request was sucessfull * @return false:failure, true:sucess */ bool mercenary_recv_data(struct s_mercenary *merc, bool flag) { struct map_session_data *sd; struct mercenary_data *md; struct s_mercenary_db *db; int i = mercenary_search_index(merc->class_); if( (sd = map_charid2sd(merc->char_id)) == NULL ) return false; if( !flag || i < 0 ) { // Not created - loaded - DB info sd->status.mer_id = 0; return false; } db = &mercenary_db[i]; if( !sd->md ) { sd->md = md = (struct mercenary_data*)aCalloc(1,sizeof(struct mercenary_data)); md->bl.type = BL_MER; md->bl.id = npc_get_new_npc_id(); md->devotion_flag = 0; md->master = sd; md->db = db; memcpy(&md->mercenary, merc, sizeof(struct s_mercenary)); status_set_viewdata(&md->bl, md->mercenary.class_); status_change_init(&md->bl); unit_dataset(&md->bl); md->ud.dir = sd->ud.dir; md->bl.m = sd->bl.m; md->bl.x = sd->bl.x; md->bl.y = sd->bl.y; unit_calc_pos(&md->bl, sd->bl.x, sd->bl.y, sd->ud.dir); md->bl.x = md->ud.to_x; md->bl.y = md->ud.to_y; map_addiddb(&md->bl); status_calc_mercenary(md, SCO_FIRST); md->contract_timer = INVALID_TIMER; md->masterteleport_timer = INVALID_TIMER; merc_contract_init(md); } else { memcpy(&sd->md->mercenary, merc, sizeof(struct s_mercenary)); md = sd->md; } if( sd->status.mer_id == 0 ) mercenary_set_calls(md, 1); sd->status.mer_id = merc->mercenary_id; if( md && md->bl.prev == NULL && sd->bl.prev != NULL ) { if(map_addblock(&md->bl)) return false; clif_spawn(&md->bl); clif_mercenary_info(sd); clif_mercenary_skillblock(sd); } return true; }
/// Invoked (from char-server) when the party info is not found int party_recv_noinfo(int party_id, int char_id) { party_broken(party_id); if (char_id != 0) { // Requester struct map_session_data *sd = map_charid2sd(char_id); if (sd && sd->status.party_id == party_id) sd->status.party_id = 0; } return 0; }
/*========================================== * Removes Baby from parents *------------------------------------------*/ int chrif_deadopt(int father_id, int mother_id, int child_id) { struct map_session_data* sd; if( father_id && ( sd = map_charid2sd(father_id) ) != NULL && sd->status.child == child_id ) { sd->status.child = 0; sd->status.skill[WE_CALLBABY].id = 0; sd->status.skill[WE_CALLBABY].lv = 0; sd->status.skill[WE_CALLBABY].flag = 0; clif_deleteskill(sd,WE_CALLBABY); } if( mother_id && ( sd = map_charid2sd(mother_id) ) != NULL && sd->status.child == child_id ) { sd->status.child = 0; sd->status.skill[WE_CALLBABY].id = 0; sd->status.skill[WE_CALLBABY].lv = 0; sd->status.skill[WE_CALLBABY].flag = 0; clif_deleteskill(sd,WE_CALLBABY); } return 0; }
/// Invoked (from char-server) when a party member leaves the party. int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type) { struct map_session_data* sd = map_charid2sd(char_id); struct party_data* p = party_search(party_id); if( p ) { int i; clif_party_withdraw(party_getavailablesd(p), account_id, name, type, PARTY); 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 ) { 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 ) { #ifdef BOUND_ITEMS int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion int j,i; party_trade_bound_cancel(sd); j = pc_bound_chk(sd,BOUND_PARTY,idxlist); for(i = 0; i < j; i++) pc_delitem(sd,idxlist[i],sd->inventory.u.items_inventory[idxlist[i]].amount,0,1,LOG_TYPE_BOUND_REMOVAL); #endif sd->status.party_id = 0; clif_name_area(&sd->bl); //Update name display [Skotlex] //TODO: hp bars should be cleared too if( p->instance_id ) { struct map_data *mapdata = map_getmapdata(sd->bl.m); if( mapdata->instance_id ) { // User was on the instance map if( mapdata->save.map ) pc_setpos(sd, mapdata->save.map, mapdata->save.x, mapdata->save.y, CLR_TELEPORT); else pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); } } } return 0; }
/*========================================== * 離婚情報同期要求 *------------------------------------------*/ int chrif_divorce(int char_id, int partner_id) { struct map_session_data* sd; int i; if (!char_id || !partner_id || (sd = map_charid2sd(partner_id)) == NULL || sd->status.partner_id != char_id) return 0; //離婚(相方は既にキャラが消えている筈なので) sd->status.partner_id = 0; //相方の結婚指輪を剥奪 for(i = 0; i < MAX_INVENTORY; i++) if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) pc_delitem(sd, i, 1, 0); return 0; }
int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, const char* name, const char* mes) { int i; struct guild* g = guild_search(guild_id); struct map_session_data* sd = map_charid2sd(char_id); struct map_session_data* online_member_sd; if(g == NULL) return 0; // no such guild (error!) i = guild_getindex(g, account_id, char_id); if( i == -1 ) return 0; // not a member (inconsistency!) online_member_sd = guild_getavailablesd(g); if(online_member_sd == NULL) return 0; // noone online to inform if(!flag) clif_guild_leave(online_member_sd, name, mes); else clif_guild_expulsion(online_member_sd, name, mes, account_id); // remove member from guild memset(&g->member[i],0,sizeof(struct guild_member)); clif_guild_memberlist(online_member_sd); // update char, if online if(sd != NULL && sd->status.guild_id == guild_id) { // do stuff that needs the guild_id first, BEFORE we wipe it if (sd->state.storage_flag == 2) //Close the guild storage. storage_guild_storageclose(sd); guild_send_dot_remove(sd); sd->status.guild_id = 0; sd->guild_emblem_id = 0; clif_charnameupdate(sd); //Update display name [Skotlex] //TODO: send emblem update to self and people around } return 0; }
//Taken from party_send_xy_timer_sub. [Skotlex] int guild_send_xy_timer_sub(DBKey key,void *data,va_list ap) { struct guild *g=(struct guild *)data; int i; nullpo_ret(g); for(i=0;i<g->max_member;i++){ //struct map_session_data* sd = g->member[i].sd; struct map_session_data* sd = map_charid2sd(g->member[i].char_id); // temporary crashfix if( sd != NULL && (sd->guild_x != sd->bl.x || sd->guild_y != sd->bl.y) && !sd->bg_id ) { clif_guild_xy(sd); sd->guild_x = sd->bl.x; sd->guild_y = sd->bl.y; } } return 0; }
int guild_member_leaved(int guild_id,int account_id,int char_id,int flag, const char *name,const char *mes) // rewrote [LuzZza] { int i; struct guild *g = guild_search(guild_id); struct map_session_data *sd = map_charid2sd(char_id); struct map_session_data *online_member_sd; if(g == NULL) return 0; for(i=0;i<g->max_member;i++) { if( g->member[i].account_id == account_id && g->member[i].char_id == char_id ){ if((online_member_sd = guild_getavailablesd(g)) == NULL) return 0; if(!flag) clif_guild_leave(online_member_sd, name, mes); else clif_guild_expulsion(online_member_sd, name, mes, account_id); memset(&g->member[i],0,sizeof(struct guild_member)); clif_guild_memberlist(online_member_sd); if(sd != NULL && sd->status.guild_id == guild_id) { if (sd->state.storage_flag == 2) //Close the guild storage. storage_guild_storageclose(sd); sd->status.guild_id=0; sd->guild_emblem_id=0; sd->state.guild_sent=0; guild_send_dot_remove(sd); clif_charnameupdate(sd); //Update display name [Skotlex] } return 0; } } return 0; }
int party_recv_info(struct party* sp, uint32 char_id) { struct party_data* p; struct party_member* member; struct map_session_data* sd; int removed[MAX_PARTY];// member_id in old data int removed_count = 0; int added[MAX_PARTY];// member_id in new data int added_count = 0; int member_id; nullpo_ret(sp); p = (struct party_data*)idb_get(party_db, sp->party_id); if( p != NULL ) { // diff members int i; for( member_id = 0; member_id < MAX_PARTY; ++member_id ) { member = &p->party.member[member_id]; if( member->char_id == 0 ) continue; // empty 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 ) removed[removed_count++] = member_id; } for( member_id = 0; member_id < MAX_PARTY; ++member_id ) { member = &sp->member[member_id]; if( member->char_id == 0 ) continue; // empty ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == member->account_id && p->party.member[i].char_id == member->char_id); if( i == MAX_PARTY ) added[added_count++] = member_id; } } else { for( member_id = 0; member_id < MAX_PARTY; ++member_id ) if( sp->member[member_id].char_id != 0 ) added[added_count++] = member_id; CREATE(p, struct party_data, 1); idb_put(party_db, sp->party_id, p); } while( removed_count > 0 ) { // no longer in party member_id = removed[--removed_count]; sd = p->data[member_id].sd; if( sd == NULL ) 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)); for( member_id = 0; member_id < MAX_PARTY; member_id++ ) { member = &p->party.member[member_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); } party_check_state(p); while( added_count > 0 ) { // new in party member_id = added[--added_count]; sd = p->data[member_id].sd; if( sd == NULL ) continue;// not online clif_charnameupdate(sd); //Update other people's display. [Skotlex] clif_party_member_info(p,sd); // Only send this on party creation, otherwise it will be sent by party_send_movemap [Lemongrass] if( sd->party_creating ){ clif_party_option(p,sd,0x100); } clif_party_info(p,NULL); if( p->instance_id != 0 ) instance_reqinfo(sd,p->instance_id); } if( char_id != 0 ) { // requester sd = map_charid2sd(char_id); if( sd && sd->status.party_id == sp->party_id && party_getmemberid(p,sd) == -1 ) sd->status.party_id = 0;// was not in the party } return 0; }