summaryrefslogtreecommitdiff
path: root/src/map/npc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/npc.c')
-rw-r--r--src/map/npc.c153
1 files changed, 78 insertions, 75 deletions
diff --git a/src/map/npc.c b/src/map/npc.c
index 6ba088a80..7a3fa9c3f 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2715,43 +2715,47 @@ static int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_l
char card_slot[NAME_LENGTH];
char opt_index_str[NAME_LENGTH];
char opt_value_str[NAME_LENGTH];
- int i, j;
+ char opt_param_str[NAME_LENGTH];
+ int i = 0;
+ int j = 0;
int key_nameid = 0;
int key_amount = 0;
int key_refine = 0;
- int key_attribute = 0;
+ int key_attribute = ATTR_NONE;
int key_identify = 0;
int key_card[MAX_SLOTS];
int key_opt_idx[MAX_ITEM_OPTIONS];
int key_opt_value[MAX_ITEM_OPTIONS];
+ int key_opt_param[MAX_ITEM_OPTIONS];
nullpo_ret(sd);
nullpo_ret(item_list);
nullpo_ret(nd);
// discard old contents
- script->cleararray_pc(sd, "@sold_nameid", (void*)0);
- script->cleararray_pc(sd, "@sold_quantity", (void*)0);
- script->cleararray_pc(sd, "@sold_refine", (void*)0);
- script->cleararray_pc(sd, "@sold_attribute", (void*)0);
- script->cleararray_pc(sd, "@sold_identify", (void*)0);
-
- for( j = 0; j < MAX_SLOTS; j++ )
- {// clear each of the card slot entries
+ script->cleararray_pc(sd, "@sold_nameid", (void *)0);
+ script->cleararray_pc(sd, "@sold_quantity", (void *)0);
+ script->cleararray_pc(sd, "@sold_refine", (void *)0);
+ script->cleararray_pc(sd, "@sold_attribute", (void *)0);
+ script->cleararray_pc(sd, "@sold_identify", (void *)0);
+
+ for (j = 0; j < MAX_SLOTS; j++) { // clear each of the card slot entries
key_card[j] = 0;
snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
- script->cleararray_pc(sd, card_slot, (void*)0);
+ script->cleararray_pc(sd, card_slot, (void *)0);
}
for (j = 0; j < MAX_ITEM_OPTIONS; j++) { // Clear Each item option entry
key_opt_idx[j] = 0;
key_opt_value[j] = 0;
+ key_opt_param[j] = 0;
- snprintf(opt_index_str, sizeof(opt_index_str), "@slot_opt_idx%d", j + 1);
- script->cleararray_pc(sd, opt_index_str, (void*)0);
-
- snprintf(opt_value_str, sizeof(opt_value_str), "@slot_opt_val%d", j + 1);
- script->cleararray_pc(sd, opt_value_str, (void*)0);
+ snprintf(opt_index_str, sizeof(opt_index_str), "@sold_opt_idx%d", j + 1);
+ script->cleararray_pc(sd, opt_index_str, (void *)0);
+ snprintf(opt_value_str, sizeof(opt_value_str), "@sold_opt_val%d", j + 1);
+ script->cleararray_pc(sd, opt_value_str, (void *)0);
+ snprintf(opt_param_str, sizeof(opt_param_str), "@sold_opt_param%d", j + 1);
+ script->cleararray_pc(sd, opt_param_str, (void *)0);
}
// save list of to be sold items
@@ -2764,32 +2768,31 @@ static int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_l
intptr_t attribute = item->attribute;
intptr_t identify = item->identify;
- script->setarray_pc(sd, "@sold_nameid", i, (void*)nameid, &key_nameid);
- script->setarray_pc(sd, "@sold_quantity", i, (void*)amount, &key_amount);
-
// process item based information into the arrays
- script->setarray_pc(sd, "@sold_refine", i, (void*)refine, &key_refine);
- script->setarray_pc(sd, "@sold_attribute", i, (void*)attribute, &key_attribute);
- script->setarray_pc(sd, "@sold_identify", i, (void*)identify, &key_identify);
+ script->setarray_pc(sd, "@sold_nameid", i, (void *)nameid, &key_nameid);
+ script->setarray_pc(sd, "@sold_quantity", i, (void *)amount, &key_amount);
+ script->setarray_pc(sd, "@sold_refine", i, (void *)refine, &key_refine);
+ script->setarray_pc(sd, "@sold_attribute", i, (void *)attribute, &key_attribute);
+ script->setarray_pc(sd, "@sold_identify", i, (void *)identify, &key_identify);
for (j = 0; j < MAX_SLOTS; j++) {
intptr_t card = item->card[j];
- // store each of the cards/special info from the item in the array
snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
- script->setarray_pc(sd, card_slot, i, (void*)card, &key_card[j]);
+ script->setarray_pc(sd, card_slot, i, (void *)card, &key_card[j]);
}
for (j = 0; j < MAX_ITEM_OPTIONS; j++) {
intptr_t opt_idx = item->option[j].index;
intptr_t opt_value = item->option[j].value;
+ intptr_t opt_param = item->option[j].param;
- snprintf(opt_index_str, sizeof(opt_index_str), "@slot_opt_idx%d", j + 1);
- script->setarray_pc(sd, opt_index_str, i, (void*)opt_idx, &key_opt_idx[j]);
-
- snprintf(opt_value_str, sizeof(opt_value_str), "@slot_opt_val%d", j + 1);
- script->setarray_pc(sd, opt_value_str, i, (void*)opt_value, &key_opt_value[j]);
+ snprintf(opt_index_str, sizeof(opt_index_str), "@sold_opt_idx%d", j + 1);
+ script->setarray_pc(sd, opt_index_str, i, (void *)opt_idx, &key_opt_idx[j]);
+ snprintf(opt_value_str, sizeof(opt_value_str), "@sold_opt_val%d", j + 1);
+ script->setarray_pc(sd, opt_value_str, i, (void *)opt_value, &key_opt_value[j]);
+ snprintf(opt_param_str, sizeof(opt_param_str), "@sold_opt_param%d", j + 1);
+ script->setarray_pc(sd, opt_param_str, i, (void *)opt_param, &key_opt_param[j]);
}
-
}
// invoke event
@@ -2798,104 +2801,102 @@ static int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_l
return 0;
}
-/// Player item selling to npc shop.
-///
-/// @param item_list 'n' pairs <index,amount>
-/// @return result code for clif->parse_NpcSellListSend
+/**
+ * Processes a character's request to sell items to a NPC shop.
+ *
+ * @param sd The character who wants to sell the items.
+ * @param item_list The list of items and respective amounts which should be sold.
+ * @return 1 on failure, 0 on success.
+ *
+ **/
static int npc_selllist(struct map_session_data *sd, struct itemlist *item_list)
{
- int64 z;
- int i,skill_t, skill_idx = skill->get_index(MC_OVERCHARGE);
- struct npc_data *nd;
- bool duplicates[MAX_INVENTORY] = { 0 };
-
nullpo_retr(1, sd);
nullpo_retr(1, item_list);
- if( ( nd = npc->checknear(sd, map->id2bl(sd->npc_shopid)) ) == NULL ) {
+ struct npc_data *nd = npc->checknear(sd, map->id2bl(sd->npc_shopid));
+
+ if (nd == NULL)
return 1;
- }
- if( nd->subtype != SHOP ) {
- if (!(nd->subtype == SCRIPT && nd->u.scr.shop && (nd->u.scr.shop->type == NST_ZENY || nd->u.scr.shop->type == NST_MARKET)))
+ if (nd->subtype != SHOP) {
+ if (nd->subtype != SCRIPT || nd->u.scr.shop == NULL || (nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET))
return 1;
}
- z = 0;
-
if (sd->status.zeny >= MAX_ZENY && nd->master_nd == NULL)
return 1;
- // verify the sell list
- for (i = 0; i < VECTOR_LENGTH(*item_list); i++) {
+ bool duplicates[MAX_INVENTORY] = { false };
+ int64 z = 0;
+
+ // Verify the sell list.
+ for (int i = 0; i < VECTOR_LENGTH(*item_list); i++) {
struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i);
- int nameid, value, idx = entry->id;
+ int idx = entry->id;
- if (idx >= sd->status.inventorySize || idx < 0 || entry->amount < 0) {
+ if (idx >= sd->status.inventorySize || idx < 0 || entry->amount < 0)
return 1;
- }
- if (duplicates[idx]) {
- // Sanity check. The client sends each inventory index at most once [Haru]
+ if (duplicates[idx]) // Sanity check. The client sends each inventory index at most once. [Haru]
return 1;
- }
+
duplicates[idx] = true;
- nameid = sd->status.inventory[idx].nameid;
+ int nameid = sd->status.inventory[idx].nameid;
- if (!nameid || !sd->inventory_data[idx] || sd->status.inventory[idx].amount < entry->amount) {
+ if (nameid == 0 || sd->inventory_data[idx] == NULL || sd->status.inventory[idx].amount < entry->amount)
return 1;
- }
- if (nd->master_nd) {
- // Script-controlled shops decide by themselves, what can be sold and at what price.
+ if (nd->master_nd != NULL) // Script-controlled shops decide by themselves, what can be sold and at what price.
continue;
- }
- value = pc->modifysellvalue(sd, sd->inventory_data[idx]->value_sell);
+ int value = pc->modifysellvalue(sd, sd->inventory_data[idx]->value_sell);
z += (int64)value * entry->amount;
}
- if( nd->master_nd ) { // Script-controlled shops
+ if (nd->master_nd != NULL) // Script-controlled shops.
return npc->selllist_sub(sd, item_list, nd->master_nd);
- }
- // delete items
- for (i = 0; i < VECTOR_LENGTH(*item_list); i++) {
+ if (z + sd->status.zeny > MAX_ZENY)
+ return 1;
+
+ // Delete items.
+ for (int i = 0; i < VECTOR_LENGTH(*item_list); i++) {
struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i);
int idx = entry->id;
if (sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET) {
- if (pet->search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0) {
+ if (pet->search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0)
intif->delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2]));
- }
}
- // Achievements [Smokexyz/Hercules]
+ // Achievements. [Smokexyz/Hercules]
achievement->validate_item_sell(sd, sd->status.inventory[idx].nameid, entry->amount);
pc->delitem(sd, idx, entry->amount, 0, DELITEM_SOLD, LOG_TYPE_NPC);
-
}
- if (z + sd->status.zeny > MAX_ZENY && nd->master_nd == NULL)
- return 1;
-
if (z > MAX_ZENY)
z = MAX_ZENY;
pc->getzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
- // custom merchant shop exp bonus
- if( battle_config.shop_exp > 0 && z > 0 && ( skill_t = pc->checkskill2(sd,skill_idx) ) > 0) {
- if( sd->status.skill[skill_idx].flag >= SKILL_FLAG_REPLACED_LV_0 )
+ int skill_t;
+ int skill_idx = skill->get_index(MC_OVERCHARGE);
+
+ // Custom merchant shop exp bonus.
+ if (battle_config.shop_exp > 0 && z > 0 && (skill_t = pc->checkskill2(sd, skill_idx)) > 0) {
+ if (sd->status.skill[skill_idx].flag >= SKILL_FLAG_REPLACED_LV_0)
skill_t = sd->status.skill[skill_idx].flag - SKILL_FLAG_REPLACED_LV_0;
- if( skill_t > 0 ) {
+ if (skill_t > 0) {
z = apply_percentrate64(z, skill_t * battle_config.shop_exp, 10000);
+
if (z < 1)
z = 1;
+
pc->gainexp(sd, NULL, 0, (int)z, false);
}
}
@@ -5241,6 +5242,8 @@ static const char *npc_parse_mapflag(const char *w1, const char *w2, const char
map->list[m].flag.nostorage = (state) ? cap_value(atoi(w4), 1, 3) : 0;
} else if (!strcmpi(w3, "nogstorage")) {
map->list[m].flag.nogstorage = (state) ? cap_value(atoi(w4), 1, 3) : 0;
+ } else if (strcmpi(w3, "nopet") == 0) {
+ map->list[m].flag.nopet = (state != 0) ? 1 : 0;
} else {
npc->parse_unknown_mapflag(mapname, w3, w4, start, buffer, filepath, retval);
}