From 6b841157909ac17c0b82b917763976f43be2f89f Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Sun, 8 Aug 2021 16:46:44 +0200 Subject: [PATCH] Speeded up item name lookup (#6161) Partial takeover from #5997 Did some further cleanup and took it out of the pull request until secret has time to finish it. All credits to @secretdataz Co-authored-by: secretdataz --- src/common/utilities.hpp | 5 ++ src/map/achievement.cpp | 2 +- src/map/atcommand.cpp | 118 ++++++++++++++++------------ src/map/clif.cpp | 12 +-- src/map/itemdb.cpp | 62 ++++++++++++--- src/map/itemdb.hpp | 15 +++- src/map/mob.cpp | 16 ++-- src/map/pet.cpp | 10 +-- src/map/quest.cpp | 2 +- src/map/script.cpp | 165 +++++++++++++++++++++------------------ src/map/skill.cpp | 10 +-- src/map/status.cpp | 2 +- src/tool/yaml.hpp | 3 +- 13 files changed, 253 insertions(+), 169 deletions(-) diff --git a/src/common/utilities.hpp b/src/common/utilities.hpp index 35346c72ff..81de444731 100644 --- a/src/common/utilities.hpp +++ b/src/common/utilities.hpp @@ -5,6 +5,7 @@ #define UTILILITIES_HPP #include +#include #include #include #include @@ -258,6 +259,10 @@ namespace rathena { return result; } } + + template void tolower( T& string ){ + std::transform( string.begin(), string.end(), string.begin(), ::tolower ); + } } } diff --git a/src/map/achievement.cpp b/src/map/achievement.cpp index 4ad79c9f9d..70b5826da0 100644 --- a/src/map/achievement.cpp +++ b/src/map/achievement.cpp @@ -267,7 +267,7 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){ return 0; } - struct item_data *item = itemdb_search_aegisname(item_name.c_str()); + std::shared_ptr item = item_db.search_aegisname(item_name.c_str()); if (item == nullptr) { this->invalidWarning(rewardNode["Item"], "Reward Item %s does not exist, skipping.\n", item_name.c_str()); diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 67f3db35c8..313fb79bf5 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -1345,9 +1345,6 @@ ACMD_FUNC(item) char item_name[100]; int number = 0, bound = BOUND_NONE; char flag = 0; - struct item item_tmp; - struct item_data *item_data[10]; - int get_count, i, j=0; char *itemlist; nullpo_retr(-1, sd); @@ -1375,31 +1372,44 @@ ACMD_FUNC(item) clif_displaymessage(fd, msg_txt(sd,983)); // Please enter an item name or ID (usage: @item ). return -1; } + + std::vector> items; itemlist = strtok(item_name, ":"); - while (itemlist != NULL && j<10) { - if ((item_data[j] = itemdb_searchname(itemlist)) == NULL && - (item_data[j] = itemdb_exists( strtoul( itemlist, nullptr, 10 ) ) ) == NULL){ + + while( itemlist != nullptr ){ + std::shared_ptr item = item_db.searchname( itemlist ); + + if( item == nullptr ){ + item = item_db.find( strtoul( itemlist, nullptr, 10 ) ); + } + + if( item == nullptr ){ clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name. return -1; } + + items.push_back( item ); itemlist = strtok(NULL, ":"); //next itemline - j++; } if (number <= 0) number = 1; - get_count = number; + int get_count = number; + + // Produce items in list + for( const auto& item : items ){ + t_itemid item_id = item->nameid; - for(j--; j>=0; j--){ //produce items in list - t_itemid item_id = item_data[j]->nameid; //Check if it's stackable. - if (!itemdb_isstackable2(item_data[j])) + if( !itemdb_isstackable2( item.get() ) ){ get_count = 1; + } - for (i = 0; i < number; i += get_count) { + for( int i = 0; i < number; i += get_count ){ // if not pet egg if (!pet_create_egg(sd, item_id)) { - memset(&item_tmp, 0, sizeof(item_tmp)); + struct item item_tmp = {}; + item_tmp.nameid = item_id; item_tmp.identify = 1; item_tmp.bound = bound; @@ -1419,10 +1429,7 @@ ACMD_FUNC(item) *------------------------------------------*/ ACMD_FUNC(item2) { - struct item item_tmp; - struct item_data *item_data; char item_name[100]; - t_itemid item_id; int number = 0, bound = BOUND_NONE; int identify = 0, refine = 0, attr = 0; int c1 = 0, c2 = 0, c3 = 0, c4 = 0; @@ -1458,17 +1465,18 @@ ACMD_FUNC(item2) if (number <= 0) number = 1; - item_id = 0; - if ((item_data = itemdb_searchname(item_name)) != NULL || - (item_data = itemdb_exists(strtoul(item_name, nullptr, 10))) != NULL) - item_id = item_data->nameid; + std::shared_ptr item_data = item_db.searchname( item_name ); - if (item_id > 500) { + if( item_data == nullptr ){ + item_data = item_db.find( strtoul( item_name, nullptr, 10 ) ); + } + + if( item_data != nullptr ){ int loop, get_count, i; char flag = 0; //Check if it's stackable. - if(!itemdb_isstackable2(item_data)){ + if( !itemdb_isstackable2( item_data.get() ) ){ loop = number; get_count = 1; }else{ @@ -1476,7 +1484,7 @@ ACMD_FUNC(item2) get_count = number; } - if( itemdb_isequip2(item_data ) ){ + if( itemdb_isequip2( item_data.get() ) ){ refine = cap_value( refine, 0, MAX_REFINE ); }else{ // All other items cannot be refined and are always identified @@ -1486,9 +1494,10 @@ ACMD_FUNC(item2) for (i = 0; i < loop; i++) { // if not pet egg - if (!pet_create_egg(sd, item_id)) { - memset(&item_tmp, 0, sizeof(item_tmp)); - item_tmp.nameid = item_id; + if (!pet_create_egg(sd, item_data->nameid)) { + struct item item_tmp = {}; + + item_tmp.nameid = item_data->nameid; item_tmp.identify = identify; item_tmp.refine = refine; item_tmp.attribute = attr; @@ -2378,8 +2387,6 @@ ACMD_FUNC(produce) char item_name[100]; t_itemid item_id; int attribute = 0, star = 0; - struct item_data *item_data; - struct item tmp_item; nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -2393,21 +2400,28 @@ ACMD_FUNC(produce) return -1; } - if ( (item_data = itemdb_searchname(item_name)) == NULL && - (item_data = itemdb_exists( strtoul( item_name, nullptr, 10 ) ) ) == NULL ) { + std::shared_ptr item_data = item_db.searchname( item_name ); + + if( item_data == nullptr ){ + item_data = item_db.find( strtoul( item_name, nullptr, 10 ) ); + } + + if( item_data == nullptr ){ clif_displaymessage(fd, msg_txt(sd,170)); //This item is not an equipment. return -1; } item_id = item_data->nameid; - if (itemdb_isequip2(item_data)) { + if( itemdb_isequip2( item_data.get() ) ){ char flag = 0; if (attribute < MIN_ATTRIBUTE || attribute > MAX_ATTRIBUTE) attribute = ATTRIBUTE_NORMAL; if (star < MIN_STAR || star > MAX_STAR) star = 0; - memset(&tmp_item, 0, sizeof tmp_item); + + struct item tmp_item = {}; + tmp_item.nameid = item_id; tmp_item.amount = 1; tmp_item.identify = 1; @@ -2820,7 +2834,6 @@ ACMD_FUNC(guildlevelup) { * *------------------------------------------*/ ACMD_FUNC(makeegg) { - struct item_data *item_data; int id; nullpo_retr(-1, sd); @@ -2843,7 +2856,9 @@ ACMD_FUNC(makeegg) { t_itemid nameid; // for egg name - if( ( item_data = itemdb_searchname( message ) ) != nullptr ){ + std::shared_ptr item_data = item_db.searchname( message ); + + if( item_data != nullptr ){ nameid = item_data->nameid; }else{ nameid = strtoul( message, nullptr, 10 ); @@ -6327,7 +6342,7 @@ ACMD_FUNC(autoloot) *------------------------------------------*/ ACMD_FUNC(autolootitem) { - struct item_data *item_data = NULL; + std::shared_ptr item_data; int i; int action = 3; // 1=add, 2=remove, 3=help+list (default), 4=reset @@ -6348,9 +6363,13 @@ ACMD_FUNC(autolootitem) if (action < 3) // add or remove { - if ((item_data = itemdb_exists(strtoul(message, nullptr, 10))) == nullptr) - item_data = itemdb_searchname(message); - if (!item_data) { + item_data = item_db.find( strtoul( message, nullptr, 10 ) ); + + if( item_data == nullptr ){ + item_data = item_db.searchname( message ); + } + + if( item_data == nullptr ){ // No items founds in the DB with Id or Name clif_displaymessage(fd, msg_txt(sd,1189)); // Item not found. return -1; @@ -6402,10 +6421,13 @@ ACMD_FUNC(autolootitem) { if (sd->state.autolootid[i] == 0) continue; - if (!(item_data = itemdb_exists(sd->state.autolootid[i]))) { + item_data = item_db.find( sd->state.autolootid[i] ); + + if( item_data == nullptr ){ ShowDebug("Non-existant item %d on autolootitem list (account_id: %d, char_id: %d)", sd->state.autolootid[i], sd->status.account_id, sd->status.char_id); continue; } + sprintf(atcmd_output, "'%s'/'%s' {%u}", item_data->name.c_str(), item_data->ename.c_str(), item_data->nameid); clif_displaymessage(fd, atcmd_output); } @@ -9175,9 +9197,7 @@ ACMD_FUNC(stats) ACMD_FUNC(delitem) { char item_name[100]; - t_itemid nameid; - int amount = 0, total, idx; - struct item_data* id; + int amount = 0, idx; nullpo_retr(-1, sd); @@ -9187,17 +9207,19 @@ ACMD_FUNC(delitem) return -1; } - if( ( id = itemdb_searchname(item_name) ) != NULL || ( id = itemdb_exists( strtoul( item_name, nullptr, 10 ) ) ) != NULL ) - { - nameid = id->nameid; + std::shared_ptr id = item_db.searchname( item_name ); + + if( id == nullptr ){ + id = item_db.find( strtoul( item_name, nullptr, 10 ) ); } - else - { + + if( id == nullptr ){ clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name. return -1; } - total = amount; + t_itemid nameid = id->nameid; + int total = amount; // delete items while( amount && ( idx = pc_search_inventory(sd, nameid) ) != -1 ) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index ec43e5827c..d7dbe10085 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -14508,7 +14508,6 @@ void clif_parse_GM_Item_Monster(int fd, struct map_session_data *sd) { struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; int mob_id = 0; - struct item_data *id = NULL; StringBuf command; char *str; //#if PACKETVER >= 20131218 @@ -14533,12 +14532,14 @@ void clif_parse_GM_Item_Monster(int fd, struct map_session_data *sd) return; } + std::shared_ptr id = item_db.searchname( str ); + // Item - if( (id = itemdb_searchname(str)) ) { + if( id ){ StringBuf_Init(&command); - if( !itemdb_isstackable2(id) ) //Nonstackable + if( !itemdb_isstackable2( id.get() ) ){ //Nonstackable StringBuf_Printf(&command, "%citem2 %u 1 0 0 0 0 0 0 0", atcommand_symbol, id->nameid); - else { + }else{ if (id->flag.guid) StringBuf_Printf(&command, "%citem %u 1", atcommand_symbol, id->nameid); else @@ -20892,7 +20893,6 @@ void clif_sale_search_reply( struct map_session_data* sd, struct cash_item_data* void clif_parse_sale_search( int fd, struct map_session_data* sd ){ #if PACKETVER_SUPPORTS_SALES char item_name[ITEM_NAME_LENGTH]; - struct item_data *id = NULL; nullpo_retv(sd); @@ -20906,7 +20906,7 @@ void clif_parse_sale_search( int fd, struct map_session_data* sd ){ safestrncpy( item_name, RFIFOCP(fd, 8), min(RFIFOW(fd, 2) - 7, ITEM_NAME_LENGTH) ); - id = itemdb_searchname(item_name); + std::shared_ptr id = item_db.searchname( item_name ); if( id ){ int i; diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index d24e3830c9..f8a12148a5 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -65,7 +65,7 @@ uint64 ItemDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "AegisName", name)) return 0; - item_data* id = itemdb_search_aegisname(name.c_str()); + std::shared_ptr id = item_db.search_aegisname( name.c_str() ); if (id != nullptr && id->nameid != nameid) { this->invalidWarning(node["AegisName"], "Found duplicate item Aegis name for %s, skipping.\n", name.c_str()); @@ -518,7 +518,7 @@ uint64 ItemDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "AliasName", view)) return 0; - item_data *view_data = itemdb_search_aegisname(view.c_str()); + std::shared_ptr view_data = item_db.search_aegisname( view.c_str() ); if (view_data == nullptr) { this->invalidWarning(node["AliasName"], "Unable to change the alias because %s is an unknown item.\n", view.c_str()); @@ -1036,6 +1036,27 @@ void ItemDatabase::loadingFinished(){ item_db.put( ITEMID_DUMMY, dummy_item ); } + + // Prepare the container size to not allocate often + this->nameToItemDataMap.reserve( this->size() ); + this->aegisNameToItemDataMap.reserve( this->size() ); + + // Build the name lookup maps + for( const auto& entry : *this ){ + // Create a copy + std::string ename = entry.second->ename; + // Convert it to lower + util::tolower( ename ); + + this->nameToItemDataMap[ename] = entry.second; + + // Create a copy + std::string aegisname = entry.second->name; + // Convert it to lower + util::tolower( aegisname ); + + this->aegisNameToItemDataMap[aegisname] = entry.second; + } } /** @@ -1070,6 +1091,30 @@ e_sex ItemDatabase::defaultGender( const YAML::Node &node, std::shared_ptr( id->sex ); } +std::shared_ptr ItemDatabase::searchname( const char* name ){ + // Create a copy + std::string lowername = name; + // Convert it to lower + util::tolower( lowername ); + + return util::umap_find( this->aegisNameToItemDataMap, lowername ); +} + +std::shared_ptr ItemDatabase::search_aegisname( const char *name ){ + // Create a copy + std::string lowername = name; + // Convert it to lower + util::tolower( lowername ); + + std::shared_ptr result = util::umap_find( this->aegisNameToItemDataMap, lowername ); + + if( result != nullptr ){ + return result; + } + + return util::umap_find( this->nameToItemDataMap, lowername ); +} + ItemDatabase item_db; /** @@ -1159,15 +1204,6 @@ static struct item_data* itemdb_searchname1(const char *str, bool aegis_only) return nullptr; } -struct item_data* itemdb_searchname(const char *str) -{ - return itemdb_searchname1(str, false); -} - -struct item_data* itemdb_search_aegisname( const char *str ){ - return itemdb_searchname1( str, true ); -} - /*========================================== * Finds up to N matches. Returns number of matches [Skotlex] * @param *data @@ -1611,7 +1647,7 @@ uint64 ItemGroupDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(listit, "Clear", item_name)) continue; - struct item_data *item = itemdb_search_aegisname(item_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if (item == nullptr) { this->invalidWarning(listit["Clear"], "Unknown Item %s. Clear failed.\n", item_name.c_str()); @@ -1629,7 +1665,7 @@ uint64 ItemGroupDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(listit, "Item", item_name)) continue; - struct item_data *item = itemdb_search_aegisname(item_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if (item == nullptr) { this->invalidWarning(listit["Item"], "Unknown Item %s.\n", item_name.c_str()); diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp index 369cc4f935..99e1bd2e2b 100644 --- a/src/map/itemdb.hpp +++ b/src/map/itemdb.hpp @@ -1023,6 +1023,9 @@ extern RandomOptionGroupDatabase random_option_group; class ItemDatabase : public TypesafeCachedYamlDatabase { private: + std::unordered_map> nameToItemDataMap; + std::unordered_map> aegisNameToItemDataMap; + e_sex defaultGender( const YAML::Node &node, std::shared_ptr id ); public: @@ -1033,6 +1036,16 @@ public: const std::string getDefaultLocation(); uint64 parseBodyNode(const YAML::Node& node); void loadingFinished(); + void clear() override{ + TypesafeCachedYamlDatabase::clear(); + + this->nameToItemDataMap.clear(); + this->aegisNameToItemDataMap.clear(); + } + + // Additional + std::shared_ptr searchname( const char* name ); + std::shared_ptr search_aegisname( const char *name ); }; extern ItemDatabase item_db; @@ -1057,8 +1070,6 @@ public: extern ItemGroupDatabase itemdb_group; -struct item_data* itemdb_searchname(const char *name); -struct item_data* itemdb_search_aegisname( const char *str ); int itemdb_searchname_array(struct item_data** data, int size, const char *str); struct item_data* itemdb_search(t_itemid nameid); struct item_data* itemdb_exists(t_itemid nameid); diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 9d9429b78e..ff5ac9e6eb 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -4218,7 +4218,7 @@ bool MobDatabase::parseDropNode(std::string nodeName, YAML::Node node, uint8 max if (!this->asString(dropit, "Item", item_name)) return false; - item_data *item = itemdb_search_aegisname(item_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if (item == nullptr) { this->invalidWarning(dropit["Item"], "Monster %s item %s does not exist, skipping.\n", nodeName.c_str(), item_name.c_str()); @@ -5296,7 +5296,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "Weapon", weapon)) return 0; - struct item_data *item = itemdb_search_aegisname(weapon.c_str()); + std::shared_ptr item = item_db.search_aegisname( weapon.c_str() ); if (item == nullptr) { this->invalidWarning(node["Weapon"], "Weapon %s is not a valid item.\n", weapon.c_str()); @@ -5317,7 +5317,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "Shield", shield)) return 0; - struct item_data *item = itemdb_search_aegisname(shield.c_str()); + std::shared_ptr item = item_db.search_aegisname( shield.c_str() ); if (item == nullptr) { this->invalidWarning(node["Shield"], "Shield %s is not a valid item.\n", shield.c_str()); @@ -5338,9 +5338,9 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "HeadTop", head)) return 0; - struct item_data *item; + std::shared_ptr item = item_db.search_aegisname( head.c_str() ); - if ((item = itemdb_search_aegisname(head.c_str())) == nullptr) { + if (item == nullptr) { this->invalidWarning(node["HeadTop"], "HeadTop %s is not a valid item.\n", head.c_str()); return 0; } @@ -5359,7 +5359,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "HeadMid", head)) return 0; - struct item_data *item = itemdb_search_aegisname(head.c_str()); + std::shared_ptr item = item_db.search_aegisname( head.c_str() ); if (item == nullptr) { this->invalidWarning(node["HeadMid"], "HeadMid %s is not a valid item.\n", head.c_str()); @@ -5380,7 +5380,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "HeadLow", head)) return 0; - struct item_data *item = itemdb_search_aegisname(head.c_str()); + std::shared_ptr item = item_db.search_aegisname( head.c_str() ); if (item == nullptr) { this->invalidWarning(node["HeadLow"], "HeadLow %s is not a valid item.\n", head.c_str()); @@ -5403,7 +5403,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "PetEquip", equipment)) return 0; - struct item_data *item = itemdb_search_aegisname(equipment.c_str()); + std::shared_ptr item = item_db.search_aegisname( equipment.c_str() ); if (item == nullptr) { this->invalidWarning(node["PetEquip"], "PetEquip %s is not a valid item.\n", equipment.c_str()); diff --git a/src/map/pet.cpp b/src/map/pet.cpp index cb4e14a90c..ff70eb7846 100644 --- a/src/map/pet.cpp +++ b/src/map/pet.cpp @@ -75,7 +75,7 @@ uint64 PetDatabase::parseBodyNode( const YAML::Node &node ){ return 0; } - struct item_data* item = itemdb_search_aegisname( item_name.c_str() ); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if( item == nullptr ){ this->invalidWarning( node["TameItem"], "Taming item %s does not exist.\n", item_name.c_str() ); @@ -96,7 +96,7 @@ uint64 PetDatabase::parseBodyNode( const YAML::Node &node ){ return 0; } - struct item_data* item = itemdb_search_aegisname( item_name.c_str() ); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if( item == nullptr ){ this->invalidWarning( node["EggItem"], "Egg item %s does not exist.\n", item_name.c_str() ); @@ -113,7 +113,7 @@ uint64 PetDatabase::parseBodyNode( const YAML::Node &node ){ return 0; } - struct item_data* item = itemdb_search_aegisname( item_name.c_str() ); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if( item == nullptr ){ this->invalidWarning( node["EquipItem"], "Equip item %s does not exist.\n", item_name.c_str() ); @@ -134,7 +134,7 @@ uint64 PetDatabase::parseBodyNode( const YAML::Node &node ){ return 0; } - struct item_data* item = itemdb_search_aegisname( item_name.c_str() ); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if( item == nullptr ){ this->invalidWarning( node["FoodItem"], "Food item %s does not exist.\n", item_name.c_str() ); @@ -441,7 +441,7 @@ uint64 PetDatabase::parseBodyNode( const YAML::Node &node ){ return 0; } - struct item_data* item = itemdb_search_aegisname( item_name.c_str() ); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if( item == nullptr ){ this->invalidWarning( requirementNode["Item"], "Evolution requirement item %s does not exist.\n", item_name.c_str() ); diff --git a/src/map/quest.cpp b/src/map/quest.cpp index ba108aa1a3..7fa708ede4 100644 --- a/src/map/quest.cpp +++ b/src/map/quest.cpp @@ -375,7 +375,7 @@ uint64 QuestDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(dropNode, "Item", item_name)) return 0; - struct item_data *item = itemdb_search_aegisname(item_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if (!item) { this->invalidWarning(dropNode["Item"], "Item %s does not exist, skipping.\n", item_name.c_str()); diff --git a/src/map/script.cpp b/src/map/script.cpp index d2a6c30a38..7c6a950bf1 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -6928,7 +6928,7 @@ static int script_getitem_randomoption(struct script_state *st, struct map_sessi * @param rental: Whether or not to count rental items * @return Total count of item being searched */ -static int script_countitem_sub(struct item *items, struct item_data *id, int size, bool expanded, bool random_option, struct script_state *st, struct map_session_data *sd = nullptr, bool rental = false) { +static int script_countitem_sub(struct item *items, std::shared_ptr id, int size, bool expanded, bool random_option, struct script_state *st, struct map_session_data *sd = nullptr, bool rental = false) { nullpo_retr(-1, items); nullpo_retr(-1, st); @@ -7022,12 +7022,12 @@ BUILDIN_FUNC(countitem) if (!script_accid2sd(aid, sd)) return SCRIPT_CMD_FAILURE; - struct item_data *id; + std::shared_ptr id; if (script_isstring(st, 2)) // item name - id = itemdb_searchname(script_getstr(st, 2)); + id = item_db.searchname( script_getstr( st, 2 ) ); else // item id - id = itemdb_exists(script_getnum(st, 2)); + id = item_db.find( script_getnum( st, 2 ) ); if (!id) { ShowError("buildin_%s: Invalid item '%s'.\n", command, script_getstr(st, 2)); // returns string, regardless of what it was @@ -7067,12 +7067,12 @@ BUILDIN_FUNC(cartcountitem) return SCRIPT_CMD_FAILURE; } - struct item_data *id; + std::shared_ptr id; if (script_isstring(st, 2)) // item name - id = itemdb_searchname(script_getstr(st, 2)); + id = item_db.searchname( script_getstr( st, 2 ) ); else // item id - id = itemdb_exists(script_getnum(st, 2)); + id = item_db.find( script_getnum( st, 2 ) ); if (!id) { ShowError("buildin_%s: Invalid item '%s'.\n", command, script_getstr(st, 2)); // returns string, regardless of what it was @@ -7106,12 +7106,12 @@ BUILDIN_FUNC(storagecountitem) if (!script_accid2sd(aid, sd)) return SCRIPT_CMD_FAILURE; - struct item_data *id; + std::shared_ptr id; if (script_isstring(st, 2)) // item name - id = itemdb_searchname(script_getstr(st, 2)); + id = item_db.searchname( script_getstr( st, 2 ) ); else // item id - id = itemdb_exists(script_getnum(st, 2)); + id = item_db.find( script_getnum( st, 2 ) ); if (!id) { ShowError("buildin_%s: Invalid item '%s'.\n", command, script_getstr(st, 2)); // returns string, regardless of what it was @@ -7150,12 +7150,12 @@ BUILDIN_FUNC(guildstoragecountitem) if (!script_accid2sd(aid, sd)) return SCRIPT_CMD_FAILURE; - struct item_data *id; + std::shared_ptr id; if (script_isstring(st, 2)) // item name - id = itemdb_searchname(script_getstr(st, 2)); + id = item_db.searchname( script_getstr( st, 2 ) ); else // item id - id = itemdb_exists(script_getnum(st, 2)); + id = item_db.find( script_getnum( st, 2 ) ); if (!id) { ShowError("buildin_%s: Invalid item '%s'.\n", command, script_getstr(st, 2)); // returns string, regardless of what it was @@ -7211,12 +7211,12 @@ BUILDIN_FUNC(rentalcountitem) if (!script_accid2sd(aid, sd)) return SCRIPT_CMD_FAILURE; - item_data *id; + std::shared_ptr id; if (script_isstring(st, 2)) // item name - id = itemdb_searchname(script_getstr(st, 2)); + id = item_db.searchname( script_getstr( st, 2 ) ); else // item id - id = itemdb_exists(script_getnum(st, 2)); + id = item_db.find( script_getnum( st, 2 ) ); if (!id) { ShowError("buildin_%s: Invalid item '%s'.\n", command, script_getstr(st, 2)); // returns string, regardless of what it was @@ -7245,7 +7245,7 @@ BUILDIN_FUNC(checkweight) int slots = 0; unsigned short amount2 = 0; unsigned int weight = 0, i, nbargs; - struct item_data* id = NULL; + std::shared_ptr id; struct map_session_data* sd; if( !script_rid2sd(sd) ) @@ -7264,10 +7264,10 @@ BUILDIN_FUNC(checkweight) unsigned short amount; if( script_isstring(st, i) ) // item name - id = itemdb_searchname(script_getstr(st, i)); + id = item_db.searchname( script_getstr( st, i ) ); else // item id - id = itemdb_exists(script_getnum(st, i)); - if( id == NULL ) { + id = item_db.find( script_getnum( st, i ) ); + if( id == nullptr ){ ShowError("buildin_checkweight: Invalid item '%s'.\n", script_getstr(st,i)); // returns string, regardless of what it was script_pushint(st,0); return SCRIPT_CMD_FAILURE; @@ -7436,23 +7436,27 @@ BUILDIN_FUNC(getitem) t_itemid nameid; unsigned short amount; struct item it; - TBL_PC *sd; + struct map_session_data *sd; unsigned char flag = 0; const char* command = script_getfuncname(st); - struct item_data *id = NULL; + std::shared_ptr id; if( script_isstring(st, 2) ) {// "" const char *name = script_getstr(st, 2); - id = itemdb_searchname(name); - if( id == NULL ){ + id = item_db.searchname( name ); + + if( id == nullptr ){ ShowError("buildin_getitem: Nonexistant item %s requested.\n", name); return SCRIPT_CMD_FAILURE; //No item created. } nameid = id->nameid; } else {// nameid = script_getnum(st, 2); - if( !(id = itemdb_exists(nameid)) ){ + + id = item_db.find( nameid ); + + if( id == nullptr ){ ShowError("buildin_getitem: Nonexistant item %u requested.\n", nameid); return SCRIPT_CMD_FAILURE; //No item created. } @@ -7483,10 +7487,11 @@ BUILDIN_FUNC(getitem) return SCRIPT_CMD_SUCCESS; //Check if it's stackable. - if (!itemdb_isstackable2(id)) + if( !itemdb_isstackable2( id.get() ) ){ get_count = 1; - else + }else{ get_count = amount; + } for (i = 0; i < amount; i += get_count) { @@ -7530,7 +7535,7 @@ BUILDIN_FUNC(getitem2) int iden, ref, attr; t_itemid c1, c2, c3, c4; char bound = BOUND_NONE; - struct item_data *item_data = NULL; + std::shared_ptr item_data; struct item item_tmp; TBL_PC *sd; const char* command = script_getfuncname(st); @@ -7563,14 +7568,19 @@ BUILDIN_FUNC(getitem2) if( script_isstring(st, 2) ) { const char *name = script_getstr(st, 2); - if( (item_data = itemdb_searchname(name)) == NULL ){ + item_data = item_db.searchname( name ); + + if( item_data == nullptr ){ ShowError("buildin_getitem2: Nonexistant item %s requested (by conv_str).\n", name); return SCRIPT_CMD_FAILURE; //No item created. } nameid = item_data->nameid; } else { nameid = script_getnum(st, 2); - if( (item_data = itemdb_exists(nameid)) == NULL ){ + + item_data = item_db.find( nameid ); + + if( item_data == nullptr ){ ShowError("buildin_getitem2: Nonexistant item %u requested (by conv_num).\n", nameid); return SCRIPT_CMD_FAILURE; //No item created. } @@ -7618,10 +7628,11 @@ BUILDIN_FUNC(getitem2) } //Check if it's stackable. - if (!itemdb_isstackable2(item_data)) + if( !itemdb_isstackable2( item_data.get() ) ){ get_count = 1; - else + }else{ get_count = amount; + } for (i = 0; i < amount; i += get_count) { @@ -7658,10 +7669,9 @@ BUILDIN_FUNC(rentitem) { if( script_isstring(st, 2) ) { const char *name = script_getstr(st, 2); - struct item_data *itd = itemdb_searchname(name); + std::shared_ptr itd = item_db.searchname( name ); - if( itd == NULL ) - { + if( itd == nullptr ){ ShowError("buildin_rentitem: Nonexistant item %s requested.\n", name); return SCRIPT_CMD_FAILURE; } @@ -7703,7 +7713,7 @@ BUILDIN_FUNC(rentitem) { BUILDIN_FUNC(rentitem2) { struct map_session_data *sd; struct item it; - struct item_data *id; + std::shared_ptr id; int seconds; t_itemid nameid = 0; unsigned char flag = 0; @@ -7720,15 +7730,19 @@ BUILDIN_FUNC(rentitem2) { if( script_isstring(st, 2) ) { const char *name = script_getstr(st, 2); - id = itemdb_searchname(name); - if( id == NULL ) { + id = item_db.searchname( name ); + + if( id == nullptr ) { ShowError("buildin_rentitem2: Nonexistant item %s requested.\n", name); return SCRIPT_CMD_FAILURE; } nameid = id->nameid; } else { nameid = script_getnum(st, 2); - if( !(id = itemdb_search(nameid))) { + + id = item_db.find( nameid ); + + if( id == nullptr ){ ShowError("buildin_rentitem2: Nonexistant item %u requested.\n", nameid); return SCRIPT_CMD_FAILURE; } @@ -7802,10 +7816,10 @@ BUILDIN_FUNC(getnameditem) if( script_isstring(st, 2) ){ const char *name = script_getstr(st, 2); - struct item_data *item_data = itemdb_searchname(name); + std::shared_ptr item_data = item_db.searchname( name ); - if( item_data == NULL) - { //Failed + // Failed + if( item_data == nullptr){ script_pushint(st,0); return SCRIPT_CMD_SUCCESS; } @@ -7877,7 +7891,7 @@ BUILDIN_FUNC(makeitem) { if( script_isstring(st, 2) ){ const char *name = script_getstr(st, 2); - struct item_data *item_data = itemdb_searchname(name); + std::shared_ptr item_data = item_db.searchname( name ); if( item_data ) nameid = item_data->nameid; @@ -7944,7 +7958,7 @@ BUILDIN_FUNC(makeitem2) { if( script_isstring( st, 2 ) ){ const char *name = script_getstr( st, 2 ); - struct item_data *item_data = itemdb_searchname( name ); + std::shared_ptr item_data = item_db.searchname( name ); if( item_data ){ nameid = item_data->nameid; @@ -8288,10 +8302,9 @@ BUILDIN_FUNC(delitem) if( script_isstring(st, 2) ) { const char* item_name = script_getstr(st, 2); - struct item_data* id = itemdb_searchname(item_name); + std::shared_ptr id = item_db.searchname(item_name); - if( id == NULL ) - { + if( id == nullptr ){ ShowError("buildin_%s: unknown item \"%s\".\n", command, item_name); st->state = END; return SCRIPT_CMD_FAILURE; @@ -8382,10 +8395,9 @@ BUILDIN_FUNC(delitem2) if( script_isstring(st, 2) ) { const char* item_name = script_getstr(st, 2); - struct item_data* id = itemdb_searchname(item_name); + std::shared_ptr id = item_db.searchname( item_name ); - if( id == NULL ) - { + if( id == nullptr ){ ShowError("buildin_%s: unknown item \"%s\".\n", command, item_name); st->state = END; return SCRIPT_CMD_FAILURE; @@ -11613,7 +11625,7 @@ BUILDIN_FUNC(getareadropitem) if( script_isstring(st, 7) ){ const char *name = script_getstr(st, 7); - struct item_data *item_data = itemdb_searchname(name); + std::shared_ptr item_data = item_db.searchname( name ); if( item_data ) nameid=item_data->nameid; @@ -13949,29 +13961,24 @@ BUILDIN_FUNC(guardianinfo) *------------------------------------------*/ BUILDIN_FUNC(getitemname) { - t_itemid item_id = 0; - struct item_data *i_data; - char *item_name; + std::shared_ptr i_data; if( script_isstring(st, 2) ){ - const char *name = script_getstr(st, 2); - struct item_data *item_data = itemdb_searchname(name); + i_data = item_db.searchname( script_getstr( st, 2 ) ); + }else{ + i_data = item_db.find( script_getnum( st, 2 ) ); + } - if( item_data ) - item_id=item_data->nameid; - }else - item_id = script_getnum(st, 2); - - i_data = itemdb_exists(item_id); - if (i_data == NULL) - { + if( i_data == nullptr ){ script_pushconststr(st,"null"); return SCRIPT_CMD_SUCCESS; } - item_name=(char *)aMalloc(ITEM_NAME_LENGTH*sizeof(char)); + + char* item_name = (char *)aMalloc( ITEM_NAME_LENGTH * sizeof( char ) ); memcpy(item_name, i_data->ename.c_str(), ITEM_NAME_LENGTH); script_pushstr(st,item_name); + return SCRIPT_CMD_SUCCESS; } @@ -14001,13 +14008,13 @@ BUILDIN_FUNC(getitemslots) *------------------------------------------*/ BUILDIN_FUNC(getiteminfo) { - item_data *i_data; + std::shared_ptr i_data; int type = script_getnum(st, 3); if (script_isstring(st, 2)) - i_data = itemdb_searchname(script_getstr(st, 2)); + i_data = item_db.searchname( script_getstr( st, 2 ) ); else - i_data = itemdb_exists(script_getnum(st, 2)); + i_data = item_db.find( script_getnum( st, 2 ) ); if (i_data == nullptr) { if (type != ITEMINFO_AEGISNAME) @@ -14062,12 +14069,12 @@ BUILDIN_FUNC(getiteminfo) *------------------------------------------*/ BUILDIN_FUNC(setiteminfo) { - item_data *i_data; + std::shared_ptr i_data; if (script_isstring(st, 2)) - i_data = itemdb_search_aegisname(script_getstr(st, 2)); + i_data = item_db.search_aegisname( script_getstr( st, 2 ) ); else - i_data = itemdb_exists(script_getnum(st, 2)); + i_data = item_db.find( script_getnum( st, 2 ) ); if (i_data == nullptr) { script_pushint(st, -1); @@ -22021,8 +22028,8 @@ BUILDIN_FUNC(npcskill) */ BUILDIN_FUNC(consumeitem) { - TBL_PC *sd; - struct item_data *item_data; + struct map_session_data *sd; + std::shared_ptr item_data; if (!script_charid2sd(3, sd)) return SCRIPT_CMD_FAILURE; @@ -22030,14 +22037,18 @@ BUILDIN_FUNC(consumeitem) if( script_isstring(st, 2) ){ const char *name = script_getstr(st, 2); - if( ( item_data = itemdb_searchname( name ) ) == NULL ){ + item_data = item_db.searchname( name ); + + if( item_data == nullptr ){ ShowError( "buildin_consumeitem: Nonexistant item %s requested.\n", name ); return SCRIPT_CMD_FAILURE; } } else { t_itemid nameid = script_getnum(st, 2); - if( ( item_data = itemdb_exists( nameid ) ) == NULL ){ + item_data = item_db.find( nameid ); + + if( item_data == nullptr ){ ShowError("buildin_consumeitem: Nonexistant item %u requested.\n", nameid ); return SCRIPT_CMD_FAILURE; } @@ -22774,9 +22785,9 @@ BUILDIN_FUNC(mergeitem2) { if (script_hasdata(st, 2)) { if (script_isstring(st, 2)) {// "" const char *name = script_getstr(st, 2); - struct item_data *id; + std::shared_ptr id = item_db.searchname( name ); - if (!(id = itemdb_searchname(name))) { + if( id == nullptr ){ ShowError("buildin_mergeitem2: Nonexistant item %s requested.\n", name); script_pushint(st, count); return SCRIPT_CMD_FAILURE; diff --git a/src/map/skill.cpp b/src/map/skill.cpp index ed53967646..56fa188a61 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -22335,7 +22335,7 @@ uint64 SkillDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(it, "Item", item_name)) continue; - struct item_data *item = itemdb_search_aegisname(item_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if (item == nullptr) { this->invalidWarning(itemNode["Item"], "Requires ItemCost Item %s does not exist.\n", item_name.c_str()); @@ -22358,7 +22358,7 @@ uint64 SkillDatabase::parseBodyNode(const YAML::Node &node) { for (const auto &it : equipNode) { std::string item_name = it.first.as(); - struct item_data *item = itemdb_search_aegisname(item_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if (item == nullptr) { this->invalidWarning(equipNode, "Requires Equipment %s does not exist.\n", item_name.c_str()); @@ -22575,7 +22575,7 @@ uint64 ReadingSpellbookDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "Book", book_name)) return 0; - struct item_data *item = itemdb_search_aegisname(book_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( book_name.c_str() ); if (item == nullptr) { this->invalidWarning(node["Book"], "Book item %s does not exist.\n", book_name.c_str()); @@ -22731,7 +22731,7 @@ uint64 SkillArrowDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "Source", source_name)) return 0; - struct item_data *item = itemdb_search_aegisname(source_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( source_name.c_str() ); if (item == nullptr) { this->invalidWarning(node["Source"], "Item %s does not exist.\n", source_name.c_str()); @@ -22756,7 +22756,7 @@ uint64 SkillArrowDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(it, "Item", item_name)) return 0; - struct item_data *item = itemdb_search_aegisname(item_name.c_str()); + std::shared_ptr item = item_db.search_aegisname( item_name.c_str() ); if (item == nullptr) { this->invalidWarning(it["Item"], "Item %s does not exist.\n", item_name.c_str()); diff --git a/src/map/status.cpp b/src/map/status.cpp index b97d6b0d22..3249cc41e8 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -292,7 +292,7 @@ uint64 RefineDatabase::parseBodyNode( const YAML::Node& node ){ return 0; } - struct item_data* id = itemdb_search_aegisname( item_name.c_str() ); + std::shared_ptr id = item_db.search_aegisname( item_name.c_str() ); if( id == nullptr ){ this->invalidWarning( chanceNode["Material"], "Unknown refine material %s, skipping.\n", item_name.c_str() ); diff --git a/src/tool/yaml.hpp b/src/tool/yaml.hpp index 361cccc804..37fa914dd3 100644 --- a/src/tool/yaml.hpp +++ b/src/tool/yaml.hpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -378,7 +377,7 @@ static bool isMultiLevel(int arr[]) { * @return Converted string */ std::string name2Upper(std::string name) { - std::transform(name.begin(), name.end(), name.begin(), ::tolower); + util::tolower( name ); name[0] = toupper(name[0]); for (size_t i = 0; i < name.size(); i++) {