Exemple #1
0
/**
 * Handles the save request from mapserver for a character's questlog.
 *
 * Received quests are saved, and an ack is sent back to the map server.
 *
 * @see inter_parse_frommap
 */
int mapif_parse_quest_save(int fd) {
	int i, j, k, old_n, new_n = (RFIFOW(fd,2)-8)/sizeof(struct quest);
	int char_id = RFIFOL(fd,4);
	struct quest *old_qd = NULL, *new_qd = NULL;
	bool success = true;

	if (new_n > 0)
		new_qd = (struct quest*)RFIFOP(fd,8);

	old_qd = mapif_quests_fromsql(char_id, &old_n);

	for (i = 0; i < new_n; i++) {
		ARR_FIND( 0, old_n, j, new_qd[i].quest_id == old_qd[j].quest_id );
		if (j < old_n) {
			// Update existing quests

			// Only states and counts are changeable.
			ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, new_qd[i].count[k] != old_qd[j].count[k] );
			if (k != MAX_QUEST_OBJECTIVES || new_qd[i].state != old_qd[j].state)
				success &= mapif_quest_update(char_id, new_qd[i]);

			if (j < (--old_n)) {
				// Compact array
				memmove(&old_qd[j],&old_qd[j+1],sizeof(struct quest)*(old_n-j));
				memset(&old_qd[old_n], 0, sizeof(struct quest));
			}
		} else {
			// Add new quests
			success &= mapif_quest_add(char_id, new_qd[i]);
		}
	}

	for (i = 0; i < old_n; i++) // Quests not in new_qd but in old_qd are to be erased.
		success &= mapif_quest_delete(char_id, old_qd[i].quest_id);

	if (old_qd)
		aFree(old_qd);

	// Send ack
	WFIFOHEAD(fd,7);
	WFIFOW(fd,0) = 0x3861;
	WFIFOL(fd,2) = char_id;
	WFIFOB(fd,6) = success?1:0;
	WFIFOSET(fd,7);

	return 0;
}
Exemple #2
0
//Save quests
int mapif_parse_quest_save(int fd)
{
	int i, j, k, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest);
	int char_id = RFIFOL(fd,4);
	struct quest qd1[MAX_QUEST_DB],qd2[MAX_QUEST_DB];
	bool success = true;

	memset(qd1, 0, sizeof(qd1));
	memset(qd2, 0, sizeof(qd2));
	if( num1 ) memcpy(&qd1, RFIFOP(fd,8), RFIFOW(fd,2)-8);
	num2 = mapif_quests_fromsql(char_id, qd2);

	for( i = 0; i < num1; i++ )
	{
		ARR_FIND( 0, num2, j, qd1[i].quest_id == qd2[j].quest_id );
		if( j < num2 ) // Update existed quests
		{	// Only states and counts are changable.
			ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, qd1[i].count[k] != qd2[j].count[k] );
			if( k != MAX_QUEST_OBJECTIVES || qd1[i].state != qd2[j].state )
				success &= mapif_quest_update(char_id, qd1[i]);

			if( j < (--num2) )
			{
				memmove(&qd2[j],&qd2[j+1],sizeof(struct quest)*(num2-j));
				memset(&qd2[num2], 0, sizeof(struct quest));
			}

		}
		else // Add new quests
			success &= mapif_quest_add(char_id, qd1[i]);
	}

	for( i = 0; i < num2; i++ ) // Quests not in qd1 but in qd2 are to be erased.
		success &= mapif_quest_delete(char_id, qd2[i].quest_id);

	WFIFOHEAD(fd,7);
	WFIFOW(fd,0) = 0x3861;
	WFIFOL(fd,2) = char_id;
	WFIFOB(fd,6) = success?1:0;
	WFIFOSET(fd,7);

	return 0;
}