예제 #1
0
파일: party.cpp 프로젝트: AlmasB/rathena
/// 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,uint32 account_id,uint32 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,"",PARTY_MEMBER_WITHDRAW_LEAVE);
		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,"",PARTY_MEMBER_WITHDRAW_LEAVE);
		return 0;
	}

	if( flag ) { // failed
		if( sd2 != NULL )
			clif_party_invite_reply(sd2,sd->status.name,PARTY_REPLY_FULL);
		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_invite_reply(sd2,sd->status.name,PARTY_REPLY_ACCEPTED);

	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_name_area(&sd->bl); //Update char name's display [Skotlex]

	if( p->instance_id )
		instance_reqinfo(sd,p->instance_id);

	return 0;
}
예제 #2
0
파일: party.cpp 프로젝트: AlmasB/rathena
/// 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;
}
예제 #3
0
/**
* Acknowledge change name request from inter-server
* @param sd
* @param name
* @param flag
*/
void hom_change_name_ack(struct map_session_data *sd, char* name, int flag)
{
	struct homun_data *hd = sd->hd;
	if (!hom_is_active(hd))
		return;

	normalize_name(name," ");//bugreport:3032

	if (!flag || name[0] == '\0') {
		clif_displaymessage(sd->fd, msg_txt(sd,280)); // You cannot use this name
		return;
	}
	safestrncpy(hd->homunculus.name,name,NAME_LENGTH);
	clif_name_area(&hd->bl);
	hd->homunculus.rename_flag = 1;
	clif_hominfo(sd,hd,0);
}
예제 #4
0
파일: party.cpp 프로젝트: AlmasB/rathena
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;
	bool rename = false;

	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;
			// If the member already existed, compare the old to the (possible) new name
			else if( !rename && strcmp(member->name,sp->member[i].name) )
				rename = true;
		}

		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, sd->status.name, PARTY_MEMBER_WITHDRAW_LEAVE);
	}

	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_name_area(&sd->bl); //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 a player was renamed, make sure to resend the party information
	if( rename ){
		clif_party_info(p,NULL);
	}

	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;
}