Speed up item and mob information commands (#7084)
* Fixes #7081. * Small refactor of the atcommands: iteminfo, mobinfo, whodrops, and idsearch. * Item information gathering is now sped up. * Refactored itemdb_searchname_array to store results in a std::map so that the data is sorted by ID automatically. * Cleanups across the board to remove extra calls for itemdb_exists(). Thanks to @voyfmyuh, @CairoLee, and @Lemongrass3110!
This commit is contained in:
@@ -83,6 +83,19 @@ namespace rathena {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize a map.
|
||||
* @param map: Map to resize
|
||||
* @param size: Size to set map to
|
||||
*/
|
||||
template <typename K, typename V, typename S> void map_resize(std::map<K, V> &map, S size) {
|
||||
auto it = map.begin();
|
||||
|
||||
std::advance(it, size);
|
||||
|
||||
map.erase(it, map.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a key-value pair and return the key value as a reference
|
||||
* @param map: Unordered Map to search through
|
||||
@@ -129,6 +142,15 @@ namespace rathena {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize an unordered map.
|
||||
* @param map: Unordered map to resize
|
||||
* @param size: Size to set unordered map to
|
||||
*/
|
||||
template <typename K, typename V, typename S> void umap_resize(std::unordered_map<K, V> &map, S size) {
|
||||
map.erase(std::advance(map.begin(), map.min(size, map.size())), map.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random value from the given unordered map
|
||||
* @param map: Unordered Map to search through
|
||||
|
||||
@@ -3911,28 +3911,33 @@ ACMD_FUNC(mapexit)
|
||||
*------------------------------------------*/
|
||||
ACMD_FUNC(idsearch)
|
||||
{
|
||||
char item_name[100];
|
||||
uint16 i, match;
|
||||
struct item_data *item_array[MAX_SEARCH];
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
char item_name[100];
|
||||
|
||||
memset(item_name, '\0', sizeof(item_name));
|
||||
memset(atcmd_output, '\0', sizeof(atcmd_output));
|
||||
|
||||
if (!message || !*message || sscanf(message, "%99s", item_name) < 0) {
|
||||
clif_displaymessage(fd, msg_txt(sd,1031)); // Please enter part of an item name (usage: @idsearch <part_of_item_name>).
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(atcmd_output, '\0', sizeof(atcmd_output));
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,77), item_name); // The reference result of '%s' (name: id):
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
match = itemdb_searchname_array(item_array, MAX_SEARCH, item_name);
|
||||
|
||||
std::map<t_itemid, std::shared_ptr<item_data>> item_array = {};
|
||||
uint16 match = itemdb_searchname_array(item_array, MAX_SEARCH, item_name);
|
||||
|
||||
if (match == MAX_SEARCH) {
|
||||
sprintf(atcmd_output, msg_txt(sd,269), MAX_SEARCH); // Displaying first %d matches
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
for(i = 0; i < match; i++) {
|
||||
sprintf(atcmd_output, msg_txt(sd,78), item_array[i]->ename.c_str(), item_array[i]->nameid); // %s: %u
|
||||
for(const auto &result : item_array) {
|
||||
std::shared_ptr<item_data> id = result.second;
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,78), id->ename.c_str(), id->nameid); // %s: %u
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
sprintf(atcmd_output, msg_txt(sd,79), match); // It is %d affair above.
|
||||
@@ -5840,7 +5845,6 @@ ACMD_FUNC(dropall)
|
||||
{
|
||||
int8 type = -1;
|
||||
uint16 i, count = 0, count2 = 0;
|
||||
struct item_data *item_data = NULL;
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
@@ -5857,14 +5861,16 @@ ACMD_FUNC(dropall)
|
||||
|
||||
for( i = 0; i < MAX_INVENTORY; i++ ) {
|
||||
if( sd->inventory.u.items_inventory[i].amount ) {
|
||||
if( (item_data = itemdb_exists(sd->inventory.u.items_inventory[i].nameid)) == NULL ) {
|
||||
std::shared_ptr<item_data> id = item_db.find(sd->inventory.u.items_inventory[i].nameid);
|
||||
|
||||
if( id == nullptr ) {
|
||||
ShowDebug("Non-existant item %d on dropall list (account_id: %d, char_id: %d)\n", sd->inventory.u.items_inventory[i].nameid, sd->status.account_id, sd->status.char_id);
|
||||
continue;
|
||||
}
|
||||
if( !pc_candrop(sd,&sd->inventory.u.items_inventory[i]) )
|
||||
continue;
|
||||
|
||||
if( type == -1 || type == (uint8)item_data->type ) {
|
||||
if( type == -1 || type == (uint8)id->type ) {
|
||||
if( sd->inventory.u.items_inventory[i].equip != 0 )
|
||||
pc_unequipitem(sd, i, 3);
|
||||
if( itemdb_ishatched_egg( &sd->inventory.u.items_inventory[i] ) ){
|
||||
@@ -7612,9 +7618,8 @@ ACMD_FUNC(mobinfo)
|
||||
unsigned char mrace[RC_ALL][11] = { "Formless", "Undead", "Beast", "Plant", "Insect", "Fish", "Demon", "Demi-Human", "Angel", "Dragon", "Player" };
|
||||
unsigned char melement[ELE_ALL][8] = { "Neutral", "Water", "Earth", "Fire", "Wind", "Poison", "Holy", "Dark", "Ghost", "Undead" };
|
||||
char atcmd_output2[CHAT_SIZE_MAX];
|
||||
struct item_data *item_data;
|
||||
uint16 mob_ids[MAX_SEARCH], count;
|
||||
int i, k;
|
||||
uint16 i;
|
||||
|
||||
memset(atcmd_output, '\0', sizeof(atcmd_output));
|
||||
memset(atcmd_output2, '\0', sizeof(atcmd_output2));
|
||||
@@ -7625,7 +7630,7 @@ ACMD_FUNC(mobinfo)
|
||||
}
|
||||
|
||||
// If monster identifier/name argument is a name
|
||||
if ((i = mobdb_checkid(atoi(message))))
|
||||
if ((i = mobdb_checkid(strtoul(message, nullptr, 10))))
|
||||
{
|
||||
mob_ids[0] = i;
|
||||
count = 1;
|
||||
@@ -7642,7 +7647,7 @@ ACMD_FUNC(mobinfo)
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
count = MAX_SEARCH;
|
||||
}
|
||||
for (k = 0; k < count; k++) {
|
||||
for (uint16 k = 0; k < count; k++) {
|
||||
std::shared_ptr<s_mob_db> mob = mob_db.find(mob_ids[k]);
|
||||
|
||||
if (mob == nullptr)
|
||||
@@ -7697,15 +7702,21 @@ ACMD_FUNC(mobinfo)
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_MOB_DROP_TOTAL; i++) {
|
||||
if (mob->dropitem[i].nameid == 0 || mob->dropitem[i].rate < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL)
|
||||
|
||||
if (mob->dropitem[i].nameid == 0 || mob->dropitem[i].rate < 1)
|
||||
continue;
|
||||
|
||||
std::shared_ptr<item_data> id = item_db.find(mob->dropitem[i].nameid);
|
||||
|
||||
if (id == nullptr)
|
||||
continue;
|
||||
|
||||
int droprate = mob_getdroprate( &sd->bl, mob, mob->dropitem[i].rate, drop_modifier );
|
||||
|
||||
if (item_data->slots)
|
||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->ename.c_str(), item_data->slots, (float)droprate / 100);
|
||||
if (id->slots)
|
||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", id->ename.c_str(), id->slots, (float)droprate / 100);
|
||||
else
|
||||
sprintf(atcmd_output2, " - %s %02.02f%%", item_data->ename.c_str(), (float)droprate / 100);
|
||||
sprintf(atcmd_output2, " - %s %02.02f%%", id->ename.c_str(), (float)droprate / 100);
|
||||
strcat(atcmd_output, atcmd_output2);
|
||||
if (++j % 3 == 0) {
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
@@ -7725,8 +7736,15 @@ ACMD_FUNC(mobinfo)
|
||||
mvpremain = 100.0; //Remaining drop chance for official mvp drop mode
|
||||
j = 0;
|
||||
for (i = 0; i < MAX_MVP_DROP_TOTAL; i++) {
|
||||
if (mob->mvpitem[i].nameid == 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL)
|
||||
|
||||
if (mob->mvpitem[i].nameid == 0)
|
||||
continue;
|
||||
|
||||
std::shared_ptr<item_data> id = item_db.find(mob->mvpitem[i].nameid);
|
||||
|
||||
if (id == nullptr)
|
||||
continue;
|
||||
|
||||
//Because if there are 3 MVP drops at 50%, the first has a chance of 50%, the second 25% and the third 12.5%
|
||||
mvppercent = (float)mob->mvpitem[i].rate * mvpremain / 10000.0f;
|
||||
if(battle_config.item_drop_mvp_mode == 0) {
|
||||
@@ -7735,15 +7753,15 @@ ACMD_FUNC(mobinfo)
|
||||
if (mvppercent > 0) {
|
||||
j++;
|
||||
if (j == 1) {
|
||||
if (item_data->slots)
|
||||
sprintf(atcmd_output2, " %s[%d] %02.02f%%", item_data->ename.c_str(), item_data->slots, mvppercent);
|
||||
if (id->slots)
|
||||
sprintf(atcmd_output2, " %s[%d] %02.02f%%", id->ename.c_str(), id->slots, mvppercent);
|
||||
else
|
||||
sprintf(atcmd_output2, " %s %02.02f%%", item_data->ename.c_str(), mvppercent);
|
||||
sprintf(atcmd_output2, " %s %02.02f%%", id->ename.c_str(), mvppercent);
|
||||
} else {
|
||||
if (item_data->slots)
|
||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->ename.c_str(), item_data->slots, mvppercent);
|
||||
if (id->slots)
|
||||
sprintf(atcmd_output2, " - %s[%d] %02.02f%%", id->ename.c_str(), id->slots, mvppercent);
|
||||
else
|
||||
sprintf(atcmd_output2, " - %s %02.02f%%", item_data->ename.c_str(), mvppercent);
|
||||
sprintf(atcmd_output2, " - %s %02.02f%%", id->ename.c_str(), mvppercent);
|
||||
}
|
||||
strcat(atcmd_output, atcmd_output2);
|
||||
}
|
||||
@@ -8149,15 +8167,21 @@ ACMD_FUNC(homshuffle)
|
||||
*------------------------------------------*/
|
||||
ACMD_FUNC(iteminfo)
|
||||
{
|
||||
struct item_data *item_array[MAX_SEARCH];
|
||||
uint16 i, count = 1;
|
||||
|
||||
if (!message || !*message) {
|
||||
clif_displaymessage(fd, msg_txt(sd,1276)); // Please enter an item name/ID (usage: @ii/@iteminfo <item name/ID>).
|
||||
return -1;
|
||||
}
|
||||
if ((item_array[0] = itemdb_exists(strtoul(message, nullptr, 10))) == nullptr)
|
||||
|
||||
std::map<t_itemid, std::shared_ptr<item_data>> item_array = {};
|
||||
uint16 count = 1;
|
||||
t_itemid itemid = strtoul(message, nullptr, 10);
|
||||
|
||||
if (itemid == 0) // Entered a string
|
||||
count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
|
||||
else {
|
||||
if ((item_array[0] = item_db.find(itemid)) == nullptr)
|
||||
count = 0;
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name.
|
||||
@@ -8168,8 +8192,9 @@ ACMD_FUNC(iteminfo)
|
||||
sprintf(atcmd_output, msg_txt(sd,269), MAX_SEARCH); // Displaying first %d matches
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
struct item_data * item_data = item_array[i];
|
||||
for (const auto &result : item_array) {
|
||||
std::shared_ptr<item_data> item_data = result.second;
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,1277), // Item: '%s'/'%s'[%d] (%u) Type: %s | Extra Effect: %s
|
||||
item_data->name.c_str(),item_data->ename.c_str(),item_data->slots,item_data->nameid,
|
||||
(item_data->type != IT_AMMO) ? itemdb_typename((enum item_types)item_data->type) : itemdb_typename_ammo((e_ammo_type)item_data->subtype),
|
||||
@@ -8200,15 +8225,21 @@ ACMD_FUNC(iteminfo)
|
||||
*------------------------------------------*/
|
||||
ACMD_FUNC(whodrops)
|
||||
{
|
||||
struct item_data *item_data, *item_array[MAX_SEARCH];
|
||||
uint16 i, j, count = 1;
|
||||
|
||||
if (!message || !*message) {
|
||||
clif_displaymessage(fd, msg_txt(sd,1284)); // Please enter item name/ID (usage: @whodrops <item name/ID>).
|
||||
return -1;
|
||||
}
|
||||
if ((item_array[0] = itemdb_exists(strtoul(message, nullptr, 10))) == nullptr)
|
||||
|
||||
std::map<t_itemid, std::shared_ptr<item_data>> item_array = {};
|
||||
uint16 count = 1;
|
||||
t_itemid itemid = strtoul(message, nullptr, 10);
|
||||
|
||||
if (itemid == 0) // Entered a string
|
||||
count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
|
||||
else {
|
||||
if ((item_array[0] = item_db.find(itemid)) == nullptr)
|
||||
count = 0;
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name.
|
||||
@@ -8219,22 +8250,23 @@ ACMD_FUNC(whodrops)
|
||||
sprintf(atcmd_output, msg_txt(sd,269), MAX_SEARCH); // Displaying first %d matches
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
item_data = item_array[i];
|
||||
sprintf(atcmd_output, msg_txt(sd,1285), item_data->ename.c_str(), item_data->slots, item_data->nameid); // Item: '%s'[%d] (ID:%u)
|
||||
for (const auto &result : item_array) {
|
||||
std::shared_ptr<item_data> id = result.second;
|
||||
|
||||
sprintf(atcmd_output, msg_txt(sd,1285), id->ename.c_str(), id->slots, id->nameid); // Item: '%s'[%d] (ID:%u)
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
|
||||
if (item_data->mob[0].chance == 0) {
|
||||
if (id->mob[0].chance == 0) {
|
||||
strcpy(atcmd_output, msg_txt(sd,1286)); // - Item is not dropped by mobs.
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
} else {
|
||||
sprintf(atcmd_output, msg_txt(sd,1287), MAX_SEARCH); // - Common mobs with highest drop chance (only max %d are listed):
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
|
||||
for (j=0; j < MAX_SEARCH && item_data->mob[j].chance > 0; j++)
|
||||
for (uint16 j=0; j < MAX_SEARCH && id->mob[j].chance > 0; j++)
|
||||
{
|
||||
int dropchance = item_data->mob[j].chance;
|
||||
std::shared_ptr<s_mob_db> mob = mob_db.find(item_data->mob[j].id);
|
||||
int dropchance = id->mob[j].chance;
|
||||
std::shared_ptr<s_mob_db> mob = mob_db.find(id->mob[j].id);
|
||||
if(!mob) continue;
|
||||
|
||||
#ifdef RENEWAL_DROP
|
||||
@@ -8246,7 +8278,7 @@ ACMD_FUNC(whodrops)
|
||||
#endif
|
||||
if (pc_isvip(sd)) // Display item rate increase for VIP
|
||||
dropchance += (dropchance * battle_config.vip_drop_increase) / 100;
|
||||
sprintf(atcmd_output, "- %s (%d): %02.02f%%", mob->jname.c_str(), item_data->mob[j].id, dropchance/100.);
|
||||
sprintf(atcmd_output, "- %s (%d): %02.02f%%", mob->jname.c_str(), id->mob[j].id, dropchance/100.);
|
||||
clif_displaymessage(fd, atcmd_output);
|
||||
}
|
||||
}
|
||||
@@ -9198,9 +9230,13 @@ ACMD_FUNC(itemlist)
|
||||
counter = 0; // total items found
|
||||
for( i = 0; i < size; ++i ) {
|
||||
const struct item* it = &items[i];
|
||||
struct item_data* itd;
|
||||
|
||||
if( it->nameid == 0 || (itd = itemdb_exists(it->nameid)) == NULL )
|
||||
if( it->nameid == 0 )
|
||||
continue;
|
||||
|
||||
std::shared_ptr<item_data> itd = item_db.find(it->nameid);
|
||||
|
||||
if (itd == nullptr)
|
||||
continue;
|
||||
|
||||
counter += it->amount;
|
||||
@@ -9302,9 +9338,12 @@ ACMD_FUNC(itemlist)
|
||||
int counter2 = 0;
|
||||
|
||||
for( j = 0; j < itd->slots; ++j ) {
|
||||
struct item_data* card;
|
||||
if( it->card[j] == 0 )
|
||||
continue;
|
||||
|
||||
if( it->card[j] == 0 || (card = itemdb_exists(it->card[j])) == NULL )
|
||||
std::shared_ptr<item_data> card = item_db.find(it->card[j]);
|
||||
|
||||
if (card == nullptr)
|
||||
continue;
|
||||
|
||||
counter2++;
|
||||
|
||||
@@ -162,11 +162,10 @@ int8 buyingstore_create( struct map_session_data* sd, int zenylimit, unsigned ch
|
||||
// check item list
|
||||
for( i = 0; i < count; i++ ){
|
||||
const struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub *item = &itemlist[i];
|
||||
|
||||
struct item_data* id = itemdb_exists( item->itemId );
|
||||
std::shared_ptr<item_data> id = item_db.find(item->itemId);
|
||||
|
||||
// invalid input
|
||||
if( id == NULL || item->amount == 0 ){
|
||||
if( id == nullptr || item->amount == 0 ){
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -176,7 +175,7 @@ int8 buyingstore_create( struct map_session_data* sd, int zenylimit, unsigned ch
|
||||
}
|
||||
|
||||
// restrictions: allowed and no character-bound items
|
||||
if( !id->flag.buyingstore || !itemdb_cantrade_sub( id, pc_get_group_level( sd ), pc_get_group_level( sd ) ) ){
|
||||
if( !id->flag.buyingstore || !itemdb_cantrade_sub( id.get(), pc_get_group_level( sd ), pc_get_group_level( sd ) ) ){
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -471,7 +471,6 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, s
|
||||
uint32 totalcash = 0;
|
||||
uint32 totalweight = 0;
|
||||
int i,new_;
|
||||
item_data *id;
|
||||
|
||||
if( sd == NULL || item_list == NULL || !cash_shop_defined){
|
||||
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_UNKNOWN );
|
||||
@@ -502,7 +501,8 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, s
|
||||
}
|
||||
|
||||
nameid = item_list[i].itemId = cash_shop_items[tab].item[j]->nameid; //item_avail replacement
|
||||
id = itemdb_exists(nameid);
|
||||
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid);
|
||||
|
||||
if( !id ){
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_UNKONWN_ITEM );
|
||||
|
||||
@@ -2193,10 +2193,10 @@ void clif_buylist( struct map_session_data *sd, struct npc_data *nd ){
|
||||
p->items[count].itemType = itemtype( nd->u.shop.shop_item[i].nameid );
|
||||
p->items[count].itemId = client_nameid( nd->u.shop.shop_item[i].nameid );
|
||||
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
|
||||
struct item_data* id = itemdb_exists( nd->u.shop.shop_item[i].nameid );
|
||||
std::shared_ptr<item_data> id = item_db.find(nd->u.shop.shop_item[i].nameid);
|
||||
|
||||
p->items[count].viewSprite = id->look;
|
||||
p->items[count].location = pc_equippoint_sub( sd, id );
|
||||
p->items[count].location = pc_equippoint_sub( sd, id.get() );
|
||||
#endif
|
||||
count++;
|
||||
}
|
||||
@@ -2279,7 +2279,7 @@ void clif_npc_market_open(struct map_session_data *sd, struct npc_data *nd) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct item_data *id = itemdb_exists( item->nameid );
|
||||
std::shared_ptr<item_data> id = item_db.find(item->nameid);
|
||||
|
||||
if( !id ){
|
||||
continue;
|
||||
@@ -2296,7 +2296,7 @@ void clif_npc_market_open(struct map_session_data *sd, struct npc_data *nd) {
|
||||
p->list[count].qty = item->qty;
|
||||
p->list[count].weight = id->weight;
|
||||
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
|
||||
p->list[count].location = pc_equippoint_sub( sd, id );
|
||||
p->list[count].location = pc_equippoint_sub( sd, id.get() );
|
||||
#endif
|
||||
count++;
|
||||
}
|
||||
@@ -16215,7 +16215,6 @@ void clif_Mail_read( struct map_session_data *sd, int mail_id ){
|
||||
} else {
|
||||
struct mail_message *msg = &sd->mail.inbox.msg[i];
|
||||
struct item *item;
|
||||
struct item_data *data;
|
||||
int msg_len = strlen(msg->body);
|
||||
|
||||
if( msg_len == 0 ) {
|
||||
@@ -16273,7 +16272,9 @@ void clif_Mail_read( struct map_session_data *sd, int mail_id ){
|
||||
for( int j = 0; j < MAIL_MAX_ITEM; j++ ){
|
||||
item = &msg->item[j];
|
||||
|
||||
if( item->nameid > 0 && item->amount > 0 && ( data = itemdb_exists( item->nameid ) ) != NULL ){
|
||||
std::shared_ptr<item_data> data = item_db.find(item->nameid);
|
||||
|
||||
if( item->nameid > 0 && item->amount > 0 && data != nullptr ){
|
||||
struct PACKET_ZC_ACK_READ_RODEX_SUB* mailitem = (struct PACKET_ZC_ACK_READ_RODEX_SUB*)WBUFP( p, p->PacketLength );
|
||||
|
||||
mailitem->ITID = client_nameid( item->nameid );
|
||||
@@ -16282,7 +16283,7 @@ void clif_Mail_read( struct map_session_data *sd, int mail_id ){
|
||||
mailitem->IsIdentified = item->identify ? 1 : 0;
|
||||
mailitem->IsDamaged = item->attribute ? 1 : 0;
|
||||
mailitem->refiningLevel = item->refine;
|
||||
mailitem->location = pc_equippoint_sub( sd, data );
|
||||
mailitem->location = pc_equippoint_sub( sd, data.get() );
|
||||
mailitem->viewSprite = data->look;
|
||||
mailitem->bindOnEquip = item->bound ? 2 : data->flag.bindOnEquip ? 1 : 0;
|
||||
clif_addcards( &mailitem->slot, item );
|
||||
@@ -16476,9 +16477,9 @@ void clif_parse_Mail_getattach( int fd, struct map_session_data *sd ){
|
||||
struct item* item = &msg->item[i];
|
||||
|
||||
if( item->nameid > 0 && item->amount > 0 ){
|
||||
struct item_data *data;
|
||||
std::shared_ptr<item_data> data = item_db.find(item->nameid);
|
||||
|
||||
if((data = itemdb_exists(item->nameid)) == NULL)
|
||||
if(data == nullptr)
|
||||
continue;
|
||||
|
||||
switch( pc_checkadditem(sd, item->nameid, item->amount) ){
|
||||
@@ -16845,7 +16846,6 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd){
|
||||
struct s_packet_db* info = &packet_db[RFIFOW(fd,0)];
|
||||
int idx = RFIFOW(fd,info->pos[0]) - 2;
|
||||
int amount = RFIFOL(fd,info->pos[1]); // Always 1
|
||||
struct item_data *item;
|
||||
|
||||
if( !battle_config.feature_auction )
|
||||
return;
|
||||
@@ -16863,7 +16863,9 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd){
|
||||
return;
|
||||
}
|
||||
|
||||
if( (item = itemdb_exists(sd->inventory.u.items_inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC || item->type == IT_SHADOWGEAR) )
|
||||
std::shared_ptr<item_data> id = item_db.find(sd->inventory.u.items_inventory[idx].nameid);
|
||||
|
||||
if( id != nullptr && !(id->type == IT_ARMOR || id->type == IT_PETARMOR || id->type == IT_WEAPON || id->type == IT_CARD || id->type == IT_ETC || id->type == IT_SHADOWGEAR) )
|
||||
{ // Consumable or pets are not allowed
|
||||
clif_Auction_setitem(sd->fd, idx, true);
|
||||
return;
|
||||
@@ -16925,7 +16927,6 @@ void clif_Auction_close(int fd, unsigned char flag)
|
||||
void clif_parse_Auction_register(int fd, struct map_session_data *sd)
|
||||
{
|
||||
struct auction_data auction;
|
||||
struct item_data *item;
|
||||
struct s_packet_db* info = &packet_db[RFIFOW(fd,0)];
|
||||
|
||||
if( !battle_config.feature_auction )
|
||||
@@ -16980,14 +16981,16 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
|
||||
return;
|
||||
}
|
||||
|
||||
if( (item = itemdb_exists(sd->inventory.u.items_inventory[sd->auction.index].nameid)) == NULL )
|
||||
std::shared_ptr<item_data> id = item_db.find(sd->inventory.u.items_inventory[sd->auction.index].nameid);
|
||||
|
||||
if( id == nullptr )
|
||||
{ // Just in case
|
||||
clif_Auction_message(fd, 2); // The auction has been canceled
|
||||
return;
|
||||
}
|
||||
|
||||
safestrncpy(auction.item_name, item->ename.c_str(), sizeof(auction.item_name));
|
||||
auction.type = item->type;
|
||||
safestrncpy(auction.item_name, id->ename.c_str(), sizeof(auction.item_name));
|
||||
auction.type = id->type;
|
||||
memcpy(&auction.item, &sd->inventory.u.items_inventory[sd->auction.index], sizeof(struct item));
|
||||
auction.item.amount = 1;
|
||||
auction.timestamp = 0;
|
||||
@@ -22788,7 +22791,7 @@ void clif_barter_open( struct map_session_data& sd, struct npc_data& nd ){
|
||||
int16 count = 0;
|
||||
for( const auto& itemPair : barter->items ){
|
||||
struct PACKET_ZC_NPC_BARTER_MARKET_ITEMINFO_sub* item = &p->list[count];
|
||||
struct item_data* id = itemdb_exists( itemPair.second->nameid );
|
||||
std::shared_ptr<item_data> id = item_db.find(itemPair.second->nameid);
|
||||
|
||||
item->nameid = client_nameid( id->nameid );
|
||||
item->type = itemtype( id->nameid );
|
||||
@@ -22801,7 +22804,7 @@ void clif_barter_open( struct map_session_data& sd, struct npc_data& nd ){
|
||||
item->index = itemPair.second->index;
|
||||
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
|
||||
item->viewSprite = id->look;
|
||||
item->location = pc_equippoint_sub( &sd, id );
|
||||
item->location = pc_equippoint_sub( &sd, id.get() );
|
||||
#endif
|
||||
|
||||
// Use a loop if someone did not start with index 0
|
||||
@@ -22938,7 +22941,7 @@ void clif_barter_extended_open( struct map_session_data& sd, struct npc_data& nd
|
||||
for( const auto& itemPair : barter->items ){
|
||||
// Needs dynamic calculation, because of variable currencies
|
||||
struct PACKET_ZC_NPC_EXPANDED_BARTER_MARKET_ITEMINFO_sub* item = (struct PACKET_ZC_NPC_EXPANDED_BARTER_MARKET_ITEMINFO_sub*)( ( (uint8*)p ) + p->packetLength );
|
||||
struct item_data* id = itemdb_exists( itemPair.second->nameid );
|
||||
std::shared_ptr<item_data> id = item_db.find(itemPair.second->nameid);
|
||||
|
||||
item->nameid = client_nameid( id->nameid );
|
||||
item->type = itemtype( id->nameid );
|
||||
@@ -22952,7 +22955,7 @@ void clif_barter_extended_open( struct map_session_data& sd, struct npc_data& nd
|
||||
item->zeny = itemPair.second->price;
|
||||
#if PACKETVER_MAIN_NUM >= 20210203 || PACKETVER_RE_NUM >= 20211103
|
||||
item->viewSprite = id->look;
|
||||
item->location = pc_equippoint_sub( &sd, id );
|
||||
item->location = pc_equippoint_sub( &sd, id.get() );
|
||||
#endif
|
||||
|
||||
p->packetLength += (int16)( sizeof( *item ) - sizeof( item->currencies ) );
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "itemdb.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../common/nullpo.hpp"
|
||||
@@ -1670,22 +1669,21 @@ LaphineUpgradeDatabase laphine_upgrade_db;
|
||||
* @param str
|
||||
* @return Number of matches item
|
||||
*------------------------------------------*/
|
||||
uint16 itemdb_searchname_array(struct item_data** data, uint16 size, const char *str)
|
||||
uint16 itemdb_searchname_array(std::map<t_itemid, std::shared_ptr<item_data>> &data, uint16 size, const char *str)
|
||||
{
|
||||
uint16 count = 0;
|
||||
const auto &item_list = item_db.getCache();
|
||||
for (const auto &item : item_db) {
|
||||
std::shared_ptr<item_data> id = item.second;
|
||||
|
||||
for (const auto &item : item_list) {
|
||||
if (item == nullptr)
|
||||
if (id == nullptr)
|
||||
continue;
|
||||
if (count < size) {
|
||||
if (stristr(item->name.c_str(), str) != nullptr || stristr(item->ename.c_str(), str) != nullptr || strcmpi(item->ename.c_str(), str) == 0)
|
||||
data[count++] = item.get();
|
||||
} else
|
||||
break;
|
||||
if (stristr(id->name.c_str(), str) != nullptr || stristr(id->ename.c_str(), str) != nullptr || strcmpi(id->ename.c_str(), str) == 0)
|
||||
data[id->nameid] = id;
|
||||
}
|
||||
|
||||
return count;
|
||||
if (data.size() > size)
|
||||
util::map_resize(data, size);
|
||||
|
||||
return static_cast<uint16>(data.size());
|
||||
}
|
||||
|
||||
std::shared_ptr<s_item_group_entry> get_random_itemsubgroup(std::shared_ptr<s_item_group_random> random) {
|
||||
@@ -1844,10 +1842,8 @@ uint8 ItemGroupDatabase::pc_get_itemgroup(uint16 group_id, bool identify, map_se
|
||||
* @param nameid
|
||||
* @return *item_data if item is exist, or NULL if not
|
||||
*/
|
||||
struct item_data* itemdb_exists(t_itemid nameid) {
|
||||
std::shared_ptr<item_data> item = item_db.find(nameid);
|
||||
|
||||
return item ? item.get() : nullptr;
|
||||
std::shared_ptr<item_data> itemdb_exists(t_itemid nameid) {
|
||||
return item_db.find(nameid);
|
||||
}
|
||||
|
||||
/// Returns name type of ammunition [Cydh]
|
||||
@@ -2366,12 +2362,13 @@ void ItemGroupDatabase::loadingFinished() {
|
||||
static bool itemdb_read_noequip(char* str[], int columns, int current) {
|
||||
t_itemid nameid;
|
||||
int flag;
|
||||
struct item_data *id;
|
||||
|
||||
nameid = strtoul(str[0], nullptr, 10);
|
||||
flag = atoi(str[1]);
|
||||
|
||||
if( ( id = itemdb_exists(nameid) ) == NULL )
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid);
|
||||
|
||||
if( id == nullptr )
|
||||
{
|
||||
ShowWarning("itemdb_read_noequip: Invalid item id %u.\n", nameid);
|
||||
return false;
|
||||
@@ -2530,8 +2527,10 @@ void ComboDatabase::loadingFinished() {
|
||||
// Populate item_data to refer to the combo
|
||||
for (const auto &combo : *this) {
|
||||
for (const auto &itm : combo.second->nameid) {
|
||||
item_data *it = itemdb_exists(itm);
|
||||
it->combos.push_back(combo.second);
|
||||
std::shared_ptr<item_data> it = item_db.find(itm);
|
||||
|
||||
if (it != nullptr)
|
||||
it->combos.push_back(combo.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1385,9 +1385,9 @@ public:
|
||||
|
||||
extern LaphineUpgradeDatabase laphine_upgrade_db;
|
||||
|
||||
uint16 itemdb_searchname_array(struct item_data** data, uint16 size, const char *str);
|
||||
uint16 itemdb_searchname_array(std::map<t_itemid, std::shared_ptr<item_data>> &data, uint16 size, const char *str);
|
||||
struct item_data* itemdb_search(t_itemid nameid);
|
||||
struct item_data* itemdb_exists(t_itemid nameid);
|
||||
std::shared_ptr<item_data> itemdb_exists(t_itemid nameid);
|
||||
#define itemdb_name(n) itemdb_search(n)->name.c_str()
|
||||
#define itemdb_ename(n) itemdb_search(n)->ename.c_str()
|
||||
#define itemdb_type(n) itemdb_search(n)->type
|
||||
|
||||
@@ -144,9 +144,9 @@ static char log_feedingtype2char(e_log_feeding_type type) {
|
||||
static bool should_log_item(t_itemid nameid, int amount, int refine)
|
||||
{
|
||||
int filter = log_config.filter;
|
||||
struct item_data* id;
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid);
|
||||
|
||||
if( ( id = itemdb_exists(nameid) ) == NULL )
|
||||
if( id == nullptr )
|
||||
return false;
|
||||
|
||||
if( ( filter&LOG_FILTER_ALL ) ||
|
||||
|
||||
@@ -313,7 +313,7 @@ std::shared_ptr<s_mob_db> mobdb_search_aegisname( const char* str ){
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Founds up to N matches. Returns number of matches [Skotlex]
|
||||
* Searches up to N matches. Returns number of matches [Skotlex]
|
||||
*------------------------------------------*/
|
||||
uint16 mobdb_searchname_array_(const char *str, uint16 * out, uint16 size, bool full_cmp)
|
||||
{
|
||||
@@ -2787,7 +2787,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
{ // Item Drop
|
||||
struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
|
||||
struct item_drop *ditem;
|
||||
struct item_data* it = NULL;
|
||||
int drop_rate, drop_modifier = 100;
|
||||
|
||||
#ifdef RENEWAL_DROP
|
||||
@@ -2804,7 +2803,10 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
for (i = 0; i < MAX_MOB_DROP_TOTAL; i++) {
|
||||
if (md->db->dropitem[i].nameid == 0)
|
||||
continue;
|
||||
if ( !(it = itemdb_exists(md->db->dropitem[i].nameid)) )
|
||||
|
||||
std::shared_ptr<item_data> it = item_db.find(md->db->dropitem[i].nameid);
|
||||
|
||||
if ( it == nullptr )
|
||||
continue;
|
||||
|
||||
drop_rate = mob_getdroprate(src, md->db, md->db->dropitem[i].rate, drop_modifier);
|
||||
@@ -2966,9 +2968,12 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
#endif
|
||||
|
||||
for(i = 0; i < MAX_MVP_DROP_TOTAL; i++) {
|
||||
struct item_data *i_data;
|
||||
if(mdrop[i].nameid == 0)
|
||||
continue;
|
||||
|
||||
if(mdrop[i].nameid == 0 || !(i_data = itemdb_exists(mdrop[i].nameid)))
|
||||
std::shared_ptr<item_data> i_data = item_db.find(mdrop[i].nameid);
|
||||
|
||||
if (i_data == nullptr)
|
||||
continue;
|
||||
|
||||
temp = mdrop[i].rate;
|
||||
|
||||
@@ -2343,7 +2343,7 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
||||
break;
|
||||
case NPCTYPE_ITEMSHOP:
|
||||
{
|
||||
struct item_data *id = itemdb_exists(nd->u.shop.itemshop_nameid);
|
||||
std::shared_ptr<item_data> id = item_db.find(nd->u.shop.itemshop_nameid);
|
||||
int delete_amount = price, i;
|
||||
|
||||
if (!id) { // Item Data is checked at script parsing but in case of item_db reload, check again.
|
||||
@@ -2418,7 +2418,6 @@ int npc_cashshop_buylist( struct map_session_data *sd, int points, std::vector<s
|
||||
t_itemid nameid;
|
||||
struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
|
||||
enum e_CASHSHOP_ACK res;
|
||||
item_data *id;
|
||||
|
||||
if( !nd || ( nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) )
|
||||
return ERROR_TYPE_NPC;
|
||||
@@ -2434,7 +2433,8 @@ int npc_cashshop_buylist( struct map_session_data *sd, int points, std::vector<s
|
||||
{
|
||||
nameid = item_list[i].nameid;
|
||||
amount = item_list[i].qty;
|
||||
id = itemdb_exists(nameid);
|
||||
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid);
|
||||
|
||||
if( !id || amount <= 0 )
|
||||
return ERROR_TYPE_ITEM_ID;
|
||||
@@ -2445,7 +2445,7 @@ int npc_cashshop_buylist( struct map_session_data *sd, int points, std::vector<s
|
||||
|
||||
nameid = item_list[i].nameid = nd->u.shop.shop_item[j].nameid; //item_avail replacement
|
||||
|
||||
if( !itemdb_isstackable2(id) && amount > 1 )
|
||||
if( !itemdb_isstackable2(id.get()) && amount > 1 )
|
||||
{
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %u!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
||||
amount = item_list[i].qty = 1;
|
||||
@@ -2529,7 +2529,7 @@ void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, in
|
||||
case NPCTYPE_ITEMSHOP:
|
||||
{
|
||||
int total = 0, i;
|
||||
struct item_data *id = itemdb_exists(nd->u.shop.itemshop_nameid);
|
||||
std::shared_ptr<item_data> id = item_db.find(nd->u.shop.itemshop_nameid);
|
||||
|
||||
if (id) { // Item Data is checked at script parsing but in case of item_db reload, check again.
|
||||
if (display) {
|
||||
@@ -2576,7 +2576,6 @@ void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, in
|
||||
int npc_cashshop_buy(struct map_session_data *sd, t_itemid nameid, int amount, int points)
|
||||
{
|
||||
struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
|
||||
struct item_data *item;
|
||||
int i, price, w;
|
||||
enum e_CASHSHOP_ACK res;
|
||||
|
||||
@@ -2592,7 +2591,9 @@ int npc_cashshop_buy(struct map_session_data *sd, t_itemid nameid, int amount, i
|
||||
if( sd->state.trading )
|
||||
return ERROR_TYPE_EXCHANGE;
|
||||
|
||||
if( (item = itemdb_exists(nameid)) == NULL )
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid);
|
||||
|
||||
if( id == nullptr )
|
||||
return ERROR_TYPE_ITEM_ID; // Invalid Item
|
||||
|
||||
ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid || itemdb_viewid(nd->u.shop.shop_item[i].nameid) == nameid);
|
||||
@@ -2603,7 +2604,7 @@ int npc_cashshop_buy(struct map_session_data *sd, t_itemid nameid, int amount, i
|
||||
|
||||
nameid = nd->u.shop.shop_item[i].nameid; //item_avail replacement
|
||||
|
||||
if(!itemdb_isstackable2(item) && amount > 1)
|
||||
if(!itemdb_isstackable2(id.get()) && amount > 1)
|
||||
{
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %u!\n",
|
||||
sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
||||
@@ -2613,20 +2614,20 @@ int npc_cashshop_buy(struct map_session_data *sd, t_itemid nameid, int amount, i
|
||||
switch( pc_checkadditem(sd, nameid, amount) )
|
||||
{
|
||||
case CHKADDITEM_NEW:
|
||||
if( pc_inventoryblank(sd) < item->inventorySlotNeeded(amount) )
|
||||
if( pc_inventoryblank(sd) < id->inventorySlotNeeded(amount) )
|
||||
return ERROR_TYPE_INVENTORY_WEIGHT;
|
||||
break;
|
||||
case CHKADDITEM_OVERAMOUNT:
|
||||
return ERROR_TYPE_INVENTORY_WEIGHT;
|
||||
}
|
||||
|
||||
w = item->weight * amount;
|
||||
w = id->weight * amount;
|
||||
if( w + sd->weight > sd->max_weight )
|
||||
return ERROR_TYPE_INVENTORY_WEIGHT;
|
||||
|
||||
if( (double)nd->u.shop.shop_item[i].value * amount > INT_MAX )
|
||||
{
|
||||
ShowWarning("npc_cashshop_buy: Item '%s' (%u) price overflow attempt!\n", item->name.c_str(), nameid);
|
||||
ShowWarning("npc_cashshop_buy: Item '%s' (%u) price overflow attempt!\n", id->name.c_str(), nameid);
|
||||
ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n",
|
||||
nd->exname, map_mapid2mapname(nd->bl.m), nd->bl.x, nd->bl.y, sd->status.name, sd->status.account_id, sd->status.char_id, nd->u.shop.shop_item[i].value, amount);
|
||||
return ERROR_TYPE_ITEM_ID;
|
||||
@@ -2647,7 +2648,7 @@ int npc_cashshop_buy(struct map_session_data *sd, t_itemid nameid, int amount, i
|
||||
item_tmp.nameid = nameid;
|
||||
item_tmp.identify = 1;
|
||||
|
||||
if (item->flag.guid)
|
||||
if (id->flag.guid)
|
||||
get_amt = 1;
|
||||
|
||||
for (int j = 0; j < amount; j += get_amt)
|
||||
@@ -2722,7 +2723,6 @@ e_purchase_result npc_buylist( struct map_session_data* sd, std::vector<s_npc_bu
|
||||
t_itemid nameid;
|
||||
unsigned short amount;
|
||||
int value;
|
||||
item_data *id;
|
||||
|
||||
// find this entry in the shop's sell list
|
||||
ARR_FIND( 0, nd->u.shop.count, j,
|
||||
@@ -2744,12 +2744,13 @@ e_purchase_result npc_buylist( struct map_session_data* sd, std::vector<s_npc_bu
|
||||
amount = item_list[i].qty;
|
||||
nameid = item_list[i].nameid = shop[j].nameid; //item_avail replacement
|
||||
value = shop[j].value;
|
||||
id = itemdb_exists(nameid);
|
||||
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid);
|
||||
|
||||
if( !id )
|
||||
return e_purchase_result::PURCHASE_FAIL_COUNT; // item no longer in itemdb
|
||||
|
||||
if( !itemdb_isstackable2(id) && amount > 1 ) { //Exploit? You can't buy more than 1 of equipment types o.O
|
||||
if( !itemdb_isstackable2(id.get()) && amount > 1 ) { //Exploit? You can't buy more than 1 of equipment types o.O
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %u!\n",
|
||||
sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
||||
amount = item_list[i].qty = 1;
|
||||
@@ -3046,7 +3047,7 @@ e_purchase_result npc_barter_purchase( struct map_session_data& sd, std::shared_
|
||||
uint32 requiredItems[MAX_INVENTORY] = { 0 };
|
||||
|
||||
for( s_barter_purchase& purchase : purchases ){
|
||||
purchase.data = itemdb_exists( purchase.item->nameid );
|
||||
purchase.data = item_db.find( purchase.item->nameid ).get();
|
||||
|
||||
if( purchase.data == nullptr ){
|
||||
return e_purchase_result::PURCHASE_FAIL_EXCHANGE_FAILED;
|
||||
@@ -3071,14 +3072,13 @@ e_purchase_result npc_barter_purchase( struct map_session_data& sd, std::shared_
|
||||
|
||||
for( const auto& requirementPair : purchase.item->requirements ){
|
||||
std::shared_ptr<s_npc_barter_requirement> requirement = requirementPair.second;
|
||||
|
||||
item_data* id = itemdb_exists( requirement->nameid );
|
||||
std::shared_ptr<item_data> id = item_db.find(requirement->nameid);
|
||||
|
||||
if( id == nullptr ){
|
||||
return e_purchase_result::PURCHASE_FAIL_EXCHANGE_FAILED;
|
||||
}
|
||||
|
||||
if( itemdb_isstackable2( id ) ){
|
||||
if( itemdb_isstackable2( id.get() ) ){
|
||||
int j;
|
||||
|
||||
for( j = 0; j < MAX_INVENTORY; j++ ){
|
||||
@@ -3985,7 +3985,6 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
t_itemid nameid2;
|
||||
int32 qty = -1;
|
||||
int value;
|
||||
struct item_data* id;
|
||||
bool skip = false;
|
||||
|
||||
if( p == NULL )
|
||||
@@ -4010,7 +4009,9 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
if (skip)
|
||||
break;
|
||||
|
||||
if( (id = itemdb_exists(nameid2)) == NULL ) {
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid2);
|
||||
|
||||
if( id == nullptr ) {
|
||||
ShowWarning("npc_parse_shop: Invalid sell item in file '%s', line '%d' (id '%u').\n", filepath, strline(buffer,start-buffer), nameid2);
|
||||
p = strchr(p+1,',');
|
||||
continue;
|
||||
|
||||
@@ -6138,17 +6138,17 @@ int pc_show_steal(struct block_list *bl,va_list ap)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
t_itemid itemid;
|
||||
|
||||
struct item_data *item=NULL;
|
||||
char output[100];
|
||||
|
||||
sd=va_arg(ap,struct map_session_data *);
|
||||
itemid=va_arg(ap,int);
|
||||
|
||||
if((item=itemdb_exists(itemid))==NULL)
|
||||
std::shared_ptr<item_data> id = item_db.find(itemid);
|
||||
|
||||
if(id == nullptr)
|
||||
sprintf(output,"%s stole an Unknown Item (id: %u).",sd->status.name, itemid);
|
||||
else
|
||||
sprintf(output,"%s stole %s.",sd->status.name,item->ename.c_str());
|
||||
sprintf(output,"%s stole %s.",sd->status.name,id->ename.c_str());
|
||||
clif_displaymessage( ((struct map_session_data *)bl)->fd, output);
|
||||
|
||||
return 0;
|
||||
@@ -11314,15 +11314,15 @@ int pc_load_combo(struct map_session_data *sd) {
|
||||
ret += pc_checkcombo(sd, id);
|
||||
|
||||
if (!itemdb_isspecial(sd->inventory.u.items_inventory[idx].card[0])) {
|
||||
item_data *data;
|
||||
|
||||
for (uint8 j = 0; j < MAX_SLOTS; j++) {
|
||||
if (!sd->inventory.u.items_inventory[idx].card[j])
|
||||
continue;
|
||||
|
||||
if ((data = itemdb_exists(sd->inventory.u.items_inventory[idx].card[j])) != nullptr) {
|
||||
std::shared_ptr<item_data> data = item_db.find(sd->inventory.u.items_inventory[idx].card[j]);
|
||||
|
||||
if (data != nullptr) {
|
||||
if (!data->combos.empty())
|
||||
ret += pc_checkcombo(sd, data);
|
||||
ret += pc_checkcombo(sd, data.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11415,7 +11415,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
|
||||
struct item_data *card_data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i]);
|
||||
std::shared_ptr<item_data> card_data = item_db.find(sd->inventory.u.items_inventory[n].card[i]);
|
||||
|
||||
if (card_data) {
|
||||
int card_pos = card_data->equip;
|
||||
@@ -11560,13 +11560,14 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
|
||||
; // No cards
|
||||
else {
|
||||
for (i = 0; i < MAX_SLOTS; i++) {
|
||||
item_data *data;
|
||||
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
if ((data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i])) != nullptr) {
|
||||
|
||||
std::shared_ptr<item_data> data = item_db.find(sd->inventory.u.items_inventory[n].card[i]);
|
||||
|
||||
if (data != nullptr) {
|
||||
if (!data->combos.empty())
|
||||
pc_checkcombo(sd, data);
|
||||
pc_checkcombo(sd, data.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11584,11 +11585,13 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit
|
||||
; //No cards
|
||||
else {
|
||||
for( i = 0; i < MAX_SLOTS; i++ ) {
|
||||
struct item_data *data;
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
if ( ( data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i]) ) != NULL ) {
|
||||
if (data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data,sd->bl.m)))
|
||||
|
||||
std::shared_ptr<item_data> data = item_db.find(sd->inventory.u.items_inventory[n].card[i]);
|
||||
|
||||
if ( data != nullptr ) {
|
||||
if (data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data.get(), sd->bl.m)))
|
||||
run_script(data->equip_script,0,sd->bl.id,fake_nd->bl.id);
|
||||
}
|
||||
}
|
||||
@@ -11645,13 +11648,14 @@ static void pc_unequipitem_sub(struct map_session_data *sd, int n, int flag) {
|
||||
; // No cards
|
||||
else {
|
||||
for (i = 0; i < MAX_SLOTS; i++) {
|
||||
item_data *data;
|
||||
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
if ((data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i])) != nullptr) {
|
||||
|
||||
std::shared_ptr<item_data> data = item_db.find(sd->inventory.u.items_inventory[n].card[i]);
|
||||
|
||||
if (data != nullptr) {
|
||||
if (!data->combos.empty()) {
|
||||
if (pc_removecombo(sd, data))
|
||||
if (pc_removecombo(sd, data.get()))
|
||||
status_calc = true;
|
||||
}
|
||||
}
|
||||
@@ -11675,11 +11679,12 @@ static void pc_unequipitem_sub(struct map_session_data *sd, int n, int flag) {
|
||||
; //No cards
|
||||
else {
|
||||
for (i = 0; i < MAX_SLOTS; i++) {
|
||||
struct item_data *data;
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
|
||||
if ((data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i])) != NULL) {
|
||||
std::shared_ptr<item_data> data = item_db.find(sd->inventory.u.items_inventory[n].card[i]);
|
||||
|
||||
if (data != nullptr) {
|
||||
if (data->unequip_script)
|
||||
run_script(data->unequip_script, 0, sd->bl.id, fake_nd->bl.id);
|
||||
}
|
||||
|
||||
@@ -14215,13 +14215,10 @@ BUILDIN_FUNC(getitemname)
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(getitemslots)
|
||||
{
|
||||
struct item_data *i_data;
|
||||
|
||||
t_itemid item_id=script_getnum(st,2);
|
||||
std::shared_ptr<item_data> i_data = item_db.find(item_id);
|
||||
|
||||
i_data = itemdb_exists(item_id);
|
||||
|
||||
if (i_data)
|
||||
if (i_data != nullptr)
|
||||
script_pushint(st,i_data->slots);
|
||||
else
|
||||
script_pushint(st,-1);
|
||||
@@ -16311,18 +16308,19 @@ BUILDIN_FUNC(unequip) {
|
||||
**/
|
||||
BUILDIN_FUNC(equip) {
|
||||
TBL_PC *sd;
|
||||
struct item_data *item_data;
|
||||
|
||||
if (!script_charid2sd(3,sd))
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
t_itemid nameid = script_getnum(st,2);
|
||||
if ((item_data = itemdb_exists(nameid))) {
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid);
|
||||
|
||||
if (id == nullptr) {
|
||||
int i;
|
||||
|
||||
ARR_FIND( 0, MAX_INVENTORY, i, sd->inventory.u.items_inventory[i].nameid == nameid );
|
||||
if (i < MAX_INVENTORY) {
|
||||
pc_equipitem(sd,i,item_data->equip);
|
||||
pc_equipitem(sd,i,id->equip);
|
||||
script_pushint(st,1);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
@@ -16335,24 +16333,23 @@ BUILDIN_FUNC(equip) {
|
||||
|
||||
BUILDIN_FUNC(autoequip)
|
||||
{
|
||||
int flag;
|
||||
struct item_data *item_data;
|
||||
t_itemid nameid=script_getnum(st,2);
|
||||
flag=script_getnum(st,3);
|
||||
int flag=script_getnum(st,3);
|
||||
std::shared_ptr<item_data> id = item_db.find(nameid);
|
||||
|
||||
if( ( item_data = itemdb_exists(nameid) ) == NULL )
|
||||
if( id == nullptr )
|
||||
{
|
||||
ShowError("buildin_autoequip: Invalid item '%u'.\n", nameid);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
if( !itemdb_isequip2(item_data) )
|
||||
if( !itemdb_isequip2(id.get()) )
|
||||
{
|
||||
ShowError("buildin_autoequip: Item '%u' cannot be equipped.\n", nameid);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
item_data->flag.autoequip = flag>0?1:0;
|
||||
id->flag.autoequip = flag>0?1:0;
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -17784,14 +17781,14 @@ BUILDIN_FUNC(setitemscript)
|
||||
{
|
||||
int n = 0;
|
||||
const char *script;
|
||||
struct item_data *i_data;
|
||||
struct script_code **dstscript;
|
||||
|
||||
t_itemid item_id = script_getnum(st,2);
|
||||
script = script_getstr(st,3);
|
||||
if( script_hasdata(st,4) )
|
||||
n=script_getnum(st,4);
|
||||
i_data = itemdb_exists(item_id);
|
||||
|
||||
std::shared_ptr<item_data> i_data = item_db.find(item_id);
|
||||
|
||||
if (!i_data || script==NULL || ( script[0] && script[0]!='{' )) {
|
||||
script_pushint(st,0);
|
||||
@@ -17845,7 +17842,7 @@ BUILDIN_FUNC(addmonsterdrop)
|
||||
}
|
||||
|
||||
t_itemid item_id = script_getnum(st, 3);
|
||||
item_data *itm = itemdb_exists(item_id);
|
||||
std::shared_ptr<item_data> itm = item_db.find(item_id);
|
||||
|
||||
if (itm == nullptr) {
|
||||
ShowError("addmonsterdrop: Nonexistant item %u requested.\n", item_id);
|
||||
@@ -18085,7 +18082,7 @@ BUILDIN_FUNC(searchitem)
|
||||
{
|
||||
struct script_data* data = script_getdata(st, 2);
|
||||
const char *itemname = script_getstr(st,3);
|
||||
struct item_data *items[MAX_SEARCH];
|
||||
std::map<t_itemid, std::shared_ptr<item_data>> items;
|
||||
int count;
|
||||
|
||||
char* name;
|
||||
@@ -18094,10 +18091,10 @@ BUILDIN_FUNC(searchitem)
|
||||
int32 i;
|
||||
TBL_PC* sd = NULL;
|
||||
|
||||
if ((items[0] = itemdb_exists(atoi(itemname))))
|
||||
if ((items[0] = item_db.find(strtoul(itemname, nullptr, 10))))
|
||||
count = 1;
|
||||
else
|
||||
count = itemdb_searchname_array(items, ARRAYLENGTH(items), itemname);
|
||||
count = itemdb_searchname_array(items, MAX_SEARCH, itemname);
|
||||
|
||||
if (!count) {
|
||||
script_pushint(st, 0);
|
||||
@@ -25208,15 +25205,15 @@ BUILDIN_FUNC(mail){
|
||||
}
|
||||
|
||||
for( i = 0; i < num_items && start < end; i++, start++ ){
|
||||
struct item_data *item = itemdb_exists(msg.item[i].nameid);
|
||||
std::shared_ptr<item_data> itm = item_db.find(msg.item[i].nameid);
|
||||
|
||||
msg.item[i].amount = (short)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) );
|
||||
|
||||
if( msg.item[i].amount <= 0 ){
|
||||
ShowError( "buildin_mail: amount %d for item %u is invalid.\n", msg.item[i].amount, msg.item[i].nameid );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}else if( itemdb_isstackable2(item) ){
|
||||
uint16 max = item->stack.amount > 0 ? item->stack.amount : MAX_AMOUNT;
|
||||
}else if( itemdb_isstackable2(itm.get()) ){
|
||||
uint16 max = itm->stack.amount > 0 ? itm->stack.amount : MAX_AMOUNT;
|
||||
|
||||
if( msg.item[i].amount > max ){
|
||||
ShowWarning( "buildin_mail: amount %d for item %u is exceeding the maximum of %d. Capping...\n", msg.item[i].amount, msg.item[i].nameid, max );
|
||||
@@ -25242,11 +25239,11 @@ BUILDIN_FUNC(mail){
|
||||
}
|
||||
|
||||
for (i = 0; i < num_items && start < end; i++, start++) {
|
||||
struct item_data* item = itemdb_exists(msg.item[i].nameid);
|
||||
std::shared_ptr<item_data> itm = item_db.find(msg.item[i].nameid);
|
||||
|
||||
msg.item[i].refine = (char)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) );
|
||||
|
||||
if (!item->flag.no_refine && (item->type == IT_WEAPON || item->type == IT_ARMOR || item->type == IT_SHADOWGEAR)) {
|
||||
if (!itm->flag.no_refine && (itm->type == IT_WEAPON || itm->type == IT_ARMOR || itm->type == IT_SHADOWGEAR)) {
|
||||
if (msg.item[i].refine > MAX_REFINE)
|
||||
msg.item[i].refine = MAX_REFINE;
|
||||
}
|
||||
@@ -25268,8 +25265,6 @@ BUILDIN_FUNC(mail){
|
||||
}
|
||||
|
||||
for( i = 0; i < num_items && start < end; i++, start++ ){
|
||||
struct item_data *item = itemdb_exists(msg.item[i].nameid);
|
||||
|
||||
msg.item[i].bound = (char)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) );
|
||||
|
||||
if( msg.item[i].bound < BOUND_NONE || msg.item[i].bound >= BOUND_MAX ){
|
||||
|
||||
@@ -24051,7 +24051,7 @@ void SkillDatabase::loadingFinished(){
|
||||
ShowError( "There are more skills defined in the skill database (%d) than the MAX_SKILL (%d) define. Please increase it and recompile.\n", this->skill_num, MAX_SKILL );
|
||||
}
|
||||
|
||||
TypesafeYamlDatabase::loadingFinished();
|
||||
TypesafeCachedYamlDatabase::loadingFinished();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3790,10 +3790,10 @@ int status_calc_pc_sub(struct map_session_data* sd, uint8 opt)
|
||||
|
||||
// Check combo items
|
||||
while (j < item_combo->nameid.size()) {
|
||||
item_data *id = itemdb_exists(item_combo->nameid[j]);
|
||||
std::shared_ptr<item_data> id = item_db.find(item_combo->nameid[j]);
|
||||
|
||||
// Don't run the script if at least one of combo's pair has restriction
|
||||
if (id && !pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(id, sd->bl.m)) {
|
||||
if (id && !pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(id.get(), sd->bl.m)) {
|
||||
no_run = true;
|
||||
break;
|
||||
}
|
||||
@@ -3830,7 +3830,6 @@ int status_calc_pc_sub(struct map_session_data* sd, uint8 opt)
|
||||
|
||||
if (sd->inventory_data[index]) {
|
||||
int j;
|
||||
struct item_data *data;
|
||||
|
||||
// Card script execution.
|
||||
if (itemdb_isspecial(sd->inventory.u.items_inventory[index].card[0]))
|
||||
@@ -3840,17 +3839,19 @@ int status_calc_pc_sub(struct map_session_data* sd, uint8 opt)
|
||||
current_equip_card_id= c;
|
||||
if(!c)
|
||||
continue;
|
||||
data = itemdb_exists(c);
|
||||
|
||||
std::shared_ptr<item_data> data = item_db.find(c);
|
||||
|
||||
if(!data)
|
||||
continue;
|
||||
if (opt&SCO_FIRST && data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data,sd->bl.m))) {// Execute equip-script on login
|
||||
if (opt&SCO_FIRST && data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data.get(), sd->bl.m))) {// Execute equip-script on login
|
||||
run_script(data->equip_script,0,sd->bl.id,0);
|
||||
if (!calculating)
|
||||
return 1;
|
||||
}
|
||||
if(!data->script)
|
||||
continue;
|
||||
if(!pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(data,sd->bl.m)) // Card restriction checks.
|
||||
if(!pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(data.get(), sd->bl.m)) // Card restriction checks.
|
||||
continue;
|
||||
if(i == EQI_HAND_L && sd->inventory.u.items_inventory[index].equip == EQP_HAND_L) { // Left hand status.
|
||||
sd->state.lr_flag = 1;
|
||||
@@ -3907,7 +3908,8 @@ int status_calc_pc_sub(struct map_session_data* sd, uint8 opt)
|
||||
}
|
||||
|
||||
if (sc->count && sc->data[SC_ITEMSCRIPT]) {
|
||||
struct item_data *data = itemdb_exists(sc->data[SC_ITEMSCRIPT]->val1);
|
||||
std::shared_ptr<item_data> data = item_db.find(sc->data[SC_ITEMSCRIPT]->val1);
|
||||
|
||||
if (data && data->script)
|
||||
run_script(data->script, 0, sd->bl.id, 0);
|
||||
}
|
||||
@@ -15555,7 +15557,7 @@ void StatusDatabase::loadingFinished(){
|
||||
}
|
||||
}
|
||||
|
||||
TypesafeYamlDatabase::loadingFinished();
|
||||
TypesafeCachedYamlDatabase::loadingFinished();
|
||||
}
|
||||
|
||||
StatusDatabase status_db;
|
||||
|
||||
@@ -794,19 +794,20 @@ bool storage_guild_additem(struct map_session_data* sd, struct s_storage* stor,
|
||||
* @return True : success, False : fail
|
||||
*/
|
||||
bool storage_guild_additem2(struct s_storage* stor, struct item* item, int amount) {
|
||||
struct item_data *id;
|
||||
int i;
|
||||
|
||||
nullpo_ret(stor);
|
||||
nullpo_ret(item);
|
||||
|
||||
if (item->nameid == 0 || amount <= 0 || !(id = itemdb_exists(item->nameid)))
|
||||
if (item->nameid == 0 || amount <= 0)
|
||||
return false;
|
||||
|
||||
if (item->expire_time)
|
||||
std::shared_ptr<item_data> id = item_db.find(item->nameid);
|
||||
|
||||
if (id == nullptr || item->expire_time)
|
||||
return false;
|
||||
|
||||
if (itemdb_isstackable2(id)) { // Stackable
|
||||
if (itemdb_isstackable2(id.get())) { // Stackable
|
||||
for (i = 0; i < stor->max_amount; i++) {
|
||||
if (compare_item(&stor->u.items_guild[i], item)) {
|
||||
// Set the amount, make it fit with max amount
|
||||
|
||||
Reference in New Issue
Block a user