summaryrefslogblamecommitdiff
path: root/src/map/itemdb.cpp
blob: 9c6d4e6da1e7f559e298497d6c4779ed171f9f03 (plain) (tree)
1
2
3
4
5
6
7
8
9

                     

                  
 
                                 
                           
                               
                               
                               
 

                        
                                  

                                     
                                                                                     
                                         
 

                    
 

                        




                        

                                
                              

                                            
                     


                                                                                                           
      
                                                                                            
 
                                                       
                                                    
                    


                                            
                  

                                            
                                                    
 
                                  
                                                                                         
                


                                            
                    

                                            
                                           
 
                                                             
 
 
                                            
              

                                            
                                           
 
                                                                             


                  

                                                                  







                                       
                                                 




                                     
                                 
                                          
                                

                                               
                                  
                                             
                                   
                                            
                                    

                                                
                                   
                                            
                                

              





                                            
                              
 





                                        
 
 



                                            
                                           
 







                                    
 
 



                                            
                               
 



                                        

 
                                            
                                                

                                            

                       
 

                    

                          

                           
              
                                                                     



                           
                                      



                         
                                                   
                    


                  
                                     



                                                 
                                        




                                                        
                                   








                               
                                  




                                                                                                 


                                          
                                              

                                          










                                                          






                                            
                                            


                                     







                                     
                                              
                         
                                                    
 
                                                 
                         
                                                      
         
                    
                                                             

             




                                            
                                                            

                                            

                               
 

                    

                     

                      
                                                        
     
                                                 


                  
                                 



                                             
                                    


                                              
                               






                           

                                                                           
                     
                         








                                   
                
                                                           
             
 
 
                                            
                                       

                                            

                             
 

                    

                  


                         
                                                          
     
                                                   

                  
                                 


                                             
                                    


                                              
                               





                           

                                                                            

                     
                                         



             
                
                                                             
             
 
 



                                            

                                          
 
                         
 

                                  
 
                       
                                                       
                         

                                                         

 
                        
 
      
      

                             
      

       
                     





                                            
                          
 

                
                                           

                       


  



                                                
                                                      
                                     
                 


                   


                                         

  
 



                                      

                      
 
                    

                            
 
 



                                            
                        
 
                           
 
                  
 
             
 
#include "itemdb.hpp"

#include <cstdlib>
#include <cstring>

#include "../common/cxxstdio.hpp"
#include "../common/db.hpp"
#include "../common/random.hpp"
#include "../common/nullpo.hpp"
#include "../common/socket.hpp"

#include "../poison.hpp"

constexpr int MAX_RANDITEM = 2000;

// ** ITEMDB_OVERRIDE_NAME_VERBOSE **
//   定義すると、itemdb.txtとgrfで名前が異なる場合、表示します.
//#define ITEMDB_OVERRIDE_NAME_VERBOSE  1

static
struct dbt *item_db;

// Function declarations

static
void itemdb_read(void);
static
int itemdb_readdb(void);
static
int itemdb_read_itemavail(void);
static
int itemdb_read_noequip(void);

/*==========================================
 * 名前で検索用
 *------------------------------------------
 */
// name = item alias, so we should find items aliases first. if not found then look for "jname" (full name)
static
void itemdb_searchname_sub(db_key_t, db_val_t data, const char *str, struct item_data **dst)
{
    struct item_data *item = (struct item_data *) data;
    if (strcasecmp(item->name, str) == 0) //by lupus
        *dst = item;
}

/*==========================================
 * 名前で検索
 *------------------------------------------
 */
struct item_data *itemdb_searchname(const char *str)
{
    struct item_data *item = NULL;
    numdb_foreach(item_db, std::bind(itemdb_searchname_sub, ph::_1, ph::_2, str, &item));
    return item;
}

/*==========================================
 * DBの存在確認
 *------------------------------------------
 */
struct item_data *itemdb_exists(int nameid)
{
    return (struct item_data *)numdb_search(item_db, nameid);
}

/*==========================================
 * DBの検索
 *------------------------------------------
 */
struct item_data *itemdb_search(int nameid)
{
    struct item_data *id = (struct item_data *)numdb_search(item_db, nameid);
    if (id)
        return id;

    id = (struct item_data *) calloc(1, sizeof(struct item_data));
    numdb_insert(item_db, nameid, id);

    id->nameid = nameid;
    id->value_buy = 10;
    id->value_sell = id->value_buy / 2;
    id->weight = 10;
    id->sex = 2;
    id->elv = 0;
    id->flag.available = 0;
    id->flag.value_notdc = 0;   //一応・・・
    id->flag.value_notoc = 0;
    id->flag.no_equip = 0;
    id->view_id = 0;

    if (nameid > 500 && nameid < 600)
        id->type = ItemType::USE;
    else if (nameid > 600 && nameid < 700)
        id->type = ItemType::_2;
    else if ((nameid > 700 && nameid < 1100) ||
             (nameid > 7000 && nameid < 8000))
        id->type = ItemType::JUNK;
    else if (nameid >= 1750 && nameid < 1771)
        id->type = ItemType::ARROW;
    else if (nameid > 1100 && nameid < 2000)
        id->type = ItemType::WEAPON;
    else if ((nameid > 2100 && nameid < 3000) ||
             (nameid > 5000 && nameid < 6000))
        id->type = ItemType::ARMOR;
    else if (nameid > 4000 && nameid < 5000)
        id->type = ItemType::_6;

    return id;
}

/*==========================================
 *
 *------------------------------------------
 */
int itemdb_isequip(int nameid)
{
    ItemType type = itemdb_type(nameid);
    return !(type == ItemType::USE
        || type == ItemType::_2
        || type == ItemType::JUNK
        || type == ItemType::_6
        || type == ItemType::ARROW);
}

/*==========================================
 *
 *------------------------------------------
 */
int itemdb_isequip2(struct item_data *data)
{
    if (!data)
        return false;
    ItemType type = data->type;
    return !(type == ItemType::USE
        || type == ItemType::_2
        || type == ItemType::JUNK
        || type == ItemType::_6
        || type == ItemType::ARROW);
}

/*==========================================
 *
 *------------------------------------------
 */
int itemdb_isequip3(int nameid)
{
    ItemType type = itemdb_type(nameid);
    return (type == ItemType::WEAPON
        || type == ItemType::ARMOR
        || type == ItemType::_8);
}

/*==========================================
 * アイテムデータベースの読み込み
 *------------------------------------------
 */
static
int itemdb_readdb(void)
{
    FILE *fp;
    char line[1024];
    int ln = 0, lines = 0;
    int nameid, j;
    char *str[32], *p, *np;
    struct item_data *id;
    int i = 0;
    const char *filename[] = { "db/item_db.txt", "db/item_db2.txt" };

    for (i = 0; i < 2; i++)
    {

        fp = fopen_(filename[i], "r");
        if (fp == NULL)
        {
            if (i > 0)
                continue;
            PRINTF("can't read %s\n", filename[i]);
            exit(1);
        }

        lines = 0;
        while (fgets(line, 1020, fp))
        {
            lines++;
            if (line[0] == '/' && line[1] == '/')
                continue;
            memset(str, 0, sizeof(str));
            for (j = 0, np = p = line; j < 17 && p; j++)
            {
                while (*p == '\t' || *p == ' ')
                    p++;
                str[j] = p;
                p = strchr(p, ',');
                if (p)
                {
                    *p++ = 0;
                    np = p;
                }
            }
            if (str[0] == NULL)
                continue;

            nameid = atoi(str[0]);
            if (nameid <= 0 || nameid >= 20000)
                continue;
            ln++;

            //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Gender,Loc,wLV,eLV,View
            id = itemdb_search(nameid);
            memcpy(id->name, str[1], 24);
            memcpy(id->jname, str[2], 24);
            id->type = ItemType(atoi(str[3]));
            id->value_buy = atoi(str[4]);
            id->value_sell = atoi(str[5]);
            if (id->value_buy == 0 && id->value_sell == 0)
            {
            }
            else if (id->value_buy == 0)
            {
                id->value_buy = id->value_sell * 2;
            }
            else if (id->value_sell == 0)
            {
                id->value_sell = id->value_buy / 2;
            }
            id->weight = atoi(str[6]);
            id->atk = atoi(str[7]);
            id->def = atoi(str[8]);
            id->range = atoi(str[9]);
            id->magic_bonus = atoi(str[10]);
            id->slot = atoi(str[11]);
            id->sex = atoi(str[12]);
            id->equip = EPOS(atoi(str[13]));
            id->wlv = atoi(str[14]);
            id->elv = atoi(str[15]);
            id->look = atoi(str[16]);
            id->flag.available = 1;
            id->flag.value_notdc = 0;
            id->flag.value_notoc = 0;
            id->view_id = 0;

            id->use_script = NULL;
            id->equip_script = NULL;

            if ((p = strchr(np, '{')) == NULL)
                continue;
            id->use_script = parse_script(p, lines);

            if ((p = strchr(p + 1, '{')) == NULL)
                continue;
            id->equip_script = parse_script(p, lines);
        }
        fclose_(fp);
        PRINTF("read %s done (count=%d)\n", filename[i], ln);
    }
    return 0;
}

// Removed item_value_db, don't re-add!

/*==========================================
 * アイテム使用可能フラグのオーバーライド
 *------------------------------------------
 */
static
int itemdb_read_itemavail(void)
{
    FILE *fp;
    char line[1024];
    int ln = 0;
    int nameid, j, k;
    char *str[10], *p;

    if ((fp = fopen_("db/item_avail.txt", "r")) == NULL)
    {
        PRINTF("can't read db/item_avail.txt\n");
        return -1;
    }

    while (fgets(line, 1020, fp))
    {
        struct item_data *id;
        if (line[0] == '/' && line[1] == '/')
            continue;
        memset(str, 0, sizeof(str));
        for (j = 0, p = line; j < 2 && p; j++)
        {
            str[j] = p;
            p = strchr(p, ',');
            if (p)
                *p++ = 0;
        }

        if (str[0] == NULL)
            continue;

        nameid = atoi(str[0]);
        if (nameid < 0 || nameid >= 20000 || !(id = itemdb_exists(nameid)))
            continue;
        k = atoi(str[1]);
        if (k > 0)
        {
            id->flag.available = 1;
            id->view_id = k;
        }
        else
            id->flag.available = 0;
        ln++;
    }
    fclose_(fp);
    PRINTF("read db/item_avail.txt done (count=%d)\n", ln);
    return 0;
}

/*==========================================
 * 装備制限ファイル読み出し
 *------------------------------------------
 */
static
int itemdb_read_noequip(void)
{
    FILE *fp;
    char line[1024];
    int ln = 0;
    int nameid, j;
    char *str[32], *p;
    struct item_data *id;

    if ((fp = fopen_("db/item_noequip.txt", "r")) == NULL)
    {
        PRINTF("can't read db/item_noequip.txt\n");
        return -1;
    }
    while (fgets(line, 1020, fp))
    {
        if (line[0] == '/' && line[1] == '/')
            continue;
        memset(str, 0, sizeof(str));
        for (j = 0, p = line; j < 2 && p; j++)
        {
            str[j] = p;
            p = strchr(p, ',');
            if (p)
                *p++ = 0;
        }
        if (str[0] == NULL)
            continue;

        nameid = atoi(str[0]);
        if (nameid <= 0 || nameid >= 20000 || !(id = itemdb_exists(nameid)))
            continue;

        id->flag.no_equip = atoi(str[1]);

        ln++;

    }
    fclose_(fp);
    PRINTF("read db/item_noequip.txt done (count=%d)\n", ln);
    return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
static
void itemdb_final(db_key_t, db_val_t data)
{
    struct item_data *id;

    id = (struct item_data *)data;
    nullpo_retv(id);

    if (id->use_script)
        free(const_cast<ScriptCode *>(id->use_script));
    if (id->equip_script)
        free(const_cast<ScriptCode *>(id->equip_script));
    free(id);
}

void itemdb_reload(void)
{
    /*
     *
     * <empty item databases>
     * itemdb_read();
     *
     */

    do_init_itemdb();
}

/*==========================================
 *
 *------------------------------------------
 */
void do_final_itemdb(void)
{
    if (item_db)
    {
        numdb_final(item_db, itemdb_final);
        item_db = NULL;
    }
}

/*
static
FILE *dfp;
static
int itemdebug(void *key,void *data,_va_list ap){
//      struct item_data *id=(struct item_data *)data;
        FPRINTF(dfp,"%6d", (int)key);
        return 0;
}
void itemdebugtxt()
{
        dfp=fopen_("itemdebug.txt","wt");
        numdb_foreach(item_db,itemdebug);
        fclose_(dfp);
}
*/

/*====================================
 * Removed item_value_db, don't re-add
 *------------------------------------
 */
static
void itemdb_read(void)
{
    itemdb_readdb();
    itemdb_read_itemavail();
    itemdb_read_noequip();
}

/*==========================================
 *
 *------------------------------------------
 */
int do_init_itemdb(void)
{
    item_db = numdb_init();

    itemdb_read();

    return 0;
}