diff --git a/src/map/clif.c b/src/map/clif.c index a44138e6a5..1082af85e8 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -15398,7 +15398,7 @@ void clif_quest_send_mission(struct map_session_data * sd) WFIFOL(fd, 4) = sd->avail_quests; for( i = 0; i < sd->avail_quests; i++ ) { - struct quest_db *qi = quest_db(sd->quest_log[i].quest_id); + struct quest_db *qi = quest_search(sd->quest_log[i].quest_id); WFIFOL(fd, i*104+8) = sd->quest_log[i].quest_id; WFIFOL(fd, i*104+12) = sd->quest_log[i].time - qi->time; @@ -15423,7 +15423,7 @@ void clif_quest_add(struct map_session_data * sd, struct quest * qd) { int fd = sd->fd; int i; - struct quest_db *qi = quest_db(qd->quest_id); + struct quest_db *qi = quest_search(qd->quest_id); WFIFOHEAD(fd, packet_len(0x2b3)); WFIFOW(fd, 0) = 0x2b3; @@ -15464,7 +15464,7 @@ void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd { int fd = sd->fd; int i; - struct quest_db *qi = quest_db(qd->quest_id); + struct quest_db *qi = quest_search(qd->quest_id); int len = qi->num_objectives * 12 + 6; WFIFOHEAD(fd, len); diff --git a/src/map/intif.c b/src/map/intif.c index add5162ed7..8ee77fb64e 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -1910,7 +1910,7 @@ void intif_parse_questlog(int fd) CREATE(sd->quest_log, struct quest, num_received); for(i = 0; i < num_received; i++) { - if(quest_db(received[i].quest_id) == &quest_dummy) { + if(quest_search(received[i].quest_id) == &quest_dummy) { ShowError("intif_parse_QuestLog: quest %d not found in DB.\n", received[i].quest_id); continue; } diff --git a/src/map/quest.c b/src/map/quest.c index 3f9c24d623..c4facd4a8b 100644 --- a/src/map/quest.c +++ b/src/map/quest.c @@ -16,17 +16,19 @@ #include +static DBMap *questdb; + /** * Searches a quest by ID. * @param quest_id : ID to lookup * @return Quest entry (equals to &quest_dummy if the ID is invalid) */ -struct quest_db *quest_db(int quest_id) +struct quest_db *quest_search(int quest_id) { - if( quest_id < 0 || quest_id > MAX_QUEST_DB || quest_db_data[quest_id] == NULL ) - return &quest_dummy; - - return quest_db_data[quest_id]; + struct quest_db *quest = (struct quest_db *)idb_get(questdb, quest_id); + if (!quest) + return &quest_dummy; + return quest; } /** @@ -61,7 +63,7 @@ int quest_pc_login(TBL_PC *sd) int quest_add(TBL_PC *sd, int quest_id) { int n; - struct quest_db *qi = quest_db(quest_id); + struct quest_db *qi = quest_search(quest_id); if( qi == &quest_dummy ) { ShowError("quest_add: quest %d not found in DB.\n", quest_id); @@ -111,7 +113,7 @@ int quest_add(TBL_PC *sd, int quest_id) int quest_change(TBL_PC *sd, int qid1, int qid2) { int i; - struct quest_db *qi = quest_db(qid2); + struct quest_db *qi = quest_search(qid2); if( qi == &quest_dummy ) { ShowError("quest_change: quest %d not found in DB.\n", qid2); @@ -236,7 +238,7 @@ void quest_update_objective(TBL_PC *sd, int mob) if( sd->quest_log[i].state != Q_ACTIVE ) // Skip inactive quests continue; - qi = quest_db(sd->quest_log[i].quest_id); + qi = quest_search(sd->quest_log[i].quest_id); for( j = 0; j < qi->num_objectives; j++ ) { if( qi->mob[j] == mob && sd->quest_log[i].count[j] < qi->count[j] ) { @@ -322,7 +324,7 @@ int quest_check(TBL_PC *sd, int quest_id, enum quest_check_type type) case HUNTING: if( sd->quest_log[i].state == Q_INACTIVE || sd->quest_log[i].state == Q_ACTIVE ) { int j; - struct quest_db *qi = quest_db(sd->quest_log[i].quest_id); + struct quest_db *qi = quest_search(sd->quest_log[i].quest_id); ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < qi->count[j]); if( j == MAX_QUEST_OBJECTIVES ) @@ -349,15 +351,13 @@ int quest_read_db(void) "", DBIMPORT"/", }; - int f; + uint8 f; for (f = 0; f < ARRAYLENGTH(dbsubpath); f++) { FILE *fp; char line[1024]; - int i, count = 0; - char *str[20], *p, *np; + uint32 count = 0; char filename[256]; - struct quest_db entry; sprintf(filename, "%s/%s%s", db_path, dbsubpath[f], "quest_db.txt"); if( (fp = fopen(filename, "r")) == NULL ) { @@ -368,6 +368,10 @@ int quest_read_db(void) } while( fgets(line, sizeof(line), fp) ) { + struct quest_db *quest = NULL, entry; + char *str[9], *p, *np; + uint8 i; + if( line[0] == '/' && line[1] == '/' ) continue; @@ -389,31 +393,36 @@ int quest_read_db(void) if( str[0] == NULL ) continue; - memset(&entry, 0, sizeof(entry)); - + memset(&entry, 0, sizeof(struct quest_db)); entry.id = atoi(str[0]); - if( entry.id < 0 || entry.id >= MAX_QUEST_DB ) { - ShowError("quest_read_db: Invalid quest ID '%d' in line '%s' (min: 0, max: %d.)\n", entry.id, line, MAX_QUEST_DB); + if( entry.id < 0 || entry.id >= INT_MAX ) { + ShowError("quest_read_db: Invalid quest ID '%d' in line '%s' (min: 0, max: %d.)\n", entry.id, line, INT_MAX); continue; } + if (!(quest = (struct quest_db *)idb_get(questdb, entry.id))) { + CREATE(quest, struct quest_db, 1); + } + entry.time = atoi(str[1]); for( i = 0; i < MAX_QUEST_OBJECTIVES; i++ ) { - entry.mob[i] = atoi(str[2 * i + 2]); - entry.count[i] = atoi(str[2 * i + 3]); + entry.mob[i] = (uint16)atoi(str[2 * i + 2]); + entry.count[i] = (uint16)atoi(str[2 * i + 3]); if( !entry.mob[i] || !entry.count[i] ) break; } - entry.num_objectives = i; - if( quest_db_data[entry.id] == NULL ) - quest_db_data[entry.id] = aMalloc(sizeof(struct quest_db)); + //StringBuf_Init(&entry.name); + //StringBuf_Printf(&entry.name, "%s", str[7]); - memcpy(quest_db_data[entry.id], &entry, sizeof(struct quest_db)); + if (!quest->id) { + memcpy(quest, &entry, sizeof(entry)); + idb_put(questdb, quest->id, quest); + } count++; } @@ -439,7 +448,7 @@ int quest_reload_check_sub(struct map_session_data *sd, va_list ap) j = 0; for( i = 0; i < sd->num_quests; i++ ) { - struct quest_db *qi = quest_db(sd->quest_log[i].quest_id); + struct quest_db *qi = quest_search(sd->quest_log[i].quest_id); if( qi == &quest_dummy ) { //Remove no longer existing entries if( sd->quest_log[i].state != Q_COMPLETE ) //And inform the client if necessary @@ -465,16 +474,15 @@ int quest_reload_check_sub(struct map_session_data *sd, va_list ap) /** * Clears the quest database for shutdown or reload. */ -void quest_clear_db(void) -{ - int i; - for( i = 0; i < MAX_QUEST_DB; i++ ) { - if( quest_db_data[i] ) { - aFree(quest_db_data[i]); - quest_db_data[i] = NULL; - } - } +static int questdb_free(DBKey key, DBData *data, va_list ap) { + struct quest_db *quest = db_data2ptr(data); + if (!quest) + return 0; + //if (&quest->name) + // StringBuf_Destroy(&quest->name); + aFree(quest); + return 1; } /** @@ -482,6 +490,7 @@ void quest_clear_db(void) */ void do_init_quest(void) { + questdb = idb_alloc(DB_OPT_BASE); quest_read_db(); } @@ -491,8 +500,7 @@ void do_init_quest(void) void do_final_quest(void) { memset(&quest_dummy, 0, sizeof(quest_dummy)); - - quest_clear_db(); + questdb->destroy(questdb, questdb_free); } /** @@ -501,8 +509,7 @@ void do_final_quest(void) void do_reload_quest(void) { memset(&quest_dummy, 0, sizeof(quest_dummy)); - - quest_clear_db(); + questdb->clear(questdb, questdb_free); quest_read_db(); diff --git a/src/map/quest.h b/src/map/quest.h index 9d3c5f8f6a..dd9080cf65 100644 --- a/src/map/quest.h +++ b/src/map/quest.h @@ -9,14 +9,13 @@ struct quest_db { int id; unsigned int time; - int mob[MAX_QUEST_OBJECTIVES]; - int count[MAX_QUEST_OBJECTIVES]; - int num_objectives; - //char name[NAME_LENGTH]; + uint16 mob[MAX_QUEST_OBJECTIVES]; + uint16 count[MAX_QUEST_OBJECTIVES]; + uint8 num_objectives; + //StringBuf name; }; -struct quest_db *quest_db_data[MAX_QUEST_DB]; ///< Quest database -struct quest_db quest_dummy; ///< Dummy entry for invalid quest lookups +struct quest_db quest_dummy; ///< Dummy entry for invalid quest lookups // Questlog check types enum quest_check_type { @@ -36,7 +35,7 @@ int quest_update_status(TBL_PC * sd, int quest_id, enum quest_state status); int quest_check(TBL_PC * sd, int quest_id, enum quest_check_type type); void quest_clear(void); -struct quest_db *quest_db(int quest_id); +struct quest_db *quest_search(int quest_id); void do_init_quest(void); void do_final_quest(void);