diff options
-rw-r--r-- | doc/script_commands.txt | 38 | ||||
-rw-r--r-- | src/map/clif.c | 12 | ||||
-rw-r--r-- | src/map/clif.h | 16 | ||||
-rw-r--r-- | src/map/npc.c | 60 |
4 files changed, 85 insertions, 41 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt index bb714d856..898e4e331 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -299,6 +299,29 @@ type of shop will not allow you to sell items at it, you may only purchase items here. The layout used to define sale items still count, and "<price>" refers to how many points will be spent purchasing the them. +** Define a trader NPC +<map name>,<x>,<y>,<facing>%TAB%trader%TAB%<NPC Name>%TAB%<sprite id>,{<code>} +-%TAB%trader%TAB%<NPC Name>%TAB%-1,{<code>} + +All the standards that are valid to script objects are also valid for trader objects +(see ** Define an NPC object for more information). +This will define a trader NPC, which can cause a shop, cashshop or market window +to come up when clicked or called by other means. Unlike shop/cashshop NPCs this +type will run a code and can change the items that are being sold over time without +other NPC objects. +The types that a trader object can have are the following: +- NST_ZENY (0) Normal Zeny Shop (shop) +- NST_CASH (1) Normal Cash Shop (cashshop) +- NST_MARKET (2) Normal NPC Market Shop (where items have limited availability + and need to be refurbished) +- NST_CUSTOM (3) Custom Shop (any currency, item/var/etca, check sample) +Unless otherwise specified via *tradertype an trader object will be defined as +NST_ZENY. + +Note: NST_MARKET is only available with PACKETVER 20131223 or newer. +See '12 - NPC Trader-Related Commands' and /doc/sample/npc_trader_sample.txt for +more information regarding how to use this NPC type. + ** Define an warp/shop/cashshop/NPC duplicate. warp: <map name>,<x>,<y>{,<facing>}%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<spanx>,<spany> @@ -1061,6 +1084,21 @@ Only the special labels which are not associated with any script command are listed here. There are other kinds of labels which may be triggered in a similar manner, but they are described with their associated commands. +OnCountFunds: + +This special label is triggered when a player opens a trader NPC object that +is NST_CUSTOM. It is used to define different currency types to the trader via +*setcurrency. Should be used along with OnPayFunds, see /doc/sample/npc_trader_sample.txt +for more information. + +OnPayFunds: + +This special label is triggered when a purchase is made on a trader NPC object +that is NST_CUSTOM. Receives @price, total cost and @points, secondary input +field for cash windows. It is used to remove items that are set as currency. +Should be used along with OnCountFunds, see /doc/sample/npc_trader_sample.txt +for more information. + On<label name>: These special labels are used with Mob scripts mostly, and script commands diff --git a/src/map/clif.c b/src/map/clif.c index 1da6070e8..0fc1fe044 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -15561,20 +15561,10 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) { WFIFOSET(fd,WFIFOW(fd,2)); } - /// Cashshop Buy Ack (ZC_PC_CASH_POINT_UPDATE). /// 0289 <cash point>.L <error>.W /// 0289 <cash point>.L <kafra point>.L <error>.W (PACKETVER >= 20070711) -/// error: -/// 0 = The deal has successfully completed. (ERROR_TYPE_NONE) -/// 1 = The Purchase has failed because the NPC does not exist. (ERROR_TYPE_NPC) -/// 2 = The Purchase has failed because the Kafra Shop System is not working correctly. (ERROR_TYPE_SYSTEM) -/// 3 = You are over your Weight Limit. (ERROR_TYPE_INVENTORY_WEIGHT) -/// 4 = You cannot purchase items while you are in a trade. (ERROR_TYPE_EXCHANGE) -/// 5 = The Purchase has failed because the Item Information was incorrect. (ERROR_TYPE_ITEM_ID) -/// 6 = You do not have enough Kafra Credit Points. (ERROR_TYPE_MONEY) -/// 7 = You can purchase up to 10 items. -/// 8 = Some items could not be purchased. +/// For error return codes see enum cashshop_error@clif.h void clif_cashshop_ack(struct map_session_data* sd, int error) { struct npc_data *nd; int fd = sd->fd; diff --git a/src/map/clif.h b/src/map/clif.h index f54c4afce..d0444f9fe 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -349,6 +349,22 @@ enum clif_messages { }; /** + * Used to answer CZ_PC_BUY_CASH_POINT_ITEM (clif_parse_cashshop_buy) + **/ +enum cashshop_error { + ERROR_TYPE_NONE = 0, // The deal has successfully completed. (ERROR_TYPE_NONE) + ERROR_TYPE_NPC, // The Purchase has failed because the NPC does not exist. (ERROR_TYPE_NPC) + ERROR_TYPE_SYSTEM, // The Purchase has failed because the Kafra Shop System is not working correctly. (ERROR_TYPE_SYSTEM) + ERROR_TYPE_INVENTORY_WEIGHT, // You are over your Weight Limit. (ERROR_TYPE_INVENTORY_WEIGHT) + ERROR_TYPE_EXCHANGE, // You cannot purchase items while you are in a trade. (ERROR_TYPE_EXCHANGE) + ERROR_TYPE_ITEM_ID, // The Purchase has failed because the Item Information was incorrect. (ERROR_TYPE_ITEM_ID) + ERROR_TYPE_MONEY, // You do not have enough Kafra Credit Points. (ERROR_TYPE_MONEY) + // Unofficial type names + ERROR_TYPE_QUANTITY, // You can purchase up to 10 items. (ERROR_TYPE_QUANTITY) + ERROR_TYPE_NOT_ALL, // Some items could not be purchased. (ERROR_TYPE_NOT_ALL) +}; + +/** * Color Table **/ enum clif_colors { diff --git a/src/map/npc.c b/src/map/npc.c index 289c42d44..247d7109b 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1298,23 +1298,23 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns unsigned short shop_size = 0; if( sd->state.trading ) - return 4; + return ERROR_TYPE_EXCHANGE; if( count <= 0 ) - return 5; + return ERROR_TYPE_ITEM_ID; if( points < 0 ) - return 6; + return ERROR_TYPE_MONEY; if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) ) - return 1; + return ERROR_TYPE_NPC; if( nd->subtype != CASHSHOP ) { if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET ) { shop = nd->u.scr.shop->item; shop_size = nd->u.scr.shop->items; } else - return 1; + return ERROR_TYPE_NPC; } else { shop = nd->u.shop.shop_item; shop_size = nd->u.shop.count; @@ -1330,11 +1330,11 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns amount = item_list[i*2+0]; if( !itemdb->exists(nameid) || amount <= 0 ) - return 5; + return ERROR_TYPE_ITEM_ID; ARR_FIND(0,shop_size,j,shop[j].nameid == nameid); if( j == shop_size || shop[j].value <= 0 ) - return 5; + return ERROR_TYPE_ITEM_ID; if( !itemdb->isstackable(nameid) && amount > 1 ) { ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", @@ -1347,7 +1347,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns new_++; break; case ADDITEM_OVERAMOUNT: - return 3; + return ERROR_TYPE_INVENTORY_WEIGHT; } vt += shop[j].value * amount; @@ -1355,20 +1355,20 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns } if( w + sd->weight > sd->max_weight ) - return 3; + return ERROR_TYPE_INVENTORY_WEIGHT; if( pc->inventoryblank(sd) < new_ ) - return 3; + return ERROR_TYPE_INVENTORY_WEIGHT; if( points > vt ) points = vt; // Payment Process ---------------------------------------------------- if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) { if( !npc->trader_pay(nd,sd,vt,points) ) - return 6; + return ERROR_TYPE_MONEY; } else { if( sd->kafraPoints < points || sd->cashPoints < (vt - points) ) - return 6; + return ERROR_TYPE_MONEY; pc->paycash(sd,vt,points); } // Delivery Process ---------------------------------------------------- @@ -1387,7 +1387,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns } } - return 0; + return ERROR_TYPE_NONE; } //npc_buylist for script-controlled shops. @@ -1631,26 +1631,26 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po unsigned short shop_size = 0; if( amount <= 0 ) - return 5; + return ERROR_TYPE_ITEM_ID; if( points < 0 ) - return 6; + return ERROR_TYPE_MONEY; if( sd->state.trading ) - return 4; + return ERROR_TYPE_EXCHANGE; if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) ) - return 1; + return ERROR_TYPE_NPC; if( (item = itemdb->exists(nameid)) == NULL ) - return 5; // Invalid Item + return ERROR_TYPE_ITEM_ID; // Invalid Item if( nd->subtype != CASHSHOP ) { if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET ) { shop = nd->u.scr.shop->item; shop_size = nd->u.scr.shop->items; } else - return 1; + return ERROR_TYPE_NPC; } else { shop = nd->u.shop.shop_item; shop_size = nd->u.shop.count; @@ -1659,10 +1659,10 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po ARR_FIND(0, shop_size, i, shop[i].nameid == nameid); if( i == shop_size ) - return 5; + return ERROR_TYPE_ITEM_ID; if( shop[i].value <= 0 ) - return 5; + return ERROR_TYPE_ITEM_ID; if(!itemdb->isstackable(nameid) && amount > 1) { ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", @@ -1673,15 +1673,15 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po switch( pc->checkadditem(sd, nameid, amount) ) { case ADDITEM_NEW: if( pc->inventoryblank(sd) == 0 ) - return 3; + return ERROR_TYPE_INVENTORY_WEIGHT; break; case ADDITEM_OVERAMOUNT: - return 3; + return ERROR_TYPE_INVENTORY_WEIGHT; } w = item->weight * amount; if( w + sd->weight > sd->max_weight ) - return 3; + return ERROR_TYPE_INVENTORY_WEIGHT; if( (double)shop[i].value * amount > INT_MAX ) { ShowWarning("npc_cashshop_buy: Item '%s' (%d) price overflow attempt!\n", item->name, nameid); @@ -1689,7 +1689,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po nd->exname, map->list[nd->bl.m].name, nd->bl.x, nd->bl.y, sd->status.name, sd->status.account_id, sd->status.char_id, shop[i].value, amount); - return 5; + return ERROR_TYPE_ITEM_ID; } price = shop[i].value * amount; @@ -1699,10 +1699,10 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) { if( !npc->trader_pay(nd,sd,price,points) ) - return 6; + return ERROR_TYPE_MONEY; } else { if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) ) - return 6; + return ERROR_TYPE_MONEY; pc->paycash(sd, price, points); } @@ -1716,7 +1716,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po pc->additem(sd,&item_tmp, amount, LOG_TYPE_NPC); } - return 0; + return ERROR_TYPE_NONE; } /// Player item purchase from npc shop. @@ -2612,7 +2612,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s enum npc_subtype type; if( strcmp(w1,"-") == 0 ) { - // 'floating' shop? + // 'floating' shop x = y = dir = 0; m = -1; } else {// w1=<map name>,<x>,<y>,<facing> @@ -2711,7 +2711,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s nd->dir = dir; if( map->list[nd->bl.m].users ) clif->spawn(&nd->bl); - } else {// 'floating' shop? + } else {// 'floating' shop map->addiddb(&nd->bl); } strdb_put(npc->name_db, nd->exname, nd); |