From 8a22b23c902520efc35a49e45649ea8a3746cc95 Mon Sep 17 00:00:00 2001 From: skotlex Date: Wed, 8 Mar 2006 15:16:48 +0000 Subject: - Added functions mobdb_searchname_array and itemdb_searchname_array which return an array of matches. - Modified @iteminfo and @mobinfo to search and display various matches instead of just one. - Constant MAX_SEARCH in map.h defines the max size of search results. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5512 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 172 +++++++++++++++++++++++++++++----------------------- src/map/itemdb.c | 25 ++++++++ src/map/itemdb.h | 1 + src/map/map.h | 2 + src/map/mob.c | 33 ++++++++++ src/map/mob.h | 1 + src/map/pc.c | 9 +-- 7 files changed, 163 insertions(+), 80 deletions(-) (limited to 'src/map') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index b9dd48ae4..f02f974c1 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5186,7 +5186,7 @@ int atcommand_idsearch( { char item_name[100]; unsigned int i, match; - struct item_data *item; + struct item_data *item_array[MAX_SEARCH]; nullpo_retr(-1, sd); memset(item_name, '\0', sizeof(item_name)); @@ -5199,13 +5199,15 @@ int atcommand_idsearch( sprintf(atcmd_output, msg_table[77], item_name); // The reference result of '%s' (name: id): clif_displaymessage(fd, atcmd_output); - match = 0; - for(i = 0; i < 20000; i++) { - if ((item = itemdb_exists(i)) != NULL && strstr(item->jname, item_name) != NULL) { - match++; - sprintf(atcmd_output, msg_table[78], item->jname, item->nameid); // %s: %d - clif_displaymessage(fd, atcmd_output); - } + match = itemdb_searchname_array(item_array, MAX_SEARCH, item_name); + if (match > MAX_SEARCH) { + sprintf(atcmd_output, msg_table[269], MAX_SEARCH, match); + clif_displaymessage(fd, atcmd_output); + match = MAX_SEARCH; + } + for(i = 0; i < match; i++) { + sprintf(atcmd_output, msg_table[78], item_array[i]->jname, item_array[i]->nameid); // %s: %d + clif_displaymessage(fd, atcmd_output); } sprintf(atcmd_output, msg_table[79], match); // It is %d affair above. clif_displaymessage(fd, atcmd_output); @@ -9251,9 +9253,9 @@ int atcommand_mobinfo( unsigned char melement[11][8] = {"None", "Neutral", "Water", "Earth", "Fire", "Wind", "Poison", "Holy", "Dark", "Ghost", "Undead"}; char atcmd_output2[200]; struct item_data *item_data; - struct mob_db *mob; - int mob_id; - int i, j; + struct mob_db *mob, *mob_array[MAX_SEARCH]; + int mob_id, count; + int i, j, k; memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(atcmd_output2, '\0', sizeof(atcmd_output2)); @@ -9264,80 +9266,90 @@ int atcommand_mobinfo( } // If monster identifier/name argument is a name - if ((mob_id = mobdb_searchname(message)) == 0) // check name first (to avoid possible name begining by a number) - mob_id = mobdb_checkid(atoi(message)); + if ((mob_id = mobdb_checkid(atoi(message)))) + { + mob_array[0] = mob_db(mob_id); + count = 1; + } else + count = mobdb_searchname_array(mob_array, MAX_SEARCH, message); - if (mob_id == 0) { + if (!count) { clif_displaymessage(fd, msg_table[40]); // Invalid monster ID or name. return -1; } - mob = mob_db(mob_id); - - // stats - if (mob->mexp) - sprintf(atcmd_output, "MVP Monster: '%s'/'%s' (%d)", mob->name, mob->jname, mob_id); - else - sprintf(atcmd_output, "Monster: '%s'/'%s' (%d)", mob->name, mob->jname, mob_id); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, " Level:%d HP:%d SP:%d Base EXP:%d Job EXP:%d", mob->lv, mob->max_hp, mob->max_sp, mob->base_exp, mob->job_exp); - clif_displaymessage(fd, atcmd_output); - sprintf(atcmd_output, " DEF:%d MDEF:%d STR:%d AGI:%d VIT:%d INT:%d DEX:%d LUK:%d", mob->def, mob->mdef, mob->str, mob->agi, mob->vit, mob->int_, mob->dex, mob->luk); - clif_displaymessage(fd, atcmd_output); - if (mob->element < 20) { - //Element - None, Level 0 - i = 0; - j = 0; - } else { - i = mob->element % 20 + 1; - j = mob->element / 20; - } - sprintf(atcmd_output, " ATK:%d~%d Range:%d~%d~%d Size:%s Race: %s Element: %s (Lv:%d)", mob->atk1, mob->atk2, mob->range, mob->range2 , mob->range3, msize[mob->size], mrace[mob->race], melement[i], j); - clif_displaymessage(fd, atcmd_output); - // drops - clif_displaymessage(fd, " Drops:"); - strcpy(atcmd_output, " "); - j = 0; - for (i = 0; i < 10; i++) { - if (mob->dropitem[i].nameid <= 0 || (item_data = itemdb_search(mob->dropitem[i].nameid)) == NULL) - continue; - if (mob->dropitem[i].p > 0) { - sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->dropitem[i].p / 100); - strcat(atcmd_output, atcmd_output2); - if (++j % 3 == 0) { - clif_displaymessage(fd, atcmd_output); - strcpy(atcmd_output, " "); - } - } + if (count > MAX_SEARCH) { + sprintf(atcmd_output, msg_table[269], MAX_SEARCH, count); + clif_displaymessage(fd, atcmd_output); + count = MAX_SEARCH; } - if (j == 0) - clif_displaymessage(fd, "This monster has no drops."); - else if (j % 3 != 0) + for (k = 0; k < count; k++) { + mob = mob_array[k]; + + // stats + if (mob->mexp) + sprintf(atcmd_output, "MVP Monster: '%s'/'%s' (%d)", mob->name, mob->jname, mob_id); + else + sprintf(atcmd_output, "Monster: '%s'/'%s' (%d)", mob->name, mob->jname, mob_id); + clif_displaymessage(fd, atcmd_output); + sprintf(atcmd_output, " Level:%d HP:%d SP:%d Base EXP:%d Job EXP:%d", mob->lv, mob->max_hp, mob->max_sp, mob->base_exp, mob->job_exp); clif_displaymessage(fd, atcmd_output); - // mvp - if (mob->mexp) { - sprintf(atcmd_output, " MVP Bonus EXP:%d %02.02f%%", mob->mexp, (float)mob->mexpper / 100); + sprintf(atcmd_output, " DEF:%d MDEF:%d STR:%d AGI:%d VIT:%d INT:%d DEX:%d LUK:%d", mob->def, mob->mdef, mob->str, mob->agi, mob->vit, mob->int_, mob->dex, mob->luk); clif_displaymessage(fd, atcmd_output); - strcpy(atcmd_output, " MVP Items:"); + if (mob->element < 20) { + //Element - None, Level 0 + i = 0; + j = 0; + } else { + i = mob->element % 20 + 1; + j = mob->element / 20; + } + sprintf(atcmd_output, " ATK:%d~%d Range:%d~%d~%d Size:%s Race: %s Element: %s (Lv:%d)", mob->atk1, mob->atk2, mob->range, mob->range2 , mob->range3, msize[mob->size], mrace[mob->race], melement[i], j); + clif_displaymessage(fd, atcmd_output); + // drops + clif_displaymessage(fd, " Drops:"); + strcpy(atcmd_output, " "); j = 0; - for (i = 0; i < 3; i++) { - if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_search(mob->mvpitem[i].nameid)) == NULL) + for (i = 0; i < 10; i++) { + if (mob->dropitem[i].nameid <= 0 || (item_data = itemdb_search(mob->dropitem[i].nameid)) == NULL) continue; - if (mob->mvpitem[i].p > 0) { - j++; - if (j == 1) - sprintf(atcmd_output2, " %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100); - else - sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100); + if (mob->dropitem[i].p > 0) { + sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->dropitem[i].p / 100); strcat(atcmd_output, atcmd_output2); + if (++j % 3 == 0) { + clif_displaymessage(fd, atcmd_output); + strcpy(atcmd_output, " "); + } } } if (j == 0) - clif_displaymessage(fd, "This monster has no MVP prizes."); - else + clif_displaymessage(fd, "This monster has no drops."); + else if (j % 3 != 0) + clif_displaymessage(fd, atcmd_output); + // mvp + if (mob->mexp) { + sprintf(atcmd_output, " MVP Bonus EXP:%d %02.02f%%", mob->mexp, (float)mob->mexpper / 100); clif_displaymessage(fd, atcmd_output); + strcpy(atcmd_output, " MVP Items:"); + j = 0; + for (i = 0; i < 3; i++) { + if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_search(mob->mvpitem[i].nameid)) == NULL) + continue; + if (mob->mvpitem[i].p > 0) { + j++; + if (j == 1) + sprintf(atcmd_output2, " %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100); + else + sprintf(atcmd_output2, " - %s %02.02f%%", item_data->name, (float)mob->mvpitem[i].p / 100); + strcat(atcmd_output, atcmd_output2); + } + } + if (j == 0) + clif_displaymessage(fd, "This monster has no MVP prizes."); + else + clif_displaymessage(fd, atcmd_output); + } } - return 0; } @@ -9353,20 +9365,28 @@ int atcommand_iteminfo( char *itype[12] = {"Potion/Food", "BUG!", "Usable", "Etc", "Weapon", "Protection", "Card", "Egg", "Pet Acessory", "BUG!", "Arrow"}; //, "Lure/Scroll"}; No need, type 11 items are converted to type 2 upon loading [Skotlex] - struct item_data *item_data; - int item_id=0; + struct item_data *item_data, *item_array[MAX_SEARCH]; + int i, item_id=0, count = 1; if (!message || !*message) { clif_displaymessage(fd, "Please, enter Item name or its ID (usage: @iteminfo )."); return -1; } + if ((item_array[0] = itemdb_exists(atoi(message))) == NULL) + count = itemdb_searchname_array(item_array, MAX_SEARCH, message); - if ((item_data = itemdb_searchname(message)) != NULL || - (item_data = itemdb_exists(atoi(message))) != NULL) - item_id = item_data->nameid; - - if (item_id >= 500) { + if (!count) { + clif_displaymessage(fd, "Item not found."); + return -1; + } + if (count > MAX_SEARCH) { + sprintf(atcmd_output, msg_table[269], MAX_SEARCH, count); + clif_displaymessage(fd, atcmd_output); + count = MAX_SEARCH; + } + for (i = 0; i < MAX_SEARCH; i++) { + item_data = item_array[i]; sprintf(atcmd_output, "Item: '%s'/'%s'[%d] (%d) Type: %s | Extra Effect: %s", item_data->name,item_data->jname,item_data->slot,item_id, item_data->type < 12 ? itype[item_data->type] : "BUG!", diff --git a/src/map/itemdb.c b/src/map/itemdb.c index aa4f3a622..0e7241ea8 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -61,6 +61,7 @@ int itemdb_searchjname_sub(int key,void *data,va_list ap) *dst=item; return 0; } + /*========================================== * 名前で検索 *------------------------------------------ @@ -72,6 +73,30 @@ struct item_data* itemdb_searchname(const char *str) return item; } +static int itemdb_searchname_array_sub(DBKey key,void * data,va_list ap) +{ + struct item_data *item=(struct item_data *)data; + char *str; + str=va_arg(ap,char *); + if (item == dummy_item) + return 1; //Invalid item. + if(strstr(item->jname,str)) + return 0; + if(strstr(item->name,str)) + return 0; + return strcmpi(item->jname,str); +} + +/*========================================== + * Founds up to N matches. Returns number of matches [Skotlex] + *------------------------------------------ + */ +int itemdb_searchname_array(struct item_data** data, int size, const char *str) +{ + return item_db->getall(item_db,(void**)data,size,itemdb_searchname_array_sub,str); +} + + /*========================================== * 箱系アイテム検索 *------------------------------------------ diff --git a/src/map/itemdb.h b/src/map/itemdb.h index dd1e08c80..c43863155 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -56,6 +56,7 @@ struct item_group { }; struct item_data* itemdb_searchname(const char *name); +int itemdb_searchname_array(struct item_data** data, int size, const char *str); struct item_data* itemdb_load(int nameid); struct item_data* itemdb_search(int nameid); struct item_data* itemdb_exists(int nameid); diff --git a/src/map/map.h b/src/map/map.h index 4eeb86957..44c879c6e 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -51,6 +51,8 @@ #define MOBID_EMPERIUM 1288 #define MAX_PC_BONUS 10 +//Designed for search functions, species max number of matches to display. +#define MAX_SEARCH 5 #define MAX_DUEL 1024 //These mark the ID of the jobs, as expected by the client. [Skotlex] diff --git a/src/map/mob.c b/src/map/mob.c index 183e063ff..c17079add 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -80,6 +80,39 @@ int mobdb_searchname(const char *str) return 0; } +static int mobdb_searchname_array_sub(struct mob_db* mob, const char *str) +{ + if (mob == mob_dummy) + return 1; //Invalid item. + if(strstr(mob->jname,str)) + return 0; + if(strstr(mob->name,str)) + return 0; + return strcmpi(mob->jname,str); +} + +/*========================================== + * Founds up to N matches. Returns number of matches [Skotlex] + *------------------------------------------ + */ +int mobdb_searchname_array(struct mob_db** data, int size, const char *str) +{ + int count = 0, i; + struct mob_db* mob; + for(i=0;i<=MAX_MOB_DB;i++){ + mob = mob_db(i); + if (mob == mob_dummy) + continue; + if (!mobdb_searchname_array_sub(mob, str)) { + if (count < size) + data[count] = mob; + count++; + } + } + return count; +} + + /*========================================== * Id Mob is checked. diff --git a/src/map/mob.h b/src/map/mob.h index c719c721b..2e12114ec 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -104,6 +104,7 @@ enum { struct mob_db* mob_db(int class_); int mobdb_searchname(const char *str); +int mobdb_searchname_array(struct mob_db** data, int size, const char *str); int mobdb_checkid(const int id); int mob_once_spawn(struct map_session_data *sd,char *mapname, int x,int y,const char *mobname,int class_,int amount,const char *event); diff --git a/src/map/pc.c b/src/map/pc.c index 792125ae5..86e1e0e62 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5856,11 +5856,12 @@ int pc_heal(struct map_session_data *sd,int hp,int sp) nullpo_retr(0, sd); - if(hp > 0 && pc_checkoverhp(sd)) - hp = 0; +//Uneeded as the hp range adjustment below will auto-adap itself and make hp = max. [Skotlex] +// if(hp > 0 && pc_checkoverhp(sd)) +// hp = 0; - if(sp > 0 && pc_checkoversp(sd)) - sp = 0; +// if(sp > 0 && pc_checkoversp(sd)) +// sp = 0; if(sd->sc.count && sd->sc.data[SC_BERSERK].timer!=-1) //バ?サ?ク中は回復させないらしい return 0; -- cgit v1.2.3-60-g2f50