Skip to content

Commit

Permalink
Added documentation regarding trader objects in script_commands.txt
Browse files Browse the repository at this point in the history
Added enumered returns to npc_cashshop_buy and to npc_cashshop_buylist
  • Loading branch information
panikon committed May 10, 2014
1 parent a168c78 commit 6d4ae76
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 41 deletions.
38 changes: 38 additions & 0 deletions doc/script_commands.txt
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down
12 changes: 1 addition & 11 deletions src/map/clif.c
Expand Up @@ -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;
Expand Down
16 changes: 16 additions & 0 deletions src/map/clif.h
Expand Up @@ -348,6 +348,22 @@ enum clif_messages {
ITEM_CANT_USE_AREA = 0x537,
};

/**
* 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
**/
Expand Down
60 changes: 30 additions & 30 deletions src/map/npc.c
Expand Up @@ -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;
Expand All @@ -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",
Expand All @@ -1347,28 +1347,28 @@ 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;
w += itemdb_weight(nameid) * amount;
}

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 ----------------------------------------------------
Expand All @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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",
Expand All @@ -1673,23 +1673,23 @@ 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);
ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n",
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;
Expand All @@ -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);
}
Expand All @@ -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.
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 6d4ae76

Please sign in to comment.