Crossfire Server, Branch 1.12  R12190
Defines | Functions | Variables
shop.c File Reference

Those functions deal with shop handling, bargaining, things like that. More...

#include <assert.h>
#include <global.h>
#include <spells.h>
#include <skills.h>
#include <living.h>
#include <newclient.h>
#include <sproto.h>
#include <math.h>
Include dependency graph for shop.c:

Go to the source code of this file.

Defines

#define DISAPPROVAL_RATIO   0.2
 Price a shopkeeper will give to someone they disapprove of.
#define LARGEST_COIN_GIVEN   2
 Never give amber or jade, but accept them.
#define NEUTRAL_RATIO   0.8
 Price a shopkeeper will give someone they neither like nor dislike.
#define NUM_COINS   5
 Number of coin types.
#define SPECIALISATION_EFFECT   0.5
 This is a measure of how effective store specialisation is.

Functions

static void add_value (object *coin_objs[], sint64 value)
 This function adds a given amount to a list of coins.
int can_pay (object *pl)
 Checks all unpaid items in op's inventory, adds up all the money they have, and checks that they can actually afford what they want to buy.
int coords_in_shop (mapstruct *map, int x, int y)
 Check if given map coords are in a shop.
static StringBuffercost_string_from_value (uint64 cost, StringBuffer *buf)
 Converts a price to number of coins.
static void count_unpaid (object *pl, object *item, int *unpaid_count, uint64 *unpaid_price, uint32 *coincount)
 Helper function for can_pay().
int describe_shop (const object *op)
 Gives a desciption of the shop on their current map to the player op.
static archetype * find_next_coin (uint64 c, int *cointype)
 Find the coin type that is worth more than 'c'.
int get_payment (object *pl, object *op)
 Descends containers looking for unpaid items, and pays for them.
static void insert_objects (object *pl, object *container, object *objects[], int objects_len)
 Insert a list of objects into a player object.
int is_in_shop (object *ob)
 Check if an object is in a shop.
int pay_for_amount (uint64 to_pay, object *pl)
 Takes the amount of money from the the player inventory and from it's various pouches using the pay_from_container() function.
int pay_for_item (object *op, object *pl)
 DAMN: This is now a wrapper for pay_from_container, which is called for the player, then for each active container that can hold money until op is paid for.
static uint64 pay_from_container (object *pl, object *pouch, uint64 to_pay)
 This pays for the item, and takes the proper amount of money off the player.
uint64 query_cost (const object *tmp, object *who, int flag)
 Return the price of an item for a character.
StringBufferquery_cost_string (const object *tmp, object *who, int flag, StringBuffer *buf)
 Finds the price of an item.
uint64 query_money (const object *op)
 Finds out how much money the player is carrying, including what is in containers.
static StringBufferreal_money_value (const object *coin, StringBuffer *buf)
 Returns a string representing the money's value, in plain coins.
static sint64 remove_value (object *coin_objs[], sint64 remain)
 This function removes a given amount from a list of coins.
void sell_item (object *op, object *pl)
 Player is selling an item.
static double shop_greed (const mapstruct *map)
 Gets shop's greed.
static double shop_specialisation_ratio (const object *item, const mapstruct *map)
 returns a double that is the ratio of the price that a shop will offer for item based on the shops specialisation.
double shopkeeper_approval (const mapstruct *map, const object *player)
 Returns a double based on how much the shopkeeper approves of the player.
static uint64 value_limit (uint64 val, int quantity, const object *who, int isshop)
 Limit the value of items based on the wealth of the shop.

Variables

static const char *const coins []
 Coins to use for shopping.

Detailed Description

Those functions deal with shop handling, bargaining, things like that.

Todo:
isn't there redundance with pay_for_item(), get_payment(), pay_for_amount()?

Definition in file shop.c.


Define Documentation

#define DISAPPROVAL_RATIO   0.2

Price a shopkeeper will give to someone they disapprove of.

Definition at line 58 of file shop.c.

#define LARGEST_COIN_GIVEN   2

Never give amber or jade, but accept them.

Definition at line 70 of file shop.c.

Referenced by add_value(), cost_string_from_value(), query_cost_string(), and sell_item().

#define NEUTRAL_RATIO   0.8

Price a shopkeeper will give someone they neither like nor dislike.

Definition at line 61 of file shop.c.

Referenced by shopkeeper_approval().

#define NUM_COINS   5

Number of coin types.

Definition at line 68 of file shop.c.

Referenced by add_value(), can_pay(), count_unpaid(), pay_from_container(), and remove_value().

#define SPECIALISATION_EFFECT   0.5

This is a measure of how effective store specialisation is.

A general store will offer this proportion of the 'maximum' price, a specialised store will offer a range of prices around it such that the maximum price is always one therefore making this number higher, makes specialisation less effective. setting this value above 1 or to a negative value would have interesting, (though not useful) effects.

Definition at line 55 of file shop.c.

Referenced by shop_specialisation_ratio().


Function Documentation

static void add_value ( object *  coin_objs[],
sint64  value 
) [static]

This function adds a given amount to a list of coins.

Parameters:
coin_objsthe list coins to add to; the list must be ordered from least to most valuable coin
valuethe value (in silver coins) to add

Definition at line 741 of file shop.c.

References LARGEST_COIN_GIVEN, and NUM_COINS.

Referenced by pay_from_container().

Here is the caller graph for this function:

int can_pay ( object *  pl)

Checks all unpaid items in op's inventory, adds up all the money they have, and checks that they can actually afford what they want to buy.

Prints appropriate messages to the player.

Parameters:
plplayer trying to bug.
Return values:
1player could buy the items.
0some items can't be bought.

Definition at line 938 of file shop.c.

References coins, cost_string_from_value(), count_unpaid(), draw_ext_info(), find_archetype(), llevError, LOG(), make_list_like(), MAX_BUF, MSG_TYPE_SHOP, MSG_TYPE_SHOP_PAYMENT, NDI_UNIQUE, NUM_COINS, PLAYER, query_money(), snprintf(), and stringbuffer_finish().

Referenced by cfapi_player_can_pay(), and shop_mat_type_move_on().

Here is the call graph for this function:

Here is the caller graph for this function:

int coords_in_shop ( mapstruct map,
int  x,
int  y 
)

Check if given map coords are in a shop.

Parameters:
map
x
ycoordinates to check.
Returns:
1 if coordinates are a shop, 0 otherwise.

Definition at line 1429 of file shop.c.

References GET_MAP_OB, and SHOP_FLOOR.

Referenced by is_in_shop().

Here is the caller graph for this function:

static StringBuffer* cost_string_from_value ( uint64  cost,
StringBuffer buf 
) [static]

Converts a price to number of coins.

While cost is 64 bit, the number of any coin is still really limited to 32 bit (size of nrof field). If it turns out players have so much money that they have more than 2 billion platinum coins, there are certainly issues - the easiest fix at that time is to add a higher denomination (mithril piece with 10,000 silver or something)

Parameters:
costvalue to transform to currency.
bufbuffer to append to, if NULL a new one is returned.
Returns:
buffer containing the price, either buf or if NULL a new StringBuffer.

Definition at line 417 of file shop.c.

References find_next_coin(), LARGEST_COIN_GIVEN, stringbuffer_append_printf(), stringbuffer_append_string(), stringbuffer_new(), and UINT32_MAX.

Referenced by can_pay(), describe_shop(), get_payment(), and query_cost_string().

Here is the call graph for this function:

Here is the caller graph for this function:

static void count_unpaid ( object *  pl,
object *  item,
int *  unpaid_count,
uint64 *  unpaid_price,
uint32 coincount 
) [static]

Helper function for can_pay().

Checks all items from item and item->below, and recurse if inventory found. coincount is supposed to be of size NUM_COINS. Parameters can't be NULL.

Parameters:
plplayer.
itemitem to check for.
[out]unpaid_counthow many unpaid items are left.
[out]unpaid_pricetotal price unpaid.
coincountarray of NUM_COINS size, will contain how many coins of the type the player has.

Definition at line 904 of file shop.c.

References coins, F_BUY, F_SHOP, FLAG_UNPAID, NUM_COINS, query_cost(), and QUERY_FLAG.

Referenced by can_pay().

Here is the call graph for this function:

Here is the caller graph for this function:

int describe_shop ( const object *  op)

Gives a desciption of the shop on their current map to the player op.

Parameters:
opplayer to describe the shop for. Mustn't be NULL.
Returns:
0 if op is not a player, 1 else.
Todo:
is return value meaningful?

Definition at line 1311 of file shop.c.

References cost_string_from_value(), draw_ext_info(), draw_ext_info_format(), shopitem::index, make_list_like(), MAX_BUF, MSG_TYPE_SHOP, MSG_TYPE_SHOP_LISTING, MSG_TYPE_SHOP_MISC, shopitem::name, shopitem::name_pl, NDI_UNIQUE, PLAYER, mapdef::shopgreed, mapdef::shopitems, shopkeeper_approval(), mapdef::shopmax, mapdef::shopmin, mapdef::shoprace, snprintf(), shopitem::strength, and stringbuffer_finish().

Referenced by do_skill().

Here is the call graph for this function:

Here is the caller graph for this function:

static archetype* find_next_coin ( uint64  c,
int *  cointype 
) [static]

Find the coin type that is worth more than 'c'.

Starts at the cointype placement.

Parameters:
cvalue we're searching.
cointypefirst coin type to search.
Returns:
coin archetype, NULL if none found.

Definition at line 385 of file shop.c.

References coins, and find_archetype().

Referenced by cost_string_from_value(), and query_cost_string().

Here is the call graph for this function:

Here is the caller graph for this function:

int get_payment ( object *  pl,
object *  op 
)

Descends containers looking for unpaid items, and pays for them.

Parameters:
plplayer buying the stuff.
opobject we are examining. If op has and inventory, we examine that. IF there are objects below op, we descend down.
Return values:
0player still has unpaid items.
1player has paid for everything.

Definition at line 992 of file shop.c.

References CLEAR_FLAG, cost_string_from_value(), draw_ext_info_format(), esrv_update_item(), F_BUY, F_SHOP, FLAG_PLAYER_SOLD, FLAG_UNPAID, get_payment(), MAX_BUF, merge_ob(), MSG_TYPE_SHOP, MSG_TYPE_SHOP_PAYMENT, NDI_UNIQUE, pay_for_item(), PLAYER, query_cost(), query_cost_string(), QUERY_FLAG, query_money(), query_name(), SET_FLAG, stringbuffer_finish(), UPD_FLAGS, and UPD_NAME.

Referenced by get_payment(), and shop_mat_type_move_on().

Here is the call graph for this function:

Here is the caller graph for this function:

static void insert_objects ( object *  pl,
object *  container,
object *  objects[],
int  objects_len 
) [static]

Insert a list of objects into a player object.

Parameters:
plthe player to add to
containerthe container (inside the player object) to add to
objectsthe list of objects to add; the objects will be either inserted into the player object or freed
objects_lenthe length of objects

Definition at line 765 of file shop.c.

References esrv_update_item(), free_object(), insert_ob_in_ob(), and UPD_WEIGHT.

Referenced by pay_from_container().

Here is the call graph for this function:

Here is the caller graph for this function:

int is_in_shop ( object *  ob)

Check if an object is in a shop.

Parameters:
obobject to check for.
Returns:
1 if in a shop so, 0 otherwise.

Definition at line 1414 of file shop.c.

References coords_in_shop().

Referenced by convert_item(), drop_object(), examine(), kill_player(), shop_mat_type_move_on(), and transport_type_apply().

Here is the call graph for this function:

Here is the caller graph for this function:

int pay_for_amount ( uint64  to_pay,
object *  pl 
)

Takes the amount of money from the the player inventory and from it's various pouches using the pay_from_container() function.

Parameters:
to_payamount to pay.
plplayer paying.
Returns:
0 if not enough money, in which case nothing is removed, 1 if money was removed.
Todo:
check if pl is a player, as query_money() expects that. Check if fix_object() call is required.

Definition at line 613 of file shop.c.

References CONTAINER, fix_object(), FLAG_APPLIED, llevError, LOG(), pay_from_container(), QUERY_FLAG, and query_money().

Referenced by cfapi_object_pay_amount().

Here is the call graph for this function:

Here is the caller graph for this function:

int pay_for_item ( object *  op,
object *  pl 
)

DAMN: This is now a wrapper for pay_from_container, which is called for the player, then for each active container that can hold money until op is paid for.

Change will be left wherever the last of the price was paid from.

Parameters:
opobject to buy.
plplayer buying.
Returns:
1 if object was bought, 0 else.
Todo:
check if pl is a player, as query_money() expects a player.

Definition at line 652 of file shop.c.

References change_exp(), CONTAINER, F_BUY, F_NO_BARGAIN, F_SHOP, FALSE, fix_object(), FLAG_APPLIED, FLAG_WAS_WIZ, llevError, LOG(), pay_from_container(), query_cost(), QUERY_FLAG, query_money(), Settings::real_wiz, SET_FLAG, settings, and SK_EXP_NONE.

Referenced by cfapi_object_pay_item(), and get_payment().

Here is the call graph for this function:

Here is the caller graph for this function:

static uint64 pay_from_container ( object *  pl,
object *  pouch,
uint64  to_pay 
) [static]

This pays for the item, and takes the proper amount of money off the player.

DAMN: This function is used for the player, then for any active containers that can hold money.

Parameters:
plplayer paying.
pouchcontainer (pouch or player) to remove the coins from.
to_payrequired amount.
Returns:
amount still not paid after using "pouch".

Definition at line 796 of file shop.c.

References add_value(), coins, CONTAINER, copy_object(), find_archetype(), free_object(), get_object(), insert_objects(), llevError, LOG(), MONEY, NUM_COINS, PLAYER, remove_ob(), and remove_value().

Referenced by pay_for_amount(), and pay_for_item().

Here is the call graph for this function:

Here is the caller graph for this function:

uint64 query_cost ( const object *  tmp,
object *  who,
int  flag 
)

Return the price of an item for a character.

Price will vary based on the shop's specialization ration, the player's approval rate, ...

Added F_TRUE flag to define.h to mean that the price should not be adjusted by players charisma. With F_TRUE, it returns the amount that the item is worth, if it was sold, but unadjusted by charisma. This is needed for alchemy, to to determine what value of gold nuggets should be given (the gold nuggets, when sold, will have the adjustment by charisma done at that time). NULL could have been passed as the who parameter, but then the adjustment for expensive items (>10000) would not be done.

Added F_APPROX flag, which means that the price returned should be wrong by an amount related to the player's bargaining skill.

Added F_SHOP flag to mean that the specialisation of the shop on the player's current map should be taken into account when determining the price. Shops that specialise in what is being traded will give better prices than those that do not.

CF 0.91.4 - This function got changed around a bit. Now the number of object is multiplied by the value early on. This fixes problems with items worth very little. What happened before is that various divisions took place, the value got rounded to 0 (Being an int), and thus remained 0.

Mark Wedel (mwedel@pyramid.com)

Parameters:
tmpobject we're querying the price of.
whowho is inquiring. Can be NULL, only meaningful if player.
flagcombination of F_xxx flags.
Returns:

Definition at line 121 of file shop.c.

References cha_bonus, F_APPROX, F_BUY, F_IDENTIFIED, F_NO_BARGAIN, F_NOT_CURSED, F_SELL, F_SHOP, F_TRUE, find_skill_by_number(), FLAG_BEEN_APPLIED, FLAG_CURSED, FLAG_DAMNED, FLAG_IDENTIFIED, FLAG_PLAYER_SOLD, GEM, get_ob_key_value(), get_typedata(), typedata::identifyskill, typedata::identifyskill2, llevDebug, llevError, LOG(), Settings::max_level, MIN, MONEY, need_identify(), PLAYER, POTION, QUERY_FLAG, settings, shop_greed(), shop_specialisation_ratio(), shopkeeper_approval(), SK_BARGAINING, value_limit(), and WAND.

Referenced by alchemy(), alchemy_object(), attempt_do_alchemy(), cfapi_object_query_cost(), check_pick(), count_unpaid(), get_payment(), pay_for_item(), query_cost_string(), and sell_item().

Here is the call graph for this function:

Here is the caller graph for this function:

StringBuffer* query_cost_string ( const object *  tmp,
object *  who,
int  flag,
StringBuffer buf 
)

Finds the price of an item.

Price will be either an approximate value or the real value.

Parameters:
tmpobject to get the price of.
whowho is getting the price.
flagcombination of F_xxx values.
bufbuffer to append to. If NULL, a newly allocated one will be used and returned.
Returns:
buffer containing the price, new if buf was NULL.

Definition at line 511 of file shop.c.

References cost_string_from_value(), F_APPROX, find_next_coin(), find_skill_by_number(), get_typedata(), typedata::identifyskill, typedata::identifyskill2, LARGEST_COIN_GIVEN, MONEY, query_cost(), real_money_value(), SK_BARGAINING, stringbuffer_append_printf(), stringbuffer_append_string(), and stringbuffer_new().

Referenced by examine(), get_payment(), pick_up_object(), and sell_item().

Here is the call graph for this function:

Here is the caller graph for this function:

uint64 query_money ( const object *  op)

Finds out how much money the player is carrying, including what is in containers.

Parameters:
opitem to get money for. Must be a player or a container.
Returns:
total money the player is carrying.

Definition at line 581 of file shop.c.

References CONTAINER, FLAG_APPLIED, llevError, LOG(), MONEY, PLAYER, QUERY_FLAG, and query_money().

Referenced by can_pay(), cfapi_object_query_money(), get_payment(), pay_for_amount(), pay_for_item(), and query_money().

Here is the call graph for this function:

Here is the caller graph for this function:

static StringBuffer* real_money_value ( const object *  coin,
StringBuffer buf 
) [static]

Returns a string representing the money's value, in plain coins.

Parameters:
coincoin. Must be of type MONEY.
bufbuffer to append to. Must not be NULL.
Returns:
buf with the value.

Definition at line 488 of file shop.c.

References MONEY, and stringbuffer_append_printf().

Referenced by query_cost_string().

Here is the call graph for this function:

Here is the caller graph for this function:

static sint64 remove_value ( object *  coin_objs[],
sint64  remain 
) [static]

This function removes a given amount from a list of coins.

Parameters:
coin_objsthe list coins to remove from; the list must be ordered from least to most valuable coin.
remainthe value (in silver coins) to remove
Returns:
the value remaining

Definition at line 700 of file shop.c.

References NUM_COINS.

Referenced by pay_from_container().

Here is the caller graph for this function:

void sell_item ( object *  op,
object *  pl 
)

Player is selling an item.

Give money, print appropriate messages.

This function uses the coins[] array to know what coins are available.

Modified to fill available race: gold containers before dumping remaining coins in character's inventory.

Parameters:
opobject to sell.
plplayer. Shouldn't be NULL or non player.

Definition at line 1059 of file shop.c.

References change_exp(), coins, CONTAINER, copy_object(), draw_ext_info_format(), esrv_update_item(), F_NO_BARGAIN, F_SELL, F_SHOP, find_archetype(), FLAG_APPLIED, FLAG_PLAYER_SOLD, FLAG_UNPAID, FREE_AND_CLEAR_STR, get_object(), identify(), insert_ob_in_ob(), LARGEST_COIN_GIVEN, llevDebug, llevError, LOG(), MAX_BUF, MSG_TYPE_SHOP, MSG_TYPE_SHOP_SELL, NDI_UNIQUE, PLAYER, query_cost(), query_cost_string(), QUERY_FLAG, query_name(), SET_FLAG, SK_EXP_NONE, stringbuffer_finish(), UPD_WEIGHT, and weight_limit.

Referenced by drop_object().

Here is the call graph for this function:

Here is the caller graph for this function:

static double shop_greed ( const mapstruct map) [static]

Gets shop's greed.

Parameters:
mapmap to get greed.
Returns:
greed of the shop on map, or 1 if it isn't specified.

Definition at line 1224 of file shop.c.

References mapdef::shopgreed.

Referenced by query_cost().

Here is the caller graph for this function:

static double shop_specialisation_ratio ( const object *  item,
const mapstruct map 
) [static]

returns a double that is the ratio of the price that a shop will offer for item based on the shops specialisation.

Does not take account of greed, returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any event is never less than 0.1 (calling functions divide by it)

Parameters:
itemitem to get ratio of.
mapshop map.
Returns:
ratio specialisation for the item.

Definition at line 1179 of file shop.c.

References shopitem::index, llevDebug, llevError, LOG(), mapdef::path, mapdef::shopitems, SPECIALISATION_EFFECT, shopitem::strength, and shopitem::typenum.

Referenced by query_cost().

Here is the call graph for this function:

Here is the caller graph for this function:

double shopkeeper_approval ( const mapstruct map,
const object *  player 
)

Returns a double based on how much the shopkeeper approves of the player.

this is based on the race of the shopkeeper and that of the player.

Parameters:
mapshop to get ratio for.
playerplayer to get ratio of.
Returns:
approval ratio.

Definition at line 1243 of file shop.c.

References NEUTRAL_RATIO, and mapdef::shoprace.

Referenced by describe_shop(), query_cost(), and shop_mat_type_move_on().

Here is the caller graph for this function:

static uint64 value_limit ( uint64  val,
int  quantity,
const object *  who,
int  isshop 
) [static]

Limit the value of items based on the wealth of the shop.

If the item is close to the maximum value a shop will offer, we start to reduce it, if the item is below the minimum value the shop is prepared to trade in, then we don't want it and offer nothing. If it isn't a shop, check whether we should do generic value reduction.

Parameters:
valcurrent price.
quantitynumber of items.
whoplayer selling.
isshop0 if not a shop, 1 if a shop.
Returns:
maximum global value.

Definition at line 1273 of file shop.c.

References isqrt(), llevError, LOG(), MIN, mapdef::shopmax, and mapdef::shopmin.

Referenced by query_cost().

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const char* const coins[] [static]
Initial value:
 {
    "ambercoin",
    "jadecoin",
    "platinacoin",
    "goldcoin",
    "silvercoin",
    NULL
}

Coins to use for shopping.

Definition at line 73 of file shop.c.

Referenced by can_pay(), count_unpaid(), find_next_coin(), pay_from_container(), and sell_item().