/** * 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; }
//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; }
/** * Sends questlog to the map server * * Note: Completed quests (state == Q_COMPLETE) are guaranteed to be sent last * and the map server relies on this behavior (once the first Q_COMPLETE quest, * all of them are considered to be Q_COMPLETE) * * @see inter_parse_frommap */ int mapif_parse_quest_load(int fd) { int char_id = RFIFOL(fd,2); struct quest *tmp_questlog = NULL; int num_quests; tmp_questlog = mapif_quests_fromsql(char_id, &num_quests); WFIFOHEAD(fd,num_quests*sizeof(struct quest)+8); WFIFOW(fd,0) = 0x3860; WFIFOW(fd,2) = num_quests*sizeof(struct quest)+8; WFIFOL(fd,4) = char_id; if (num_quests > 0) memcpy(WFIFOP(fd,8), tmp_questlog, sizeof(struct quest)*num_quests); WFIFOSET(fd,num_quests*sizeof(struct quest)+8); if (tmp_questlog) aFree(tmp_questlog); return 0; }
//Send questlog to map server int mapif_parse_quest_load(int fd) { int char_id = RFIFOL(fd,2); struct quest tmp_questlog[MAX_QUEST_DB]; int num_quests, i, num_complete = 0; int complete[MAX_QUEST_DB]; memset(tmp_questlog, 0, sizeof(tmp_questlog)); memset(complete, 0, sizeof(complete)); num_quests = mapif_quests_fromsql(char_id, tmp_questlog); WFIFOHEAD(fd,num_quests*sizeof(struct quest)+8); WFIFOW(fd,0) = 0x3860; WFIFOW(fd,2) = num_quests*sizeof(struct quest)+8; WFIFOL(fd,4) = char_id; //Active and inactive quests for( i = 0; i < num_quests; i++ ) { if( tmp_questlog[i].state == Q_COMPLETE ) { complete[num_complete++] = i; continue; } memcpy(WFIFOP(fd,(i-num_complete)*sizeof(struct quest)+8), &tmp_questlog[i], sizeof(struct quest)); } // Completed quests for( i = num_quests - num_complete; i < num_quests; i++ ) memcpy(WFIFOP(fd,i*sizeof(struct quest)+8), &tmp_questlog[complete[i-num_quests+num_complete]], sizeof(struct quest)); WFIFOSET(fd,num_quests*sizeof(struct quest)+8); return 0; }