diff options
Diffstat (limited to 'src/map/npc.c')
-rw-r--r-- | src/map/npc.c | 109 |
1 files changed, 100 insertions, 9 deletions
diff --git a/src/map/npc.c b/src/map/npc.c index b7b62898f..37b8d99b8 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -932,6 +932,9 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd) case SHOP: clif_npcbuysell(sd,nd->bl.id); break; + case CASHSHOP: + clif_cashshop_show(sd,nd); + break; case SCRIPT: run_script(nd->u.scr.script,0,sd->bl.id,nd->bl.id); break; @@ -1012,6 +1015,77 @@ static int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* i npc_event(sd, npc_ev, 0); return 0; } +/*========================================== + * Cash Shop Buy + *------------------------------------------*/ +int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points) +{ + struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid); + struct item_data *item; + int i, prize, w; + + if( !nd || nd->subtype != CASHSHOP ) + return 1; + + if( sd->state.trading ) + return 4; + + if( (item = itemdb_search(nameid)) == NULL ) + return 5; // Invalid Item + + ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid); + if( i == nd->u.shop.count ) + return 5; + if( nd->u.shop.shop_item[i].value <= 0 ) + return 5; + + if(!itemdb_isstackable(nameid) && amount > 1) + { + ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", + sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); + amount = 1; + } + + switch( pc_checkadditem(sd, nameid, amount) ) + { + case ADDITEM_NEW: + if( pc_inventoryblank(sd) == 0 ) + return 3; + break; + case ADDITEM_OVERAMOUNT: + return 3; + } + + w = item->weight * amount; + if( w + sd->weight > sd->max_weight ) + return 3; + + prize = nd->u.shop.shop_item[i].value * amount; + if( points > prize ) + points = prize; + + if( sd->cashPoints < prize - points ) + return 6; + if( sd->kafraPoints < points ) + return 6; + + pc_paycash(sd, prize, points); + + if( !pet_create_egg(sd, nameid) ) + { + struct item item_tmp; + memset(&item_tmp, 0, sizeof(struct item)); + item_tmp.nameid = nameid; + item_tmp.identify = 1; + + pc_additem(sd,&item_tmp, amount); + } + + if(log_config.enable_logs&0x20) + log_pick_pc(sd, "S", nameid, amount, NULL); + + return 0; +} /*========================================== * @@ -1266,7 +1340,7 @@ int npc_unload(struct npc_data* nd) npc_chat_finalize(nd); // deallocate npc PCRE data structures #endif - if( nd->subtype == SHOP ) + if( nd->subtype == SHOP || nd->subtype == CASHSHOP ) aFree(nd->u.shop.shop_item); else if( nd->subtype == SCRIPT ) @@ -1547,7 +1621,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const return strchr(start,'\n');// continue } -/// Parses a shop npc. +/// Parses a shop/cashshop npc. static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) { //TODO: could be rewritten to NOT need this temp array [ultramage] @@ -1557,12 +1631,17 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const int x, y, dir, m, i; struct npc_data *nd; + enum npc_subtype type = SHOP; + if( !strcasecmp(w2,"cashshop") ) + type = CASHSHOP; + if( strcmp(w1,"-") == 0 ) {// 'floating' shop? - x = 0; y = 0; dir = 0; m = -1; + x = y = dir = 0; + m = -1; } else - {// w1=<map name>,<x>,<y>,<facing> + { char mapname[32]; if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 || strchr(w4, ',') == NULL ) @@ -1570,6 +1649,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const ShowError("npc_parse_shop: Invalid shop definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); return strchr(start,'\n');// skip and continue } + m = map_mapname2mapid(mapname); } @@ -1583,14 +1663,25 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const ShowError("npc_parse_shop: Invalid item definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); break; } - id = itemdb_search(nameid); + + if( (id = itemdb_search(nameid)) == NULL ) + { + ShowError("npc_parse_shop: Invalid sell item in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); + break; + } + if( value < 0 ) - value = id->value_buy; - if( value*0.75 < id->value_sell*1.24 ) + { + if( type == SHOP ) value = id->value_buy; + else value = 0; // Cashshop don't have a "buy prize" in the item_db + } + + if( type == SHOP && value*0.75 < id->value_sell*1.24 ) {// Expoit possible: you can buy and sell back with profit ShowWarning("npc_parse_shop: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n", id->name, nameid, value, (int)(value*0.75), id->value_sell, (int)(id->value_sell*1.24), filepath, strline(buffer,start-buffer)); } + //for logs filters, atcommands and iteminfo script command if( id->maxchance <= 0 ) id->maxchance = 10000; //10000 (100% drop chance)would show that the item's sold in NPC Shop @@ -1620,7 +1711,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const ++npc_shop; nd->bl.type = BL_NPC; - nd->subtype = SHOP; + nd->subtype = type; if( m >= 0 ) {// normal shop npc map_addnpc(m,nd); @@ -2605,7 +2696,7 @@ void npc_parsesrcfile(const char* filepath) { p = npc_parse_warp(w1,w2,w3,w4, p, buffer, filepath); } - else if( strcasecmp(w2,"shop") == 0 && count > 3 ) + else if( (!strcasecmp(w2,"shop") || !strcasecmp(w2,"cashshop")) && count > 3 ) { p = npc_parse_shop(w1,w2,w3,w4, p, buffer, filepath); } |