summaryrefslogblamecommitdiff
path: root/src/emap/quest.c
blob: 4ef0e55f37d1eacfd6e01f4fe751e32fd26a9d96 (plain) (tree)
1
2
3
4
5
6
7
8
9


                                                                         

                            



                   





                          
                       

                      

                       









                                                                                        
 




                                  
 



















                                                              
 

                                                                                              
                   



                                                                                                                                                   
                   

                    
 

                                                                                                            
                   

                    
 

                                                


                                                         
 

                                                                                                                 
 


















                                                                                           
         





                                                               
 




















                                                                                                 
         
     
               
                 
 
// Copyright (c) Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// Copyright (c) 2014 Evol developers

#include "common/hercules.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common/HPMi.h"
#include "common/malloc.h"
#include "common/mmo.h"
#include "common/socket.h"
#include "common/strlib.h"
#include "map/itemdb.h"
#include "map/script.h"
#include "map/quest.h"

#include "emap/quest.h"

/**
 * Reads and parses an entry from the quest_db.
 *
 * @param cs     The config setting containing the entry.
 * @param n      The sequential index of the current config setting.
 * @param source The source configuration file.
 * @return The parsed quest entry.
 * @retval NULL in case of errors.
 */
struct quest_db *equest_read_db_sub(config_setting_t *cs, int *nPtr, const char *source)
{
    struct quest_db *entry = NULL;
    config_setting_t *t = NULL;
    int i32 = 0, quest_id;
    const char *str = NULL;
    const int n = *nPtr;

    /*
     * Id: Quest ID                    [int]
     * Name: Quest Name                [string]
     * TimeLimit: Time Limit (seconds) [int, optional]
     * Targets: (                      [array, optional]
     *     {
     *         MobId: Mob ID           [int]
     *         Count:                  [int]
     *     },
     *     ... (can repeated up to MAX_QUEST_OBJECTIVES times)
     * )
     * Drops: (
     *     {
     *         ItemId: Item ID to drop [int]
     *         Rate: Drop rate         [int]
     *         MobId: Mob ID to match  [int, optional]
     *     },
     *     ... (can be repeated)
     * )
     */

    if (!libconfig->setting_lookup_int(cs, "Id", &quest_id)) {
        ShowWarning("quest_read_db: Missing id in \"%s\", entry #%d, skipping.\n", source, n);
        hookStop();
        return NULL;
    }
    if (quest_id < 0 || quest_id >= MAX_QUEST_DB) {
        ShowWarning("quest_read_db: Invalid quest ID '%d' in \"%s\", entry #%d (min: 0, max: %d), skipping.\n", quest_id, source, n, MAX_QUEST_DB);
        hookStop();
        return NULL;
    }

    if (!libconfig->setting_lookup_string(cs, "Name", &str) || !*str) {
        ShowWarning("quest_read_db_sub: Missing Name in quest %d of \"%s\", skipping.\n", quest_id, source);
        hookStop();
        return NULL;
    }

    script->set_constant2(str, quest_id, false);

    CREATE(entry, struct quest_db, 1);
    entry->id = quest_id;
    //safestrncpy(entry->name, str, sizeof(entry->name));

    if (libconfig->setting_lookup_int(cs, "TimeLimit", &i32)) // This is an unsigned value, do not check for >= 0
        entry->time = (unsigned int)i32;

    if ((t=libconfig->setting_get_member(cs, "Targets")) && config_setting_is_list(t)) {
/*
        int i, len = libconfig->setting_length(t);
        for (i = 0; i < len && entry->objectives_count < MAX_QUEST_OBJECTIVES; i++) {
            // Note: We ensure that objectives_count < MAX_QUEST_OBJECTIVES because
            //       quest_log (as well as the client) expect this maximum size.
            config_setting_t *tt = libconfig->setting_get_elem(t, i);
            int mob_id = 0, count = 0;
            if (!tt)
                break;
            if (!config_setting_is_group(tt))
                continue;
            if (!libconfig->setting_lookup_int(tt, "MobId", &mob_id) || mob_id <= 0)
                continue;
            if (!libconfig->setting_lookup_int(tt, "Count", &count) || count <= 0)
                continue;
            RECREATE(entry->objectives, struct quest_objective, ++entry->objectives_count);
            entry->objectives[entry->objectives_count-1].mob = mob_id;
            entry->objectives[entry->objectives_count-1].count = count;
        }
*/
        entry->objectives_count = 1;
        RECREATE(entry->objectives, struct quest_objective, 1);
        entry->objectives[0].mob = 1;
        entry->objectives[0].count = 0;
    }

    if ((t=libconfig->setting_get_member(cs, "Drops")) && config_setting_is_list(t)) {
        int i, len = libconfig->setting_length(t);
        for (i = 0; i < len; i++) {
            config_setting_t *tt = libconfig->setting_get_elem(t, i);
            int mob_id = 0, nameid = 0, rate = 0;
            if (!tt)
                break;
            if (!config_setting_is_group(tt))
                continue;
            if (!libconfig->setting_lookup_int(tt, "MobId", &mob_id))
                mob_id = 0; // Zero = any monster
            if (mob_id < 0)
                continue;
            if (!libconfig->setting_lookup_int(tt, "ItemId", &nameid) || !itemdb->exists(nameid))
                continue;
            if (!libconfig->setting_lookup_int(tt, "Rate", &rate) || rate <= 0)
                continue;
            RECREATE(entry->dropitem, struct quest_dropitem, ++entry->dropitem_count);
            entry->dropitem[entry->dropitem_count-1].mob_id = mob_id;
            entry->dropitem[entry->dropitem_count-1].nameid = nameid;
            entry->dropitem[entry->dropitem_count-1].rate = rate;
        }
    }
    hookStop();
    return entry;
}