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 <secretdataz@users.noreply.github.com>
This commit is contained in:
Lemongrass3110 2021-08-08 16:46:44 +02:00 committed by GitHub
parent 666311099e
commit 6b84115790
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 253 additions and 169 deletions

View File

@ -5,6 +5,7 @@
#define UTILILITIES_HPP
#include <algorithm>
#include <locale>
#include <map>
#include <memory>
#include <string>
@ -258,6 +259,10 @@ namespace rathena {
return result;
}
}
template <typename T> void tolower( T& string ){
std::transform( string.begin(), string.end(), string.begin(), ::tolower );
}
}
}

View File

@ -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_data> 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());

View File

@ -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 <item name/ID> <quantity>).
return -1;
}
std::vector<std::shared_ptr<item_data>> 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_data> 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_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_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_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> 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<item_data> 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 )

View File

@ -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<item_data> 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<item_data> id = item_db.searchname( item_name );
if( id ){
int i;

View File

@ -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<item_data> 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<item_data> 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<item_
return static_cast<e_sex>( id->sex );
}
std::shared_ptr<item_data> 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<item_data> ItemDatabase::search_aegisname( const char *name ){
// Create a copy
std::string lowername = name;
// Convert it to lower
util::tolower( lowername );
std::shared_ptr<item_data> 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_data> 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_data> item = item_db.search_aegisname( item_name.c_str() );
if (item == nullptr) {
this->invalidWarning(listit["Item"], "Unknown Item %s.\n", item_name.c_str());

View File

@ -1023,6 +1023,9 @@ extern RandomOptionGroupDatabase random_option_group;
class ItemDatabase : public TypesafeCachedYamlDatabase<t_itemid, item_data> {
private:
std::unordered_map<std::string, std::shared_ptr<item_data>> nameToItemDataMap;
std::unordered_map<std::string, std::shared_ptr<item_data>> aegisNameToItemDataMap;
e_sex defaultGender( const YAML::Node &node, std::shared_ptr<item_data> 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<item_data> searchname( const char* name );
std::shared_ptr<item_data> 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);

View File

@ -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_data> 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_data> 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_data> 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_data> 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_data> 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_data> 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_data> 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());

View File

@ -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_data> 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_data> 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_data> 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_data> 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_data> 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() );

View File

@ -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_data> 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());

View File

@ -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<item_data> 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<item_data> 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<item_data> 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<item_data> 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<item_data> 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<item_data> 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<item_data> 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<item_data> id;
if( script_isstring(st, 2) ) {// "<item name>"
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 {// <item id>
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> 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<item_data> 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<item_data> 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_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_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_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<item_data> 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<item_data> 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_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<item_data> 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<item_data> 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<item_data> 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> 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)) {// "<item name>"
const char *name = script_getstr(st, 2);
struct item_data *id;
std::shared_ptr<item_data> 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;

View File

@ -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_data> 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<std::string>();
struct item_data *item = itemdb_search_aegisname(item_name.c_str());
std::shared_ptr<item_data> 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_data> 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_data> 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_data> 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());

View File

@ -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<item_data> 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() );

View File

@ -7,7 +7,6 @@
#include <fstream>
#include <functional>
#include <iostream>
#include <locale>
#include <map>
#include <unordered_map>
#include <vector>
@ -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++) {