55 #define SPECIALISATION_EFFECT 0.5
58 #define DISAPPROVAL_RATIO 0.2
61 #define NEUTRAL_RATIO 0.8
64 static uint64
value_limit(uint64 val,
int quantity,
const object *who,
int isshop);
70 #define LARGEST_COIN_GIVEN 2
73 static const char *const coins[] = {
121 uint64
query_cost(
const object *tmp,
object *who,
int flag) {
138 flag &= ~(F_NO_BARGAIN|F_IDENTIFIED|F_NOT_CURSED|F_APPROX|
F_SHOP);
146 return tmp->
value*number*ratio;
150 return tmp->
value*number*ratio;
154 return tmp->
value*number*ratio;
161 return number*tmp->
value;
166 LOG(
llevError,
"Query_cost: Gem type with unknown flag : %d\n", flag);
176 val = tmp->
value*number;
179 if (tmp->
arch != NULL) {
181 LOG(
llevError,
"Asking for buy-value of unidentified object.\n");
197 LOG(
llevDebug,
"In sell item: Have object with no archetype: %s\n", tmp->
name);
199 LOG(
llevError,
"Asking for buy-value of unidentified object without arch.\n");
200 val = number*tmp->
value*10;
202 val = number*tmp->
value/5;
224 val /= (1-tmp->
magic);
260 int lev_identify = 0;
288 if (!no_bargain && (lev_bargain > 0))
299 val = (val*(long)(1000*(1+diff)))/1000;
301 val = (val*(long)(1000*(1-diff)))/1000;
314 val = (sint64)val+(sint64)((sint64)val*(sin(tmp->
count)/sqrt(lev_bargain+lev_identify*2+1.0)));
338 else if (flag ==
F_BUY) {
368 if (who->
map->
path != NULL && val > 50)
369 val = (sint64)val+0.05*(sint64)val*cos(tmp->
count+strlen(who->
map->
path));
389 if (
coins[*cointype] == NULL)
441 cost -= (uint64)num*(uint64)coin->
clone.
value;
448 if (next_coin == NULL)
454 cost -= (uint64)num*(uint64)coin->
clone.
value;
512 uint64 real_value =
query_cost(tmp, who, flag);
586 LOG(
llevError,
"Query money called with non player/container\n");
589 for (tmp = op->
inv; tmp; tmp = tmp->
below) {
591 total += (uint64)tmp->
nrof*(uint64)tmp->
value;
594 && (tmp->
race == NULL || strstr(tmp->
race,
"gold"))) {
623 for (pouch = pl->
inv; (pouch != NULL) && (to_pay > 0); pouch = pouch->
below) {
626 && (pouch->
race == NULL || strstr(pouch->
race,
"gold"))) {
631 LOG(
llevError,
"pay_for_amount: Cannot remove enough money -- %"FMT64U
" remains\n", to_pay);
673 for (pouch = pl->
inv; (pouch != NULL) && (to_pay > 0); pouch = pouch->
below) {
676 && (pouch->
race == NULL || strstr(pouch->
race,
"gold"))) {
681 LOG(
llevError,
"pay_for_item: Cannot remove enough money -- %"FMT64U
" remains\n", to_pay);
707 if (coin_objs[i]->nrof*coin_objs[i]->value > remain) {
708 num_coins = remain/coin_objs[i]->
value;
709 if ((uint64)num_coins*(uint64)coin_objs[i]->value < remain) {
713 num_coins = coin_objs[i]->
nrof;
715 remain -= (sint64)num_coins*(sint64)coin_objs[i]->
value;
716 coin_objs[i]->
nrof -= num_coins;
722 while (remain < 0 && count >= 0) {
723 num_coins = -remain/coin_objs[count]->
value;
724 coin_objs[count]->
nrof += num_coins;
725 remain += num_coins*coin_objs[count]->
value;
741 static void add_value(
object *coin_objs[], sint64 value) {
747 nrof = (
uint32)(value/coin_objs[i]->value);
748 value -= nrof*coin_objs[i]->
value;
749 coin_objs[i]->
nrof += nrof;
768 for (i = 0; i < objects_len; i++) {
769 if (objects[i]->nrof > 0) {
799 object *tmp, *coin_objs[
NUM_COINS], *next;
800 object *other_money[16];
801 size_t other_money_len;
813 for (tmp = pouch->
inv; tmp; tmp = next) {
823 if (coin_objs[i] != NULL) {
835 if (i == NUM_COINS) {
836 if (other_money_len >=
sizeof(other_money)/
sizeof(*other_money)) {
840 other_money[other_money_len++] = tmp;
849 if (coin_objs[i] == NULL) {
855 coin_objs[i]->
nrof = 0;
862 for (i = 0; i < other_money_len && remain > 0; i++) {
866 coin = other_money[i];
872 if (nrof > coin->
nrof) {
904 static void count_unpaid(
object *
pl,
object *item,
int *unpaid_count, uint64 *unpaid_price,
uint32 *coincount) {
907 for (; item; item = item->
below) {
918 coincount[i] += item->
nrof;
939 int unpaid_count = 0, i;
940 uint64 unpaid_price = 0;
945 LOG(
llevError,
"can_pay(): called against something that isn't a player\n");
954 if (unpaid_price > player_wealth) {
956 int denominations = 0;
959 snprintf(buf,
sizeof(buf),
"You have %d unpaid items that would cost you %s, ", unpaid_count, value);
962 if (coincount[i] > 0 &&
coins[i]) {
963 if (denominations == 0)
964 snprintf(buf+strlen(buf),
sizeof(buf)-strlen(buf),
"but you only have");
967 snprintf(buf+strlen(buf),
sizeof(buf)-strlen(buf),
"%s", coinbuf);
970 if (denominations == 0)
971 snprintf(buf+strlen(buf),
sizeof(buf)-strlen(buf),
"but you don't have any money.");
972 else if (denominations > 1)
996 if (op != NULL && op->
inv)
1002 if (op != NULL && op->
below)
1017 "You lack %s to buy %s.",
1018 "You lack %s to buy %s.",
1032 "You paid %s for %s.",
1033 "You paid %s for %s.",
1062 object *tmp, *pouch;
1064 char name_op[
MAX_BUF], *value;
1067 LOG(
llevDebug,
"Object other than player tried to sell something.\n");
1078 "We're not interested in %s.",
1079 "We're not interested in %s.",
1108 for (pouch = pl->
inv; pouch; pouch = pouch->
below) {
1112 && strstr(pouch->
race,
"gold")) {
1127 i -= (uint64)tmp->
nrof*(uint64)tmp->
value;
1137 i -= (uint64)tmp->
nrof*(uint64)tmp->
value;
1146 LOG(
llevError,
"Warning - payment not zero: %llu\n", i);
1148 LOG(
llevError,
"Warning - payment not zero: %I64u\n", i);
1155 "You receive %s for %s.",
1156 "You receive %s for %s.",
1185 LOG(
llevError,
"shop_specialisation_ratio: passed a NULL item for map %s\n", map->
path);
1189 LOG(
llevError,
"shop_specialisation_ratio: passed an item with an invalid type\n");
1198 for (i = 0; i < items[0].
index; i++)
1199 if (items[i].typenum == item->
type || (!items[i].
typenum && likedness == 0.001))
1200 likedness = items[i].
strength/100.0;
1202 if (likedness > 1.0) {
1203 LOG(
llevDebug,
"shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->
type, map->
path);
1206 if (likedness < -1.0) {
1207 LOG(
llevDebug,
"shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->
type, map->
path);
1210 ratio = ratio+(1.0-ratio)*likedness;
1244 double approval = 1.0;
1273 static uint64
value_limit(uint64 val,
int quantity,
const object *who,
int isshop) {
1274 uint64 newval, unit_price;
1277 unit_price = val/quantity;
1278 if (!isshop || !who) {
1279 if (unit_price > 10000)
1280 newval = 8000+
isqrt(unit_price)*20;
1282 newval = unit_price;
1285 LOG(
llevError,
"value_limit: asked shop price for ob %s on NULL map\n", who->
name);
1289 if (map->
shopmin && unit_price < map->shopmin)
1293 else if (unit_price > 10000)
1294 newval = 8000+
isqrt(unit_price)*20;
1296 newval = unit_price;
1316 char tmp[
MAX_BUF] =
"\0", *value;
1328 "From looking at the nearby shop you determine that it trades in:",
1335 pos += strlen(tmp+pos);
1340 strcpy(tmp,
"a little of everything.");
1351 "It won't trade for items above %s.",
1352 "It won't trade for items above %s.",
1361 "It won't trade in items worth less than %s.",
1362 "It won't trade in items worth less than %s.",
1371 "It tends to overcharge massively.", NULL);
1375 "It tends to overcharge substantially.", NULL);
1379 "It tends to overcharge slightly.", NULL);
1383 "It tends to undercharge.", NULL);
1390 "You think the shopkeeper likes you.", NULL);
1391 else if (opinion > 0.5)
1394 "The shopkeeper seems unconcerned by you.", NULL);
1398 "The shopkeeper seems to have taken a dislike to you.", NULL);
1401 "There is no shop nearby.", NULL);
archetype * find_archetype(const char *name)
int get_payment(object *pl, object *op)
const char * get_ob_key_value(const object *op, const char *const key)
static const char *const coins[]
int is_in_shop(object *ob)
void change_exp(object *op, sint64 exp, const char *skill_name, int flag)
static StringBuffer * real_money_value(const object *coin, StringBuffer *buf)
static StringBuffer * cost_string_from_value(uint64 cost, StringBuffer *buf)
StringBuffer * stringbuffer_new(void)
int coords_in_shop(mapstruct *map, int x, int y)
static double shop_specialisation_ratio(const object *item, const mapstruct *map)
void esrv_update_item(int flags, object *pl, object *op)
object * merge_ob(object *op, object *top)
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
static uint64 value_limit(uint64 val, int quantity, const object *who, int isshop)
static void insert_objects(object *pl, object *container, object *objects[], int objects_len)
#define MSG_TYPE_SHOP_LISTING
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
int describe_shop(const object *op)
uint64 query_cost(const object *tmp, object *who, int flag)
const typedata * get_typedata(int itemtype)
void make_list_like(char *input)
void remove_ob(object *op)
int pay_for_item(object *op, object *pl)
void stringbuffer_append_string(StringBuffer *sb, const char *str)
#define MSG_TYPE_SHOP_MISC
StringBuffer * query_cost_string(const object *tmp, object *who, int flag, StringBuffer *buf)
void identify(object *op)
static double shop_greed(const mapstruct *map)
const float cha_bonus[MAX_STAT+1]
#define MSG_TYPE_SHOP_PAYMENT
#define FREE_AND_CLEAR_STR(xyz)
#define QUERY_FLAG(xyz, p)
#define CLEAR_FLAG(xyz, p)
#define FLAG_BEEN_APPLIED
object * insert_ob_in_ob(object *op, object *where)
static void count_unpaid(object *pl, object *item, int *unpaid_count, uint64 *unpaid_price, uint32 *coincount)
object * get_object(void)
int need_identify(const object *op)
int snprintf(char *dest, int max, const char *format,...)
double shopkeeper_approval(const mapstruct *map, const object *player)
static uint64 pay_from_container(object *pl, object *pouch, uint64 to_pay)
#define LARGEST_COIN_GIVEN
void sell_item(object *op, object *pl)
const uint32 weight_limit[MAX_STAT+1]
#define MSG_TYPE_SHOP_SELL
#define SPECIALISATION_EFFECT
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
#define GET_MAP_OB(M, X, Y)
void LOG(LogLevel logLevel, const char *format,...)
uint64 query_money(const object *op)
struct shopitem * shopitems
static archetype * find_next_coin(uint64 c, int *cointype)
void copy_object(object *op2, object *op)
void query_name(const object *op, char *buf, size_t size)
static sint64 remove_value(object *coin_objs[], sint64 remain)
object * find_skill_by_number(object *who, int skillno)
void free_object(object *ob)
void fix_object(object *op)
char * stringbuffer_finish(StringBuffer *sb)
int pay_for_amount(uint64 to_pay, object *pl)
static void add_value(object *coin_objs[], sint64 value)