diff --git a/src/map/npc.c b/src/map/npc.c index 174de92949..31e4ce62f5 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1366,6 +1366,63 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) return 0; } +/** Payment Process for NPCTYPE_CASHSHOP, NPCTYPE_ITEMSHOP, and NPCTYPE_POINTSHOP + * @param nd NPC Shop data + * @param price Price must be paid + * @param points Total points that player has + * @param sd Player data + * @return e_CASHSHOP_ACK + **/ +static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int price, int points, struct map_session_data *sd) { + int cost[2] = { 0, 0 }; + + npc_shop_currency_type(sd, nd, cost, false); + + switch(nd->subtype) { + case NPCTYPE_CASHSHOP: + if (cost[1] < points || cost[0] < (price - points)) + return ERROR_TYPE_MONEY; + pc_paycash(sd, price, points, LOG_TYPE_NPC); + break; + case NPCTYPE_ITEMSHOP: + { + struct item_data *id = itemdb_exists(nd->u.shop.itemshop_nameid); + + if (cost[0] < (price - points)) { + char output[CHAT_SIZE_MAX]; + + memset(output, '\0', sizeof(output)); + + sprintf(output, msg_txt(sd, 712), (id) ? id->jname : "NULL", (id) ? id->nameid : 0); // You do not have enough %s (%hu). + clif_colormes(sd->fd, color_table[COLOR_RED], output); + return ERROR_TYPE_PURCHASE_FAIL; + } + if (id) + pc_delitem(sd, pc_search_inventory(sd, nd->u.shop.itemshop_nameid), price - points, 0, 0, LOG_TYPE_NPC); + else + ShowWarning("Failed to delete item %hu from itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y); + } + break; + case NPCTYPE_POINTSHOP: + { + char output[CHAT_SIZE_MAX]; + + memset(output, '\0', sizeof(output)); + + if (cost[0] < (price - points)) { + sprintf(output, msg_txt(sd, 713), nd->u.shop.pointshop_str); // You do not have enough '%s'. + clif_colormes(sd->fd, color_table[COLOR_RED], output); + return ERROR_TYPE_PURCHASE_FAIL; + } + pc_setreg2(sd, nd->u.shop.pointshop_str, cost[0] - (price - points)); + sprintf(output, msg_txt(sd, 716), nd->u.shop.pointshop_str, cost[0] - (price - points)); // Your '%s' is now: %d + clif_disp_onlyself(sd, output, strlen(output) + 1); + } + break; + } + return ERROR_TYPE_NONE; +} + /** * Cash Shop Buy List for clients 2010-11-16 and newer * @param sd: Player data @@ -1376,9 +1433,10 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) */ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list) { - int i, j, amount, new_, w, vt, cost[2] = { 0, 0 }; + int i, j, amount, new_, w, vt; unsigned short nameid; struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid); + enum e_CASHSHOP_ACK res; if( !nd || ( nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) ) return ERROR_TYPE_NPC; @@ -1429,51 +1487,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns return ERROR_TYPE_INVENTORY_WEIGHT; if( points > vt ) points = vt; - // Payment Process ---------------------------------------------------- - npc_shop_currency_type(sd, nd, cost, false); - - switch(nd->subtype) { - case NPCTYPE_CASHSHOP: - if (cost[1] < points || cost[0] < (vt - points)) - return ERROR_TYPE_MONEY; - pc_paycash(sd, vt, points, LOG_TYPE_NPC); - break; - case NPCTYPE_ITEMSHOP: - { - struct item_data *id = itemdb_exists(nd->u.shop.itemshop_nameid); - - if (cost[0] < (vt - points)) { - char output[CHAT_SIZE_MAX]; - - memset(output, '\0', sizeof(output)); - - sprintf(output, msg_txt(sd, 712), (id) ? id->jname : "NULL", (id) ? id->nameid : 0); // You do not have enough %s (%hu). - clif_colormes(sd->fd, color_table[COLOR_RED], output); - return ERROR_TYPE_PURCHASE_FAIL; - } - if (id) - pc_delitem(sd, pc_search_inventory(sd, nd->u.shop.itemshop_nameid), vt - points, 0, 0, LOG_TYPE_NPC); - else - ShowWarning("Failed to delete item %hu from itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y); - } - break; - case NPCTYPE_POINTSHOP: - { - char output[CHAT_SIZE_MAX]; - - memset(output, '\0', sizeof(output)); - - if (cost[0] < (vt - points)) { - sprintf(output, msg_txt(sd, 713), nd->u.shop.pointshop_str); // You do not have enough '%s'. - clif_colormes(sd->fd, color_table[COLOR_RED], output); - return ERROR_TYPE_PURCHASE_FAIL; - } - pc_setreg2(sd, nd->u.shop.pointshop_str, cost[0] - (vt - points)); - sprintf(output, msg_txt(sd, 716), nd->u.shop.pointshop_str, cost[0] - (vt - points)); // Your '%s' is now: %d - clif_disp_onlyself(sd, output, strlen(output) + 1); - } - break; - } + if ((res = npc_cashshop_process_payment(nd, vt, points, sd)) != ERROR_TYPE_NONE) + return res; // Delivery Process ---------------------------------------------------- for( i = 0; i < count; i++ ) { @@ -1573,6 +1588,7 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo 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; if( amount <= 0 ) return ERROR_TYPE_ITEM_ID; @@ -1580,7 +1596,7 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo if( points < 0 ) return ERROR_TYPE_MONEY; - if( !nd || nd->subtype != NPCTYPE_CASHSHOP ) + if( !nd || (nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP) ) return ERROR_TYPE_NPC; if( sd->state.trading ) @@ -1630,10 +1646,8 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo if( points > price ) points = price; - if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) ) - return ERROR_TYPE_MONEY; - - pc_paycash(sd, price, points, LOG_TYPE_NPC); + if ((res = npc_cashshop_process_payment(nd, price, points, sd)) != ERROR_TYPE_NONE) + return res; if( !pet_create_egg(sd, nameid) ) { struct item item_tmp;