ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.C
(Generate patch)

Comparing deliantra/server/server/shop.C (file contents):
Revision 1.5 by root, Tue Aug 29 07:34:00 2006 UTC vs.
Revision 1.30 by root, Wed Jan 10 19:52:43 2007 UTC

1/*
2 * static char *rcsid_shop_c =
3 * "$Id: shop.C,v 1.5 2006/08/29 07:34:00 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
11 7
12 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
21 17
22 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 21
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 22 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 23*/
28 24
29#include <global.h> 25#include <global.h>
30#include <spells.h> 26#include <spells.h>
31#include <skills.h> 27#include <skills.h>
32#include <living.h> 28#include <living.h>
33#include <newclient.h>
34#ifndef __CEXTRACT__
35#include <sproto.h> 29#include <sproto.h>
36#endif
37#include <math.h> 30#include <math.h>
38 31
39/* this is a measure of how effective store specialisation is. A general store 32/* this is a measure of how effective store specialisation is. A general store
40 * will offer this proportion of the 'maximum' price, a specialised store will 33 * will offer this proportion of the 'maximum' price, a specialised store will
41 * offer a range of prices around it such that the maximum price is always one 34 * offer a range of prices around it such that the maximum price is always one
46#define SPECIALISATION_EFFECT 0.5 39#define SPECIALISATION_EFFECT 0.5
47 40
48/* price a shopkeeper will give someone they neither like nor dislike */ 41/* price a shopkeeper will give someone they neither like nor dislike */
49#define NEUTRAL_RATIO 0.8 42#define NEUTRAL_RATIO 0.8
50 43
51static uint64 pay_from_container(object *pl, object *pouch, uint64 to_pay); 44static void pay_from_container (object *pl, object *pouch, sint64 &to_pay);
52static uint64 value_limit(uint64 val, int quantity, const object *who, int isshop); 45static sint64 value_limit (sint64 val, int quantity, const object *who, int isshop);
53static double shop_specialisation_ratio(const object *item, const mapstruct *map); 46static double shop_specialisation_ratio (const object *item, const maptile *map);
54static double shop_greed(const mapstruct *map); 47static double shop_greed (const maptile *map);
55 48
56#define NUM_COINS 4 /* number of coin types */ 49#define NUM_COINS 4 /* number of coin types */
57static const char* const coins[] = {"royalty", "platinacoin", "goldcoin", "silvercoin", NULL}; 50static const char *const coins[] = { "royalty", "platinacoin", "goldcoin", "silvercoin", NULL };
58 51
59/* Added F_TRUE flag to define.h to mean that the price should not 52/* Added F_TRUE flag to define.h to mean that the price should not
60 * be adjusted by players charisma. With F_TRUE, it returns the amount 53 * be adjusted by players charisma. With F_TRUE, it returns the amount
61 * that the item is worth, if it was sold, but unadjusted by charisma. 54 * that the item is worth, if it was sold, but unadjusted by charisma.
62 * This is needed for alchemy, to to determine what value of gold nuggets 55 * This is needed for alchemy, to to determine what value of gold nuggets
79 * thus remained 0. 72 * thus remained 0.
80 * 73 *
81 * Mark Wedel (mwedel@pyramid.com) 74 * Mark Wedel (mwedel@pyramid.com)
82 */ 75 */
83 76
84static uint64 approx_range; 77static sint64 approx_range;
85 78
79sint64
86uint64 query_cost(const object *tmp, object *who, int flag) { 80query_cost (const object *tmp, object *who, int flag)
81{
87 double val; 82 double val;
88 int number; /* used to better calculate value */ 83 int number; /* used to better calculate value */
89 int no_bargain; 84 int no_bargain;
90 int identified; 85 int identified;
91 int not_cursed; 86 int not_cursed;
92 int approximate; 87 int approximate;
93 int shop; 88 int shop;
94 double diff; 89 double diff;
95 90
96 approx_range = 0; 91 approx_range = 0;
97 92
98 no_bargain = flag & F_NO_BARGAIN; 93 no_bargain = flag & F_NO_BARGAIN;
99 identified = flag & F_IDENTIFIED; 94 identified = flag & F_IDENTIFIED;
100 not_cursed = flag & F_NOT_CURSED; 95 not_cursed = flag & F_NOT_CURSED;
101 approximate = flag & F_APPROX; 96 approximate = flag & F_APPROX;
102 shop = flag & F_SHOP; 97 shop = flag & F_SHOP;
103 flag &= ~(F_NO_BARGAIN|F_IDENTIFIED|F_NOT_CURSED|F_APPROX|F_SHOP); 98 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP);
104 99
105 if (tmp->type==MONEY) return (tmp->nrof * tmp->value); 100 if (tmp->type == MONEY)
101 return tmp->nrof * tmp->value;
102
106 if (tmp->type==GEM) { 103 if (tmp->type == GEM)
107 if (flag==F_TRUE) return (tmp->nrof * tmp->value);
108 if (flag==F_BUY) return (uint64) (1.03 * tmp->nrof * tmp->value);
109 if (flag==F_SELL) return (uint64) (0.97 * tmp->nrof * tmp->value);
110 LOG(llevError,"Query_cost: Gem type with unknown flag : %d\n", flag);
111 return 0;
112 } 104 {
105 if (flag == F_TRUE)
106 return (tmp->nrof * tmp->value);
107
108 if (flag == F_BUY)
109 return (sint64) (1.03 * tmp->nrof * tmp->value);
110
111 if (flag == F_SELL)
112 return (sint64) (0.97 * tmp->nrof * tmp->value);
113
114 LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ());
115 return 0;
116 }
117
113 number = tmp->nrof; 118 number = tmp->nrof;
114 if (number==0) number=1; 119 if (number == 0)
120 number = 1;
115 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED) || !need_identify(tmp) || identified) { 121 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified)
122 {
116 if (!not_cursed && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) 123 if (!not_cursed && (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)))
117 return 0; 124 return 0;
118 else 125 else
119 val=tmp->value * number; 126 val = tmp->value * number;
120 } 127 }
121 /* This area deals with objects that are not identified, but can be */ 128 /* This area deals with objects that are not identified, but can be */
122 else { 129 else
130 {
123 if (tmp->arch != NULL) { 131 if (tmp->arch != NULL)
132 {
124 if (flag == F_BUY) { 133 if (flag == F_BUY)
134 {
125 LOG(llevError, "Asking for buy-value of unidentified object.\n"); 135 LOG (llevError, "Asking for buy-value of unidentified object.\n");
126 val = tmp->arch->clone.value * 50 * number; 136 val = tmp->arch->clone.value * 50 * number;
127 } 137 }
128 else { /* Trying to sell something, or get true value */ 138 else
139 { /* Trying to sell something, or get true value */
129 if (tmp->type == POTION) 140 if (tmp->type == POTION)
130 val = number * 40; /* Don't want to give anything away */ 141 val = number * 40; /* Don't want to give anything away */
131 else { 142 else
143 {
132 /* Get 2/3'rd value for applied objects, 1/3'rd for totally 144 /* Get 2/3'rd value for applied objects, 1/3'rd for totally
133 * unknown objects 145 * unknown objects
134 */ 146 */
135 if (QUERY_FLAG(tmp, FLAG_BEEN_APPLIED)) 147 if (QUERY_FLAG (tmp, FLAG_BEEN_APPLIED))
136 val = number * tmp->arch->clone.value *2 / 3; 148 val = number * tmp->arch->clone.value * 2 / 3;
149 else
150 val = number * tmp->arch->clone.value / 3;
151 }
152 }
153 }
137 else 154 else
138 val = number * tmp->arch->clone.value / 3; 155 { /* No archetype with this object */
139 }
140 }
141 } else { /* No archetype with this object */
142 LOG(llevDebug,"In sell item: Have object with no archetype: %s\n", tmp->name); 156 LOG (llevDebug, "In sell item: Have object with no archetype: %s\n", &tmp->name);
143 if (flag == F_BUY) { 157 if (flag == F_BUY)
158 {
144 LOG(llevError, "Asking for buy-value of unidentified object without arch.\n"); 159 LOG (llevError, "Asking for buy-value of unidentified object without arch.\n");
145 val = number * tmp->value * 10; 160 val = number * tmp->value * 10;
161 }
162 else
163 val = number * tmp->value / 5;
164 }
146 } 165 }
147 else
148 val = number * tmp->value / 5;
149 }
150 }
151 166
152 /* If the item has been applied or identifed or does not need to be 167 /* If the item has been applied or identifed or does not need to be
153 * identified, AND the object is magical and the archetype is non 168 * identified, AND the object is magical and the archetype is non
154 * magical, then change values accordingly. The tmp->arch==NULL is 169 * magical, then change values accordingly. The tmp->arch==NULL is
155 * really just a check to prevent core dumps for when it checks 170 * really just a check to prevent core dumps for when it checks
156 * tmp->arch->clone.magic for any magic. The check for archetype 171 * tmp->arch->clone.magic for any magic. The check for archetype
157 * magic is to not give extra money for archetypes that are by 172 * magic is to not give extra money for archetypes that are by
158 * default magical. This is because the archetype value should have 173 * default magical. This is because the archetype value should have
159 * already figured in that value. 174 * already figured in that value.
160 */ 175 */
161 if((QUERY_FLAG(tmp, FLAG_IDENTIFIED)||!need_identify(tmp)||identified|| 176 if ((QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified ||
162 QUERY_FLAG(tmp, FLAG_BEEN_APPLIED)) && 177 QUERY_FLAG (tmp, FLAG_BEEN_APPLIED)) && tmp->magic && (tmp->arch == NULL || !tmp->arch->clone.magic))
163 tmp->magic&&(tmp->arch==NULL||!tmp->arch->clone.magic)) { 178 {
164 if(tmp->magic>0) 179 if (tmp->magic > 0)
165 val*=(3*tmp->magic*tmp->magic*tmp->magic); 180 val *= (3 * tmp->magic * tmp->magic * tmp->magic);
166 else 181 else
167 /* Note that tmp->magic is negative, so that this 182 /* Note that tmp->magic is negative, so that this
168 * will actually be something like val /=2, /=3, etc. 183 * will actually be something like val /=2, /=3, etc.
169 */
170 val/=(1-tmp->magic);
171 }
172
173 if (tmp->type==WAND) {
174 /* Value of the wand is multiplied by the number of
175 * charges. the treasure code already sets up the value
176 * 50 charges is used as the baseline.
177 */
178 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED) || !need_identify(tmp) || identified)
179 val=(val*tmp->stats.food) / 50;
180 else /* if not identified, presume one charge */
181 val/=50;
182 }
183
184 /* Limit amount of money you can get for really great items. */
185 if (flag==F_SELL)
186 val=value_limit((uint64)val, number, who, shop);
187
188 // use a nonlinear price adjustment. as my predecessor said, don't change
189 // the archetypes, its work required for balancing, and we don't care.
190 //val = pow (val, 1.05);
191
192 /* This modification is for bargaining skill.
193 * Now only players with max level in bargaining
194 * AND Cha = 30 will get optimal price.
195 * Thus charisma will never get useless.
196 * -b.e. edler@heydernet.de
197 */
198
199 if (who!=NULL && who->type==PLAYER) {
200 int lev_bargain = 0;
201 int lev_identify = 0;
202 int idskill1=0;
203 int idskill2=0;
204 const typedata *tmptype;
205
206 tmptype=get_typedata(tmp->type);
207
208 if (find_skill_by_number(who,SK_BARGAINING)) {
209 lev_bargain = find_skill_by_number(who,SK_BARGAINING)->level;
210 }
211 if (tmptype) {
212 idskill1=tmptype->identifyskill;
213 if (idskill1) {
214 idskill2=tmptype->identifyskill2;
215 if (find_skill_by_number(who,idskill1)) {
216 lev_identify = find_skill_by_number(who,idskill1)->level;
217 }
218 if (idskill2 && find_skill_by_number(who,idskill2)) {
219 lev_identify += find_skill_by_number(who,idskill2)->level;
220 }
221 }
222 }
223 else LOG(llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->name);
224
225 /* ratio determines how much of the price modification
226 * will come from the basic stat charisma
227 * the rest will come from the level in bargaining skill
228 */ 184 */
185 val /= (1 - tmp->magic);
186 }
187
188 if (tmp->type == WAND)
189 {
190 /* Value of the wand is multiplied by the number of
191 * charges. the treasure code already sets up the value
192 * 50 charges is used as the baseline.
193 */
194 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified)
195 val = (val * tmp->stats.food) / 50;
196 else /* if not identified, presume one charge */
197 val /= 50;
198 }
199
200 /* Limit amount of money you can get for really great items. */
201 if (flag == F_SELL)
202 val = value_limit ((sint64) val, number, who, shop);
203
204 // use a nonlinear price adjustment. as my predecessor said, don't change
205 // the archetypes, its work required for balancing, and we don't care.
206 //val = pow (val, 1.05);
207
208 /* This modification is for bargaining skill.
209 * Now only players with max level in bargaining
210 * AND Cha = 30 will get optimal price.
211 * Thus charisma will never get useless.
212 * -b.e. edler@heydernet.de
213 */
214
215 if (who != NULL && who->type == PLAYER)
216 {
217 int lev_bargain = 0;
218 int lev_identify = 0;
219 int idskill1 = 0;
220 int idskill2 = 0;
221 const typedata *tmptype;
222
223 tmptype = get_typedata (tmp->type);
224
225 if (find_skill_by_number (who, SK_BARGAINING))
226 lev_bargain = find_skill_by_number (who, SK_BARGAINING)->level;
227
228 if (tmptype)
229 {
230 idskill1 = tmptype->identifyskill;
231
232 if (idskill1)
233 {
234 idskill2 = tmptype->identifyskill2;
235
236 if (find_skill_by_number (who, idskill1))
237 lev_identify = find_skill_by_number (who, idskill1)->level;
238
239 if (idskill2 && find_skill_by_number (who, idskill2))
240 lev_identify += find_skill_by_number (who, idskill2)->level;
241 }
242 }
243 else
244 LOG (llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->debug_desc ());
245
246 /* ratio determines how much of the price modification
247 * will come from the basic stat charisma
248 * the rest will come from the level in bargaining skill
249 */
229 const double cha_ratio = 0.40; 250 const double cha_ratio = 0.40;
230 251
231 diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / (double)settings.max_level, 0.25); 252 diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / (double) settings.max_level, 0.25);
232 253
233 diff = (1. - cha_ratio) * diff
234 + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.); 254 diff = (1. - cha_ratio) * diff + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.);
235 255
236 diff = .02 + (.80 - .02) * diff; 256 diff = .02 + (.80 - .02) * diff;
237
238 if (flag == F_BUY) val += (val * diff);
239 else if (flag == F_SELL) val -= (val * diff);
240 257
258 if (flag == F_BUY)
259 val += (val * diff);
260 else if (flag == F_SELL)
261 val -= (val * diff);
262
241 // now find a price range. the less good we can judge, the larger the range is 263 // now find a price range. the less good we can judge, the larger the range is
242 // then the range is adjusted randomly around the correct value 264 // then the range is adjusted randomly around the correct value
243 if (approximate) 265 if (approximate)
244 approx_range = uint64 (val / sqrt (lev_identify * 3 + 1)); 266 approx_range = sint64 (val / sqrt (lev_identify * 3 + 1));
245 }
246 267 }
268
247 /* I don't think this should really happen - if it does, it indicates and 269 /* I don't think this should really happen - if it does, it indicates and
248 * overflow of diff above. That shoudl only happen if 270 * overflow of diff above. That shoudl only happen if
249 * we are selling objects - in that case, the person just 271 * we are selling objects - in that case, the person just
250 * gets no money. 272 * gets no money.
251 */ 273 */
252 if((sint64)val<0) 274 if ((sint64) val < 0)
253 val=0; 275 val = 0;
254 276
255 /* Unidentified stuff won't sell for more than 60gp */ 277 /* Unidentified stuff won't sell for more than 60gp */
256 if(flag==F_SELL && !QUERY_FLAG(tmp, FLAG_IDENTIFIED) && need_identify(tmp) && !identified) { 278 if (flag == F_SELL && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && need_identify (tmp) && !identified)
257 val = (val > 600)? 600:val;
258 }
259 279 {
280 val = (val > 600) ? 600 : val;
281 }
282
260 /* if we are in a shop, check how the type of shop should affect the price */ 283 /* if we are in a shop, check how the type of shop should affect the price */
261 if (shop && who) { 284 if (shop && who)
285 {
262 if (flag==F_SELL) 286 if (flag == F_SELL)
263 val= ( 287 val = (val * shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who) / shop_greed (who->map));
264 val
265 * shop_specialisation_ratio(tmp, who->map)
266 * shopkeeper_approval(who->map, who)
267 / shop_greed(who->map)
268 );
269 else if (flag==F_BUY) { 288 else if (flag == F_BUY)
270 /* 289 {
290 /*
271 * when buying, if the item was sold by another player, it is ok to 291 * when buying, if the item was sold by another player, it is ok to
272 * let the item be sold cheaper, according to the specialisation of 292 * let the item be sold cheaper, according to the specialisation of
273 * the shop. If a player sold an item here, then his sale price was 293 * the shop. If a player sold an item here, then his sale price was
274 * multiplied by the specialisation ratio, to do the same to the buy 294 * multiplied by the specialisation ratio, to do the same to the buy
275 * price will not generate extra money. However, the 295 * price will not generate extra money. However, the
276 * same is not true of generated items, these have to /divide/ by the 296 * same is not true of generated items, these have to /divide/ by the
277 * specialisation, so that the price is never less than what they could 297 * specialisation, so that the price is never less than what they could
278 * be sold for (otherwise players could camp map resets to make money). 298 * be sold for (otherwise players could camp map resets to make money).
279 * In game terms, a non-specialist shop, might not recognise the true 299 * In game terms, a non-specialist shop, might not recognise the true
280 * value of the items they sell (much like how people sometimes find 300 * value of the items they sell (much like how people sometimes find
281 * antiques in a junk shop in real life). 301 * antiques in a junk shop in real life).
282 */ 302 */
283 if (QUERY_FLAG(tmp, FLAG_PLAYER_SOLD)) 303 if (QUERY_FLAG (tmp, FLAG_PLAYER_SOLD))
284 val= ( 304 val = (val * shop_greed (who->map) * shop_specialisation_ratio (tmp, who->map) / shopkeeper_approval (who->map, who));
285 val 305 else
286 * shop_greed(who->map)
287 * shop_specialisation_ratio(tmp, who->map)
288 / shopkeeper_approval(who->map, who)
289 );
290 else
291 val= (
292 val
293 * shop_greed(who->map)
294 / (shop_specialisation_ratio(tmp, who->map)*shopkeeper_approval(who->map, who)) 306 val = (val * shop_greed (who->map) / (shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who)));
295 ); 307 }
296 }
297 /* we will also have an extra 0-5% variation between shops of the same type 308 /* we will also have an extra 0-5% variation between shops of the same type
298 * for valuable items (below a value of 50 this effect wouldn't be very 309 * for valuable items (below a value of 50 this effect wouldn't be very
299 * pointful, and could give fun with rounding. 310 * pointful, and could give fun with rounding.
300 */ 311 */
301 if(who->map->path!=NULL && val > 50) 312 if (who->map->path != NULL && val > 50)
302 val= (val+0.05*(sint64)val*cos(tmp->count+strlen(who->map->path))); 313 val = (val + 0.05 * (sint64) val * cos (tmp->count + strlen (who->map->path)));
303 } 314 }
304 return (uint64)val; 315 return (sint64) val;
305} 316}
306 317
307/* Find the coin type that is worth more the 'c'. Starts at the 318/* Find the coin type that is worth more the 'c'. Starts at the
308 * cointype placement. 319 * cointype placement.
309 */ 320 */
310 321
322static archetype *
311static archetype *find_next_coin(uint64 c, int *cointype) { 323find_next_coin (sint64 c, int *cointype)
324{
312 archetype *coin; 325 archetype *coin;
313 326
314 do { 327 do
328 {
315 if (coins[*cointype]==NULL) return NULL; 329 if (coins[*cointype] == NULL)
330 return NULL;
316 coin = find_archetype(coins[*cointype]); 331 coin = archetype::find (coins[*cointype]);
317 if (coin == NULL) 332 if (coin == NULL)
318 return NULL; 333 return NULL;
319 *cointype += 1; 334 *cointype += 1;
335 }
320 } while (coin->clone.value > c); 336 while (coin->clone.value > c);
321 337
322 return coin; 338 return coin;
323} 339}
324 340
325/* This returns a string of how much something is worth based on 341/* This returns a string of how much something is worth based on
330 * have so much money that they have more than 2 billion platinum 346 * have so much money that they have more than 2 billion platinum
331 * coins, there are certainly issues - the easiest fix at that 347 * coins, there are certainly issues - the easiest fix at that
332 * time is to add a higher denomination (mithril piece with 348 * time is to add a higher denomination (mithril piece with
333 * 10,000 silver or something) 349 * 10,000 silver or something)
334 */ 350 */
351const char *
335const char *cost_string_from_value(uint64 cost, int approx) 352cost_string_from_value (sint64 cost, int approx)
336{ 353{
337 static char buf[MAX_BUF]; 354 static char buf[MAX_BUF];
338 archetype *coin, *next_coin; 355 archetype *coin, *next_coin;
339 int num, cointype = 0; 356 int num, cointype = 0;
340 357
341 coin = find_next_coin(cost, &cointype); 358 coin = find_next_coin (cost, &cointype);
342 if (coin == NULL) 359 if (coin == NULL)
343 return "nothing"; 360 return "nothing";
344 361
345 num = cost / coin->clone.value; 362 num = cost / coin->clone.value;
346 /* so long as nrof is 32 bit, this is true. 363 /* so long as nrof is 32 bit, this is true.
347 * If it takes more coins than a person can possibly carry, this 364 * If it takes more coins than a person can possibly carry, this
348 * is basically true. 365 * is basically true.
349 */ 366 */
350 if ( (cost / coin->clone.value) > UINT32_MAX) { 367 if ((cost / coin->clone.value) > UINT32_MAX)
368 {
351 strcpy(buf,"an unimaginable sum of money"); 369 strcpy (buf, "an unimaginable sum of money");
352 return buf; 370 return buf;
353 } 371 }
354 372
355 cost -= (uint64)num * (uint64)coin->clone.value; 373 cost -= num * (sint64)coin->clone.value;
374
356 sprintf(buf, "%d %s", num, num > 1 ? coin->clone.name_pl : coin->clone.name); 375 sprintf (buf, "%d %s", num, num > 1 ? &coin->clone.name_pl : &coin->clone.name);
357 376
358 next_coin = find_next_coin(cost, &cointype); 377 next_coin = find_next_coin (cost, &cointype);
359 if (next_coin == NULL || approx) 378 if (next_coin == NULL || approx)
360 return buf;
361
362 coin = next_coin;
363 num = cost / coin->clone.value;
364 cost -= (uint64)num * (uint64)coin->clone.value;
365
366 sprintf (buf + strlen (buf), " and %d %s", num, num > 1 ? coin->clone.name_pl : coin->clone.name);
367
368 return buf; 379 return buf;
369}
370 380
381 coin = next_coin;
382 num = cost / coin->clone.value;
383 cost -= num * (sint64)coin->clone.value;
384
385 sprintf (buf + strlen (buf), " and %d %s", num, num > 1 ? &coin->clone.name_pl : &coin->clone.name);
386
387 return buf;
388}
389
390const char *
371const char *query_cost_string(const object *tmp,object *who,int flag) { 391query_cost_string (const object *tmp, object *who, int flag)
392{
372 uint64 real_value = query_cost(tmp,who,flag); 393 sint64 real_value = query_cost (tmp, who, flag);
373 int idskill1=0; 394 int idskill1 = 0;
374 int idskill2=0; 395 int idskill2 = 0;
375 const typedata *tmptype; 396 const typedata *tmptype;
376 397
377 tmptype=get_typedata(tmp->type); 398 tmptype = get_typedata (tmp->type);
378 if (tmptype) { 399 if (tmptype)
400 {
379 idskill1=tmptype->identifyskill; 401 idskill1 = tmptype->identifyskill;
380 idskill2=tmptype->identifyskill2; 402 idskill2 = tmptype->identifyskill2;
381 } 403 }
382 404
383 /* we show an approximate price if 405 /* we show an approximate price if
384 * 1) we are approximating 406 * 1) we are approximating
385 * 2) there either is no id skill(s) for the item, or we don't have them 407 * 2) there either is no id skill(s) for the item, or we don't have them
386 * 3) we don't have bargaining skill either 408 * 3) we don't have bargaining skill either
387 */ 409 */
388 if (flag & F_APPROX) { 410 if (flag & F_APPROX)
411 {
389 if (!idskill1 || !find_skill_by_number(who, idskill1)) { 412 if (!idskill1 || !find_skill_by_number (who, idskill1))
413 {
390 if (!idskill2 || !find_skill_by_number(who, idskill2)) { 414 if (!idskill2 || !find_skill_by_number (who, idskill2))
415 {
391 if (!find_skill_by_number(who,SK_BARGAINING)) { 416 if (!find_skill_by_number (who, SK_BARGAINING))
417 {
392 static char buf[MAX_BUF]; 418 static char buf[MAX_BUF];
393 int num, cointype = 0; 419 int num, cointype = 0;
394 archetype *coin = find_next_coin(real_value, &cointype); 420 archetype *coin = find_next_coin (real_value, &cointype);
395 421
396 if (coin == NULL) return "nothing"; 422 if (coin == NULL)
397 423 return "nothing";
424
398 num = real_value / coin->clone.value; 425 num = real_value / coin->clone.value;
399 if (num == 1) 426 if (num == 1)
400 sprintf(buf, "about one %s", coin->clone.name); 427 sprintf (buf, "about one %s", &coin->clone.name);
401 else if (num < 5) 428 else if (num < 5)
402 sprintf(buf, "a few %s", coin->clone.name_pl); 429 sprintf (buf, "a few %s", &coin->clone.name_pl);
403 else if (num < 10) 430 else if (num < 10)
404 sprintf(buf, "several %s", coin->clone.name_pl); 431 sprintf (buf, "several %s", &coin->clone.name_pl);
405 else if (num < 25) 432 else if (num < 25)
406 sprintf(buf, "a moderate amount of %s", coin->clone.name_pl); 433 sprintf (buf, "a moderate amount of %s", &coin->clone.name_pl);
407 else if (num < 100) 434 else if (num < 100)
408 sprintf(buf, "lots of %s", coin->clone.name_pl); 435 sprintf (buf, "lots of %s", &coin->clone.name_pl);
409 else if (num < 1000) 436 else if (num < 1000)
410 sprintf(buf, "a great many %s", coin->clone.name_pl); 437 sprintf (buf, "a great many %s", &coin->clone.name_pl);
411 else 438 else
412 sprintf(buf, "a vast quantity of %s", coin->clone.name_pl); 439 sprintf (buf, "a vast quantity of %s", &coin->clone.name_pl);
413 return buf; 440 return buf;
441 }
442 }
414 } 443 }
415 }
416 }
417 444
418 int hash = ((unsigned int)tmp->count * 174364621) & 1023; 445 int hash = ((unsigned int) tmp->count * 174364621) & 1023;
419 446
420 if (approx_range) 447 if (approx_range)
421 { 448 {
422 uint64 lo = (sint64)real_value - (approx_range * hash >> 10); 449 sint64 lo = (sint64) real_value - (approx_range * hash >> 10);
423 static char buf[MAX_BUF]; 450 static char buf[MAX_BUF];
424 451
425 sprintf (buf, "between %s", cost_string_from_value (lo, 1)); 452 sprintf (buf, "between %s", cost_string_from_value (lo, 1));
426 sprintf (buf + strlen (buf), " and %s", cost_string_from_value (lo + approx_range, 1)); 453 sprintf (buf + strlen (buf), " and %s", cost_string_from_value (lo + approx_range, 1));
427 454
428 return buf; 455 return buf;
429 } 456 }
430 } 457 }
431 458
432 return cost_string_from_value (real_value, 0); 459 return cost_string_from_value (real_value, 0);
433} 460}
434 461
435/* This function finds out how much money the player is carrying, 462/* This function finds out how much money the player is carrying,
436 * including what is in containers. 463 * including what is in containers.
437 */ 464 */
465sint64
438uint64 query_money(const object *op) { 466query_money (const object *op)
467{
439 object *tmp; 468 object *tmp;
440 uint64 total=0; 469 sint64 total = 0;
441 470
442 if (op->type!=PLAYER && op->type!=CONTAINER) { 471 if (op->type != PLAYER && op->type != CONTAINER)
472 {
443 LOG(llevError, "Query money called with non player/container\n"); 473 LOG (llevError, "Query money called with non player/container\n");
444 return 0; 474 return 0;
445 } 475 }
476
446 for (tmp = op->inv; tmp; tmp= tmp->below) { 477 for (tmp = op->inv; tmp; tmp = tmp->below)
447 if (tmp->type==MONEY) { 478 if (tmp->type == MONEY)
448 total += (uint64)tmp->nrof * (uint64)tmp->value; 479 total += tmp->nrof * (sint64)tmp->value;
449 } else if (tmp->type==CONTAINER && 480 else if (tmp->type == CONTAINER && QUERY_FLAG (tmp, FLAG_APPLIED) && (tmp->race == NULL || strstr (tmp->race, "gold")))
450 QUERY_FLAG(tmp,FLAG_APPLIED) &&
451 (tmp->race==NULL || strstr(tmp->race,"gold"))) {
452 total += query_money(tmp); 481 total += query_money (tmp);
453 } 482
454 }
455 return total; 483 return total;
456} 484}
485
457/* TCHIZE: This function takes the amount of money from the 486/* TCHIZE: This function takes the amount of money from the
458 * the player inventory and from it's various pouches using the 487 * the player inventory and from it's various pouches using the
459 * pay_from_container function. 488 * pay_from_container function.
460 * returns 0 if not possible. 1 if success 489 * returns 0 if not possible. 1 if success
461 */ 490 */
491int
462int pay_for_amount(uint64 to_pay,object *pl) { 492pay_for_amount (sint64 to_pay, object *pl)
493{
463 object *pouch; 494 object *pouch;
464 495
465 if (to_pay==0) return 1; 496 if (to_pay == 0)
466 if (to_pay > query_money(pl)) return 0;
467
468 to_pay = pay_from_container(pl, pl, to_pay);
469
470 for (pouch=pl->inv; (pouch!=NULL) && (to_pay>0); pouch=pouch->below) {
471 if (pouch->type == CONTAINER
472 && QUERY_FLAG(pouch, FLAG_APPLIED)
473 && (pouch->race == NULL || strstr(pouch->race, "gold"))) {
474 to_pay = pay_from_container(pl, pouch, to_pay);
475 }
476 }
477 fix_player(pl);
478 return 1; 497 return 1;
498
499 if (to_pay > query_money (pl))
500 return 0;
501
502 pay_from_container (pl, pl, to_pay);
503
504 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
505 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr (pouch->race, "gold")))
506 pay_from_container (pl, pouch, to_pay);
507
508 pl->update_stats ();
509 return 1;
479} 510}
480 511
481/* DAMN: This is now a wrapper for pay_from_container, which is 512/* DAMN: This is now a wrapper for pay_from_container, which is
482 * called for the player, then for each active container that can hold 513 * called for the player, then for each active container that can hold
483 * money until op is paid for. Change will be left wherever the last 514 * money until op is paid for. Change will be left wherever the last
484 * of the price was paid from. 515 * of the price was paid from.
485 */ 516 */
517int
486int pay_for_item(object *op,object *pl) { 518pay_for_item (object *op, object *pl)
519{
487 uint64 to_pay = query_cost(op,pl,F_BUY | F_SHOP); 520 sint64 to_pay = query_cost (op, pl, F_BUY | F_SHOP);
488 object *pouch; 521 object *pouch;
489 uint64 saved_money; 522 sint64 saved_money;
490 523
491 if (to_pay==0) return 1; 524 if (to_pay == 0)
492 if (to_pay>query_money(pl)) return 0;
493
494 /* We compare the paid price with the one for a player
495 * without bargaining skill.
496 * This determins the amount of exp (if any) gained for bargaining.
497 */
498 saved_money = query_cost(op,pl,F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay;
499
500 if (saved_money > 0)
501 change_exp(pl,saved_money,"bargaining",SK_EXP_NONE);
502
503 to_pay = pay_from_container(pl, pl, to_pay);
504
505 for (pouch=pl->inv; (pouch!=NULL) && (to_pay>0); pouch=pouch->below) {
506 if (pouch->type == CONTAINER
507 && QUERY_FLAG(pouch, FLAG_APPLIED)
508 && (pouch->race == NULL || strstr(pouch->race, "gold"))) {
509 to_pay = pay_from_container(pl, pouch, to_pay);
510 }
511 }
512 if (settings.real_wiz == FALSE && QUERY_FLAG(pl, FLAG_WAS_WIZ))
513 SET_FLAG(op, FLAG_WAS_WIZ);
514 fix_player(pl);
515 return 1; 525 return 1;
526
527 if (to_pay > query_money (pl))
528 return 0;
529
530 /* We compare the paid price with the one for a player
531 * without bargaining skill.
532 * This determins the amount of exp (if any) gained for bargaining.
533 */
534 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay;
535
536 if (saved_money > 0)
537 change_exp (pl, saved_money, "bargaining", SK_EXP_NONE);
538
539 pay_from_container (pl, pl, to_pay);
540
541 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
542 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr (pouch->race, "gold")))
543 pay_from_container (pl, pouch, to_pay);
544
545 if (settings.real_wiz == FALSE && QUERY_FLAG (pl, FLAG_WAS_WIZ))
546 SET_FLAG (op, FLAG_WAS_WIZ);
547
548 pl->update_stats ();
549 return 1;
516} 550}
517 551
518/* This pays for the item, and takes the proper amount of money off 552/* This pays for the item, and takes the proper amount of money off
519 * the player. 553 * the player.
520 * CF 0.91.4 - this function is mostly redone in order to fix a bug 554 * CF 0.91.4 - this function is mostly redone in order to fix a bug
527 * 561 *
528 * pouch is the container (pouch or player) to remove the coins from. 562 * pouch is the container (pouch or player) to remove the coins from.
529 * to_pay is the required amount. 563 * to_pay is the required amount.
530 * returns the amount still missing after using "pouch". 564 * returns the amount still missing after using "pouch".
531 */ 565 */
566static void
532static uint64 pay_from_container(object *pl, object *pouch, uint64 to_pay) { 567pay_from_container (object *pl, object *pouch, sint64 &to_pay)
568{
533 int count, i; 569 int count, i;
534 sint64 remain; 570 object *tmp, *next;
535 object *tmp, *coin_objs[NUM_COINS], *next;
536 archetype *at; 571 archetype *at;
537 572
538 if (pouch->type != PLAYER && pouch->type != CONTAINER) return to_pay; 573 if (pouch->type != PLAYER && pouch->type != CONTAINER)
574 return;
539 575
540 remain = to_pay; 576 object *coin_objs[NUM_COINS] = { 0 };
541 for (i=0; i<NUM_COINS; i++) coin_objs[i] = NULL;
542 577
543 /* This hunk should remove all the money objects from the player/container */ 578 /* This hunk should remove all the money objects from the player/container */
544 for (tmp=pouch->inv; tmp; tmp=next) { 579 for (tmp = pouch->inv; tmp; tmp = next)
580 {
545 next = tmp->below; 581 next = tmp->below;
546 582
547 if (tmp->type == MONEY) { 583 if (tmp->type == MONEY)
584 {
548 for (i=0; i<NUM_COINS; i++) { 585 for (i = 0; i < NUM_COINS; i++)
549 if (!strcmp(coins[NUM_COINS-1-i], tmp->arch->name) && 586 {
550 (tmp->value == tmp->arch->clone.value) ) { 587 if (tmp->value == tmp->arch->clone.value && !strcmp (coins[NUM_COINS - 1 - i], tmp->arch->name))
588 {
589 // This should not happen, but if it does, just merge the two.
590 if (coin_objs [i])
591 {
592 LOG (llevError, "%s has two money entries of (%s)\n", &pouch->name, coins[NUM_COINS - 1 - i]);
593 tmp->remove ();
594 coin_objs[i]->nrof += tmp->nrof;
595 esrv_del_item (pl->contr, tmp->count);
596 tmp->destroy ();
597 }
598 else
599 {
600 tmp->remove ();
551 601
552 /* This should not happen, but if it does, just * 602 if (pouch->type == PLAYER)
553 * merge the two. */ 603 esrv_del_item (pl->contr, tmp->count);
554 if (coin_objs[i]!=NULL) { 604
555 LOG(llevError,"%s has two money entries of (%s)\n", 605 coin_objs[i] = tmp;
556 pouch->name, coins[NUM_COINS-1-i]); 606 }
557 remove_ob(tmp); 607
558 coin_objs[i]->nrof += tmp->nrof; 608 break;
559 esrv_del_item(pl->contr, tmp->count); 609 }
560 free_object(tmp); 610 }
561 } 611
562 else {
563 remove_ob(tmp);
564 if(pouch->type==PLAYER) esrv_del_item(pl->contr, tmp->count);
565 coin_objs[i] = tmp;
566 }
567 break;
568 }
569 }
570 if (i==NUM_COINS) 612 if (i == NUM_COINS)
571 LOG(llevError,"in pay_for_item: Did not find string match for %s\n", tmp->arch->name); 613 LOG (llevError, "in pay_for_item: Did not find string match for %s\n", &tmp->arch->name);
572 } 614 }
573 } 615 }
574 616
575 /* Fill in any gaps in the coin_objs array - needed to make change. */ 617 /* Fill in any gaps in the coin_objs array - needed to make change. */
576 /* Note that the coin_objs array goes from least value to greatest value */ 618 /* Note that the coin_objs array goes from least value to greatest value */
577 for (i=0; i<NUM_COINS; i++) 619 for (i = 0; i < NUM_COINS; i++)
578 if (coin_objs[i]==NULL) { 620 if (!coin_objs[i])
621 {
579 at = find_archetype(coins[NUM_COINS-1-i]); 622 at = archetype::find (coins[NUM_COINS - 1 - i]);
623
624 if (at == NULL)
580 if (at==NULL) LOG(llevError, "Could not find %s archetype\n", coins[NUM_COINS-1-i]); 625 LOG (llevError, "Could not find %s archetype\n", coins[NUM_COINS - 1 - i]);
626
581 coin_objs[i] = arch_to_object (at); 627 coin_objs[i] = arch_to_object (at);
582 coin_objs[i]->nrof = 0; 628 coin_objs[i]->nrof = 0;
583 } 629 }
584 630
585 for (i=0; i<NUM_COINS; i++) { 631 for (i = 0; i < NUM_COINS; i++)
586 int num_coins; 632 {
633 object &coin = *coin_objs[i];
634 sint64 num_coins = min ((to_pay + coin.value - 1) / coin.value, coin.nrof);
635 to_pay -= num_coins * coin.value;
587 636
588 if (coin_objs[i]->nrof*coin_objs[i]->value> remain) { 637 coin.nrof -= num_coins;
589 num_coins = remain / coin_objs[i]->value;
590 if ((uint64)num_coins*(uint64)coin_objs[i]->value < remain) num_coins++;
591 } else {
592 num_coins = coin_objs[i]->nrof;
593 }
594 remain -= (sint64) num_coins * (sint64)coin_objs[i]->value;
595 coin_objs[i]->nrof -= num_coins;
596 /* Now start making change. Start at the coin value 638 /* Now start making change. Start at the coin value
597 * below the one we just did, and work down to 639 * below the one we just did, and work down to
598 * the lowest value. 640 * the lowest value.
599 */ 641 */
600 count=i-1; 642 count = i - 1;
601 while (remain<0 && count>=0) { 643
644 while (to_pay < 0 && count >= 0)
645 {
602 num_coins = -remain/ coin_objs[count]->value; 646 num_coins = (-to_pay) / coin_objs[count]->value;
603 coin_objs[count]->nrof += num_coins; 647 coin_objs[count]->nrof += num_coins;
604 remain += num_coins * coin_objs[count]->value; 648 to_pay += num_coins * coin_objs[count]->value;
605 count--; 649 count--;
606 } 650 }
607 } 651 }
652
608 for (i=0; i<NUM_COINS; i++) { 653 for (i = 0; i < NUM_COINS; i++)
654 {
609 if (coin_objs[i]->nrof) { 655 if (coin_objs[i]->nrof)
656 {
610 object *tmp = insert_ob_in_ob(coin_objs[i], pouch); 657 object *tmp = insert_ob_in_ob (coin_objs[i], pouch);
611 658
612 esrv_send_item(pl, tmp); 659 esrv_send_item (pl, tmp);
613 esrv_send_item (pl, pouch); 660 esrv_send_item (pl, pouch);
614 if (pl != pouch) esrv_update_item (UPD_WEIGHT, pl, pouch); 661
662 if (pl != pouch)
663 esrv_update_item (UPD_WEIGHT, pl, pouch);
664
615 if (pl->type != PLAYER) { 665 if (pl->type != PLAYER)
616 esrv_send_item (pl, pl); 666 esrv_send_item (pl, pl);
667 }
668 else
669 coin_objs[i]->destroy ();
617 } 670 }
618 } else {
619 free_object(coin_objs[i]);
620 }
621 }
622 return(remain);
623} 671}
624 672
625/* Checks all unpaid items in op's inventory, adds up all the money they 673/* Checks all unpaid items in op's inventory, adds up all the money they
626 * have, and checks that they can actually afford what they want to buy. 674 * have, and checks that they can actually afford what they want to buy.
627 * Returns 1 if they can, and 0 if they can't. also prints an appropriate message 675 * Returns 1 if they can, and 0 if they can't. also prints an appropriate message
628 * to the player 676 * to the player
629 */ 677 */
630 678int
631int can_pay(object *pl) { 679can_pay (object *pl)
680{
632 int unpaid_count = 0, i; 681 int unpaid_count = 0;
633 uint64 unpaid_price = 0; 682 sint64 unpaid_price = 0;
634 uint64 player_wealth = query_money(pl); 683 sint64 player_wealth = query_money (pl);
635 object *item; 684
636 uint32 coincount[NUM_COINS];
637 if (!pl || pl->type != PLAYER) { 685 if (!pl || pl->type != PLAYER)
686 {
638 LOG(llevError, "can_pay(): called against something that isn't a player\n"); 687 LOG (llevError, "can_pay(): called against something that isn't a player\n");
639 return 0; 688 return 0;
640 } 689 }
641 for (i=0; i< NUM_COINS; i++) coincount[i] = 0; 690
642 for (item = pl->inv;item;) { 691 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item)
643 if QUERY_FLAG(item, FLAG_UNPAID) { 692 if (QUERY_FLAG (item, FLAG_UNPAID))
693 {
644 unpaid_count++; 694 unpaid_count++;
645 unpaid_price += query_cost(item, pl, F_BUY | F_SHOP); 695 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP);
646 }
647 /* merely converting the player's monetary wealth won't do, if we did that,
648 * we could print the wrong numbers for the coins, so we count the money instead
649 */
650 for (i=0; i< NUM_COINS; i++)
651 if (!strcmp(coins[i], item->arch->name))
652 coincount[i] += item->nrof;
653 if (item->inv) item = item->inv;
654 else if (item->below) item = item->below;
655 else if (item->env && item->env != pl && item->env->below) item = item->env->below;
656 else item = NULL;
657 } 696 }
697
658 if (unpaid_price > player_wealth) { 698 if (unpaid_price > player_wealth)
659 char buf[MAX_BUF], coinbuf[MAX_BUF]; 699 {
660 int denominations = 0; 700 char buf[MAX_BUF];
661 int has_coins = NUM_COINS;
662 char cost[MAX_BUF]; 701 char cost[MAX_BUF];
663 char missing[MAX_BUF]; 702 char missing[MAX_BUF];
664 703
665 sprintf(cost, "%s", cost_string_from_value (unpaid_price, 0)); 704 snprintf (cost, MAX_BUF, "%s", cost_string_from_value (unpaid_price, 0));
666 sprintf(missing, "%s", cost_string_from_value (unpaid_price - player_wealth, 0)); 705 snprintf (missing, MAX_BUF, "%s", cost_string_from_value (unpaid_price - player_wealth, 0));
667 706
668 sprintf(buf, "You have %d unpaid items that would cost you %s. You need another %s to be able to afford that.", 707 snprintf (buf, MAX_BUF, "You have %d unpaid items that would cost you %s. You need another %s to be able to afford that.",
669 unpaid_count, cost, missing); 708 unpaid_count, cost, missing);
670 new_draw_info(NDI_UNIQUE, 0, pl, buf); 709 new_draw_info (NDI_UNIQUE, 0, pl, buf);
671 return 0; 710
711 return 0;
672 } 712 }
713 else
673 else return 1; 714 return 1;
674} 715}
675
676 716
677/* Better get_payment, descends containers looking for 717/* Better get_payment, descends containers looking for
678 * unpaid items, and pays for them. 718 * unpaid items, and pays for them.
679 * returns 0 if the player still has unpaid items. 719 * returns 0 if the player still has unpaid items.
680 * returns 1 if the player has paid for everything. 720 * returns 1 if the player has paid for everything.
681 * pl is the player buying the stuff. 721 * pl is the player buying the stuff.
682 * op is the object we are examining. If op has
683 * and inventory, we examine that. IF there are objects
684 * below op, we descend down.
685 */ 722 */
686int get_payment(object *pl, object *op) { 723int
724get_payment (object *pl)
725{
726 for (;;)
727 {
728 next_item:
729
730 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op)
731 {
732 if (QUERY_FLAG (op, FLAG_UNPAID))
733 {
687 char buf[MAX_BUF]; 734 char buf[MAX_BUF];
688 int ret=1; 735 snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP));
689 736
690 if (op!=NULL&&op->inv)
691 ret = get_payment(pl, op->inv);
692
693 if (!ret)
694 return 0;
695
696 if (op!=NULL&&op->below)
697 ret = get_payment (pl, op->below);
698
699 if (!ret)
700 return 0;
701
702 if(op!=NULL&&QUERY_FLAG(op,FLAG_UNPAID)) {
703 strncpy(buf,query_cost_string(op,pl,F_BUY | F_SHOP),MAX_BUF);
704 buf[MAX_BUF-1] = '\0';
705 if(!pay_for_item(op,pl)) { 737 if (!pay_for_item (op, pl))
738 {
706 uint64 i=query_cost(op,pl,F_BUY | F_SHOP) - query_money(pl); 739 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl);
740
707 CLEAR_FLAG(op, FLAG_UNPAID); 741 CLEAR_FLAG (op, FLAG_UNPAID);
708 new_draw_info_format(NDI_UNIQUE, 0, pl, 742 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op));
709 "You lack %s to buy %s.", cost_string_from_value (i, 0),
710 query_name(op));
711 SET_FLAG(op, FLAG_UNPAID); 743 SET_FLAG (op, FLAG_UNPAID);
712 return 0; 744 return 0;
745 }
713 } else { 746 else
714 object *tmp; 747 {
715 tag_t c = op->count; 748 object *tmp;
716 749
717 CLEAR_FLAG(op, FLAG_UNPAID); 750 CLEAR_FLAG (op, FLAG_UNPAID);
718 CLEAR_FLAG(op, FLAG_PLAYER_SOLD); 751 CLEAR_FLAG (op, FLAG_PLAYER_SOLD);
719 new_draw_info_format(NDI_UNIQUE, 0, op, 752 new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op));
720 "You paid %s for %s.",buf,query_name(op)); 753 tmp = merge_ob (op, NULL);
721 tmp=merge_ob(op,NULL); 754
722 if (pl->type == PLAYER) { 755 if (pl->type == PLAYER)
723 if (tmp) { /* it was merged */ 756 {
724 esrv_del_item (pl->contr, c); 757 if (tmp)
725 op = tmp; 758 { /* it was merged */
726 } 759 esrv_del_item (pl->contr, op->count);
760 op = tmp;
761 }
762
727 esrv_send_item(pl, op); 763 esrv_send_item (pl, op);
728 } 764 }
729 } 765
730 } 766 goto next_item;
767 }
768 }
769 }
770
731 return 1; 771 return 1;
772 }
732} 773}
733 774
734/* written by elmex: 775/* written by elmex:
735 * moved this code from sell_item () here to have a function 776 * moved this code from sell_item () here to have a function
736 * that pays the player an amount. Mainly put the code here to 777 * that pays the player an amount. Mainly put the code here to
740 * in his inventory anyway. This is the best alternative to not pay any money 781 * in his inventory anyway. This is the best alternative to not pay any money
741 * or put it on the ground under the player. This way the player can still 782 * or put it on the ground under the player. This way the player can still
742 * go somewhere and unload the money at a safe place. 783 * go somewhere and unload the money at a safe place.
743 * 784 *
744 */ 785 */
786void
745void pay_player (object *pl, uint64 amount) { 787pay_player (object *pl, sint64 amount)
788{
746 int count = 0; 789 int count = 0;
747 archetype *at = 0; 790 archetype *at = 0;
748 object *pouch = 0, *tmp = 0; 791 object *pouch = 0, *tmp = 0;
749 792
750 for (count = 0; coins[count] != NULL; count++) 793 for (count = 0; coins[count] != NULL; count++)
751 { 794 {
752 at = find_archetype (coins[count]); 795 at = archetype::find (coins[count]);
753 796
754 if (at == NULL) 797 if (at == NULL)
755 LOG(llevError, "Could not find %s archetype\n", coins[count]); 798 LOG (llevError, "Could not find %s archetype\n", coins[count]);
756 else if ((amount / at->clone.value) > 0) 799 else if ((amount / at->clone.value) > 0)
757 { 800 {
758 for (pouch=pl->inv; pouch; pouch=pouch->below) 801 for (pouch = pl->inv; pouch; pouch = pouch->below)
759 { 802 {
760 if (pouch->type == CONTAINER 803 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && pouch->race && strstr (pouch->race, "gold"))
761 && QUERY_FLAG (pouch, FLAG_APPLIED)
762 && pouch->race
763 && strstr (pouch->race, "gold"))
764 { 804 {
765 int w = at->clone.weight * (100 - pouch->stats.Str) / 100; 805 int w = at->clone.weight * (100 - pouch->stats.Str) / 100;
766 int n = amount / at->clone.value; 806 int n = amount / at->clone.value;
767 807
768 if (w == 0) 808 if (w == 0)
769 w = 1; /* Prevent divide by zero */ 809 w = 1; /* Prevent divide by zero */
770 810
771 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit)) 811 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit))
772 { 812 {
773 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n) 813 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n)
774 n = (pouch->weight_limit - pouch->carrying) / w; 814 n = (pouch->weight_limit - pouch->carrying) / w;
775 815
776 tmp = arch_to_object (at); 816 tmp = arch_to_object (at);
777 tmp->nrof = n; 817 tmp->nrof = n;
778 amount -= (uint64)tmp->nrof * (uint64)tmp->value; 818 amount -= tmp->nrof * tmp->value;
779 tmp = insert_ob_in_ob (tmp, pouch); 819 tmp = insert_ob_in_ob (tmp, pouch);
780 esrv_send_item (pl, tmp); 820 esrv_send_item (pl, tmp);
781 esrv_send_item (pl, pouch); 821 esrv_send_item (pl, pouch);
782 esrv_update_item (UPD_WEIGHT, pl, pouch); 822 esrv_update_item (UPD_WEIGHT, pl, pouch);
783 esrv_send_item (pl, pl); 823 esrv_send_item (pl, pl);
787 827
788 if (amount / at->clone.value > 0) 828 if (amount / at->clone.value > 0)
789 { 829 {
790 tmp = arch_to_object (at); 830 tmp = arch_to_object (at);
791 tmp->nrof = amount / tmp->value; 831 tmp->nrof = amount / tmp->value;
792 amount -= (uint64)tmp->nrof * (uint64)tmp->value; 832 amount -= tmp->nrof * tmp->value;
793 tmp = insert_ob_in_ob (tmp, pl); 833 tmp = insert_ob_in_ob (tmp, pl);
794 esrv_send_item (pl, tmp); 834 esrv_send_item (pl, tmp);
795 esrv_send_item (pl, pl); 835 esrv_send_item (pl, pl);
796 } 836 }
797 } 837 }
798 } 838 }
799 839
800 if (amount != 0) 840 if (amount != 0)
801#ifndef WIN32
802 LOG (llevError,"Warning - payment in pay_player () not zero: %llu\n", amount); 841 LOG (llevError, "Warning - payment in pay_player () not zero: %llu\n", amount);
803#else
804 LOG (llevError,"Warning - payment in pay_player () not zero: %I64u\n", amount);
805#endif
806} 842}
807 843
808/* elmex: this is for the bank plugin :( */ 844/* elmex: this is for the bank plugin :( */
845sint64
809uint64 pay_player_arch (object *pl, const char *arch, uint64 amount) { 846pay_player_arch (object *pl, const char *arch, sint64 amount)
847{
810 archetype *at = find_archetype (arch); 848 archetype *at = archetype::find (arch);
811 object *tmp = NULL; 849 object *tmp = NULL;
812 850
813 if (at == NULL) 851 if (at == NULL)
814 return 0; 852 return 0;
815 853
830 * buy item. 868 * buy item.
831 * 869 *
832 * Modified to fill available race: gold containers before dumping 870 * Modified to fill available race: gold containers before dumping
833 * remaining coins in character's inventory. 871 * remaining coins in character's inventory.
834 */ 872 */
873void
835void sell_item(object *op, object *pl) { 874sell_item (object *op, object *pl)
875{
836 uint64 amount = query_cost (op,pl,F_SELL | F_SHOP), extra_gain; 876 sint64 amount = query_cost (op, pl, F_SELL | F_SHOP), extra_gain;
837 877
838 if(pl==NULL || pl->type != PLAYER) 878 if (pl == NULL || pl->type != PLAYER)
839 { 879 {
840 LOG(llevDebug,"Object other than player tried to sell something.\n"); 880 LOG (llevDebug, "Object other than player tried to sell something.\n");
841 return; 881 return;
842 } 882 }
843 883
844 if(op->custom_name) 884 op->custom_name = 0;
845 FREE_AND_CLEAR_STR (op->custom_name);
846 885
847 if(!amount) 886 if (!amount)
848 { 887 {
849 new_draw_info_format (NDI_UNIQUE, 0, pl, 888 new_draw_info_format (NDI_UNIQUE, 0, pl, "We're not interested in %s.", query_name (op));
850 "We're not interested in %s.", query_name (op));
851 889
852 /* Even if the character doesn't get anything for it, it may still be 890 /* Even if the character doesn't get anything for it, it may still be
853 * worth something. If so, make it unpaid 891 * worth something. If so, make it unpaid
854 */ 892 */
855 if (op->value) 893 if (op->value)
856 { 894 {
857 SET_FLAG(op, FLAG_UNPAID); 895 SET_FLAG (op, FLAG_UNPAID);
858 SET_FLAG(op, FLAG_PLAYER_SOLD); 896 SET_FLAG (op, FLAG_PLAYER_SOLD);
859 } 897 }
860 898
861 identify (op); 899 identify (op);
862 return; 900 return;
863 } 901 }
868 * exp/10 -> 1 for each gold coin 906 * exp/10 -> 1 for each gold coin
869 */ 907 */
870 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP); 908 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP);
871 909
872 if (extra_gain > 0) 910 if (extra_gain > 0)
873 change_exp(pl, extra_gain / 10, "bargaining", SK_EXP_NONE); 911 change_exp (pl, extra_gain / 10, "bargaining", SK_EXP_NONE);
874 912
875 pay_player (pl, amount); 913 pay_player (pl, amount);
876 914
877 new_draw_info_format (NDI_UNIQUE, 0, pl, 915 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.", query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op));
878 "You receive %s for %s.", query_cost_string (op, pl, F_SELL | F_SHOP),
879 query_name (op));
880 916
881 SET_FLAG (op, FLAG_UNPAID); 917 SET_FLAG (op, FLAG_UNPAID);
882 identify (op); 918 identify (op);
883} 919}
884 920
886/* returns a double that is the ratio of the price that a shop will offer for 922/* returns a double that is the ratio of the price that a shop will offer for
887 * item based on the shops specialisation. Does not take account of greed, 923 * item based on the shops specialisation. Does not take account of greed,
888 * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any 924 * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any
889 * event is never less than 0.1 (calling functions divide by it) 925 * event is never less than 0.1 (calling functions divide by it)
890 */ 926 */
927static double
891static double shop_specialisation_ratio(const object *item, const mapstruct *map) { 928shop_specialisation_ratio (const object *item, const maptile *map)
929{
892 shopitems *items=map->shopitems; 930 shopitems *items = map->shopitems;
893 double ratio = SPECIALISATION_EFFECT, likedness=0.001; 931 double ratio = SPECIALISATION_EFFECT, likedness = 0.001;
894 int i; 932 int i;
895 933
896 if (item==NULL) { 934 if (item == NULL)
935 {
897 LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path); 936 LOG (llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", &map->path);
898 return 0; 937 return 0;
899 } 938 }
939
900 if (!item->type) { 940 if (!item->type)
941 {
901 LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type\n"); 942 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
902 /* 943 /*
903 * I'm not really sure what the /right/ thing to do here is, these types of 944 * I'm not really sure what the /right/ thing to do here is, these types of
904 * item shouldn't exist anyway, but returning the ratio is probably the best bet.." 945 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
905 */ 946 */
906 return ratio; 947 return ratio;
907 } 948 }
949
908 if (map->shopitems) { 950 if (map->shopitems)
951 {
909 for (i=0; i<items[0].index; i++) 952 for (i = 0; i < items[0].index; i++)
910 if (items[i].typenum==item->type || (!items[i].typenum && likedness == 0.001)) 953 if (items[i].typenum == item->type || (!items[i].typenum && likedness == 0.001))
911 likedness = items[i].strength/100.0; 954 likedness = items[i].strength / 100.0;
912 } 955 }
913 if (likedness > 1.0) { /* someone has been rather silly with the map headers. */ 956
957 if (likedness > 1.0)
958 { /* someone has been rather silly with the map headers. */
914 LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", 959 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, &map->path);
915 item->type, map->path);
916 likedness = 1.0; 960 likedness = 1.0;
917 } 961 }
962
918 if (likedness < -1.0) { 963 if (likedness < -1.0)
964 {
919 LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", 965 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, &map->path);
920 item->type, map->path);
921 likedness = -1.0; 966 likedness = -1.0;
922 } 967 }
968
923 ratio = ratio + (1.0-ratio) * likedness; 969 ratio = ratio + (1.0 - ratio) * likedness;
924 if (ratio <= 0.1) ratio=0.1; /* if the ratio were much lower than this, we would get silly prices */ 970
971 if (ratio <= 0.1)
972 ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */
973
925 return ratio; 974 return ratio;
926} 975}
927 976
928/*returns the greed of the shop on map, or 1 if it isn't specified. */ 977/*returns the greed of the shop on map, or 1 if it isn't specified. */
929static double shop_greed(const mapstruct *map) { 978static double
979shop_greed (const maptile *map)
980{
930 double greed=1.0; 981 double greed = 1.0;
982
931 if (map->shopgreed) 983 if (map->shopgreed)
932 return map->shopgreed; 984 return map->shopgreed;
933 return greed; 985 return greed;
934} 986}
935 987
936/* Returns a double based on how much the shopkeeper approves of the player. 988/* Returns a double based on how much the shopkeeper approves of the player.
937 * this is based on the race of the shopkeeper and that of the player. 989 * this is based on the race of the shopkeeper and that of the player.
938 */ 990 */
991double
939double shopkeeper_approval(const mapstruct *map, const object *player) { 992shopkeeper_approval (const maptile *map, const object *player)
993{
940 double approval=1.0; 994 double approval = 1.0;
941 995
942 if (map->shoprace) { 996 if (map->shoprace)
997 {
943 approval=NEUTRAL_RATIO; 998 approval = NEUTRAL_RATIO;
944 if (player->race && !strcmp(player->race, map->shoprace)) approval = 1.0; 999 if (player->race && !strcmp (player->race, map->shoprace))
1000 approval = 1.0;
945 } 1001 }
1002
946 return approval; 1003 return approval;
947} 1004}
948 1005
949/* limit the value of items based on the wealth of the shop. If the item is close 1006/* limit the value of items based on the wealth of the shop. If the item is close
950 * to the maximum value a shop will offer, we start to reduce it, if the item is 1007 * to the maximum value a shop will offer, we start to reduce it, if the item is
951 * below the minimum value the shop is prepared to trade in, then we don't 1008 * below the minimum value the shop is prepared to trade in, then we don't
952 * want it and offer nothing. If it isn't a shop, check whether we should do generic 1009 * want it and offer nothing. If it isn't a shop, check whether we should do generic
953 * value reduction. 1010 * value reduction.
954 * 1011 *
955 */ 1012 */
1013static sint64
956static uint64 value_limit (uint64 val, int quantity, const object *who, int isshop) { 1014value_limit (sint64 val, int quantity, const object *who, int isshop)
1015{
957 uint64 newval, unit_price, tmpshopmax; 1016 sint64 newval, unit_price, tmpshopmax;
958 mapstruct *map; 1017 maptile *map;
959 1018
960 unit_price = val / quantity; 1019 unit_price = val / quantity;
961 1020
962 if (!isshop || !who) 1021 if (!isshop || !who)
963 { 1022 {
964 if (unit_price > 250000) 1023 if (unit_price > 250000)
965 newval = (uint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.); 1024 newval = (sint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.);
966 else 1025 else
967 newval = unit_price; 1026 newval = unit_price;
968 } 1027 }
969 else 1028 else
970 { 1029 {
971 if (!who->map) 1030 if (!who->map)
972 { 1031 {
973 LOG(llevError, "value_limit: asked shop price for ob %s on NULL map\n", who->name); 1032 LOG (llevError, "value_limit: asked shop price for ob %s on NULL map\n", &who->name);
974 return val; 1033 return val;
975 } 1034 }
976 1035
977 map = who->map; 1036 map = who->map;
978 1037
979 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default 1038 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default
980 1039
981 if (map->shopmin && unit_price < map->shopmin) 1040 if (map->shopmin && unit_price < map->shopmin)
982 return 0; 1041 return 0;
983 else if (unit_price > tmpshopmax / 2) 1042 else if (unit_price > tmpshopmax / 2)
984 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax); 1043 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax);
985 else 1044 else
986 newval=unit_price; 1045 newval = unit_price;
987 } 1046 }
988 1047
989 newval *= quantity; 1048 newval *= quantity;
990 1049
991 return newval; 1050 return newval;
992} 1051}
993 1052
994/* gives a desciption of the shop on their current map to the player op. */ 1053/* gives a desciption of the shop on their current map to the player op. */
1054int
995int describe_shop(const object *op) { 1055describe_shop (const object *op)
1056{
996 mapstruct *map = op->map; 1057 maptile *map = op->map;
1058
997 /*shopitems *items=map->shopitems;*/ 1059 /*shopitems *items=map->shopitems; */
998 int pos=0, i; 1060 int pos = 0, i;
999 double opinion=0; 1061 double opinion = 0;
1000 char tmp[MAX_BUF]="\0"; 1062 char tmp[MAX_BUF] = "\0";
1063
1001 if (op->type != PLAYER) return 0; 1064 if (op->type != PLAYER)
1065 return 0;
1002 1066
1003 /*check if there is a shop specified for this map */ 1067 /*check if there is a shop specified for this map */
1004 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax) { 1068 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax)
1069 {
1005 new_draw_info(NDI_UNIQUE,0,op,"From looking at the nearby shop you determine that it trades in:"); 1070 new_draw_info (NDI_UNIQUE, 0, op, "From looking at the nearby shop you determine that it trades in:");
1071
1006 if (map->shopitems) { 1072 if (map->shopitems)
1007 for (i=0; i < map->shopitems[0].index; i++) { 1073 for (i = 0; i < map->shopitems[0].index; i++)
1008 if (map->shopitems[i].name && map->shopitems[i].strength > 10) { 1074 if (map->shopitems[i].name && map->shopitems[i].strength > 10)
1075 {
1009 snprintf(tmp+pos, sizeof(tmp)-pos, "%s, ", map->shopitems[i].name_pl); 1076 snprintf (tmp + pos, sizeof (tmp) - pos, "%s, ", map->shopitems[i].name_pl);
1010 pos += strlen(tmp+pos); 1077 pos += strlen (tmp + pos);
1011 } 1078 }
1012 } 1079
1013 } 1080 if (!pos)
1014 if (!pos) strcat(tmp, "a little of everything."); 1081 strcat (tmp, "a little of everything.");
1015 1082
1016 /* format the string into a list */ 1083 /* format the string into a list */
1017 make_list_like(tmp); 1084 make_list_like (tmp);
1018 new_draw_info_format(NDI_UNIQUE, 0, op, "%s", tmp); 1085 new_draw_info_format (NDI_UNIQUE, 0, op, "%s", tmp);
1019 1086
1020 if (map->shopmax) 1087 if (map->shopmax)
1021 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade for items above %s.", 1088 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade for items above %s.", cost_string_from_value (map->shopmax, 0));
1022 cost_string_from_value(map->shopmax, 0)); 1089
1023 if (map->shopmin) 1090 if (map->shopmin)
1024 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade in items worth less than %s.", 1091 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade in items worth less than %s.", cost_string_from_value (map->shopmin, 0));
1025 cost_string_from_value(map->shopmin, 0)); 1092
1026 if (map->shopgreed) { 1093 if (map->shopgreed)
1094 {
1027 if (map->shopgreed >2.0) 1095 if (map->shopgreed > 2.0)
1028 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge massively."); 1096 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge massively.");
1029 else if (map->shopgreed >1.5) 1097 else if (map->shopgreed > 1.5)
1030 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge substantially."); 1098 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge substantially.");
1031 else if (map->shopgreed >1.1) 1099 else if (map->shopgreed > 1.1)
1032 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge slightly."); 1100 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge slightly.");
1033 else if (map->shopgreed <0.9) 1101 else if (map->shopgreed < 0.9)
1034 new_draw_info(NDI_UNIQUE,0,op,"It tends to undercharge."); 1102 new_draw_info (NDI_UNIQUE, 0, op, "It tends to undercharge.");
1035 } 1103 }
1104
1036 if (map->shoprace) { 1105 if (map->shoprace)
1106 {
1037 opinion=shopkeeper_approval(map, op); 1107 opinion = shopkeeper_approval (map, op);
1038 if (opinion > 0.8) 1108 if (opinion > 0.8)
1039 new_draw_info(NDI_UNIQUE,0,op,"You think the shopkeeper likes you."); 1109 new_draw_info (NDI_UNIQUE, 0, op, "You think the shopkeeper likes you.");
1040 else if (opinion > 0.5) 1110 else if (opinion > 0.5)
1041 new_draw_info(NDI_UNIQUE,0,op,"The shopkeeper seems unconcerned by you."); 1111 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper seems unconcerned by you.");
1042 else 1112 else
1043 new_draw_info(NDI_UNIQUE,0,op,"The shopkeeper seems to have taken a dislike to you."); 1113 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper seems to have taken a dislike to you.");
1044 } 1114 }
1045 } 1115 }
1116 else
1046 else new_draw_info(NDI_UNIQUE,0,op,"There is no shop nearby."); 1117 new_draw_info (NDI_UNIQUE, 0, op, "There is no shop nearby.");
1047 1118
1048 return 1; 1119 return 1;
1049} 1120}
1050typedef struct shopinv { 1121
1122struct shopinv
1123{
1051 char *item_sort; 1124 char *item_sort;
1052 char *item_real; 1125 char *item_real;
1053 uint16 type; 1126 uint16 type;
1054 uint32 nrof; 1127 uint32 nrof;
1055} shopinv; 1128};
1056 1129
1057/* There are a lot fo extra casts in here just to suppress warnings - it 1130/* There are a lot fo extra casts in here just to suppress warnings - it
1058 * makes it look uglier than it really it. 1131 * makes it look uglier than it really it.
1059 * The format of the strings we get is type:name. So we first want to 1132 * The format of the strings we get is type:name. So we first want to
1060 * sort by type (numerical) - if the same type, then sort by name. 1133 * sort by type (numerical) - if the same type, then sort by name.
1061 */ 1134 */
1135static int
1062static int shop_sort(const void *a1, const void *a2) 1136shop_sort (const void *a1, const void *a2)
1063{ 1137{
1064 shopinv *s1 = (shopinv*)a1, *s2= (shopinv*)a2; 1138 shopinv *s1 = (shopinv *) a1, *s2 = (shopinv *) a2;
1065 1139
1066 if (s1->type<s2->type) return -1; 1140 if (s1->type < s2->type)
1141 return -1;
1067 if (s1->type>s2->type) return 1; 1142 if (s1->type > s2->type)
1143 return 1;
1144
1068 /* the type is the same (what atoi gets), so do a strcasecmp to sort 1145 /* the type is the same (what atoi gets), so do a strcasecmp to sort
1069 * via alphabetical order 1146 * via alphabetical order
1070 */ 1147 */
1071 return strcasecmp(s1->item_sort, s2->item_sort); 1148 return strcasecmp (s1->item_sort, s2->item_sort);
1072} 1149}
1073 1150
1151static void
1074static void add_shop_item(object *tmp, shopinv *items, int *numitems, int *numallocated) 1152add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated)
1075{ 1153{
1076#if 0 1154#if 0
1077 char buf[MAX_BUF]; 1155 char buf[MAX_BUF];
1078#endif 1156#endif
1079 /* clear unpaid flag so that doesn't come up in query 1157 /* clear unpaid flag so that doesn't come up in query
1080 * string. We clear nrof so that we can better sort 1158 * string. We clear nrof so that we can better sort
1081 * the object names. 1159 * the object names.
1082 */ 1160 */
1083 1161
1084 CLEAR_FLAG(tmp, FLAG_UNPAID); 1162 CLEAR_FLAG (tmp, FLAG_UNPAID);
1085 items[*numitems].nrof=tmp->nrof; 1163 items[*numitems].nrof = tmp->nrof;
1086 /* Non mergable items have nrof of 0, but count them as one 1164 /* Non mergable items have nrof of 0, but count them as one
1087 * so the display is properly. 1165 * so the display is properly.
1088 */ 1166 */
1089 if (tmp->nrof == 0) items[*numitems].nrof++; 1167 if (tmp->nrof == 0)
1168 items[*numitems].nrof++;
1090 items[*numitems].type=tmp->type; 1169 items[*numitems].type = tmp->type;
1091 1170
1092 switch (tmp->type) { 1171 switch (tmp->type)
1172 {
1093#if 0 1173#if 0
1094 case BOOTS: 1174 case BOOTS:
1095 case GLOVES: 1175 case GLOVES:
1096 case RING: 1176 case RING:
1097 case AMULET: 1177 case AMULET:
1098 case BRACERS: 1178 case BRACERS:
1099 case GIRDLE: 1179 case GIRDLE:
1100 sprintf(buf,"%s %s",query_base_name(tmp,0),describe_item(tmp, NULL)); 1180 sprintf (buf, "%s %s", query_base_name (tmp, 0), describe_item (tmp, NULL));
1101 items[*numitems].item_sort = strdup_local(buf); 1181 items[*numitems].item_sort = strdup (buf);
1102 sprintf(buf,"%s %s",query_name(tmp),describe_item(tmp, NULL)); 1182 sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL));
1103 items[*numitems].item_real = strdup_local(buf); 1183 items[*numitems].item_real = strdup (buf);
1104 (*numitems)++; 1184 (*numitems)++;
1105 break; 1185 break;
1106#endif 1186#endif
1107 1187
1108 default: 1188 default:
1109 items[*numitems].item_sort = strdup_local(query_base_name(tmp, 0)); 1189 items[*numitems].item_sort = strdup (query_base_name (tmp, 0));
1110 items[*numitems].item_real = strdup_local(query_base_name(tmp, 1)); 1190 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1111 (*numitems)++; 1191 (*numitems)++;
1112 break; 1192 break;
1113 } 1193 }
1114 SET_FLAG(tmp, FLAG_UNPAID); 1194 SET_FLAG (tmp, FLAG_UNPAID);
1115} 1195}
1116 1196
1197void
1117void shop_listing(object *op) 1198shop_listing (object *op)
1118{ 1199{
1119 int i,j,numitems=0,numallocated=0, nx, ny; 1200 int i, j, numitems = 0, numallocated = 0, nx, ny;
1120 char *map_mark = (char *) calloc(MAGIC_MAP_SIZE * MAGIC_MAP_SIZE,1); 1201 char *map_mark = (char *) calloc (MAGIC_MAP_SIZE * MAGIC_MAP_SIZE, 1);
1121 object *stack; 1202 object *stack;
1122 shopinv *items; 1203 shopinv *items;
1123 1204
1124 /* Should never happen, but just in case a monster does apply a sign */ 1205 /* Should never happen, but just in case a monster does apply a sign */
1125 if (op->type!=PLAYER) return; 1206 if (op->type != PLAYER)
1207 return;
1126 1208
1127 new_draw_info(NDI_UNIQUE, 0, op, "\nThe shop contains:"); 1209 new_draw_info (NDI_UNIQUE, 0, op, "\nThe shop contains:");
1128 1210
1129 magic_mapping_mark(op, map_mark, 3); 1211 magic_mapping_mark (op, map_mark, 3);
1130 items=(shopinv*)malloc(40*sizeof(shopinv)); 1212 items = (shopinv *) malloc (40 * sizeof (shopinv));
1131 numallocated=40; 1213 numallocated = 40;
1132 1214
1133 /* Find all the appropriate items */ 1215 /* Find all the appropriate items */
1134 for (i=0; i<MAP_WIDTH(op->map); i++) { 1216 for (i = 0; i < op->map->width; i++)
1135 for (j=0; j<MAP_HEIGHT(op->map); j++) { 1217 {
1218 for (j = 0; j < op->map->height; j++)
1219 {
1136 /* magic map code now centers the map on the object at MAGIC_MAP_HALF. 1220 // magic map code now centers the map on the object at MAGIC_MAP_HALF.
1137 *
1138 */
1139 nx = i - op->x + MAGIC_MAP_HALF; 1221 nx = i - op->x + MAGIC_MAP_HALF;
1140 ny = j - op->y + MAGIC_MAP_HALF; 1222 ny = j - op->y + MAGIC_MAP_HALF;
1141 /* unlikely, but really big shops could run into this issue */ 1223 /* unlikely, but really big shops could run into this issue */
1142 if (nx < 0 || ny < 0 || nx > MAGIC_MAP_SIZE || ny > MAGIC_MAP_SIZE) continue; 1224 if (nx < 0 || ny < 0 || nx > MAGIC_MAP_SIZE || ny > MAGIC_MAP_SIZE)
1225 continue;
1143 1226
1144 if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR) { 1227 if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR)
1145 stack =get_map_ob(op->map,i,j); 1228 {
1229 stack = GET_MAP_OB (op->map, i, j);
1146 1230
1147 while (stack) { 1231 while (stack)
1232 {
1148 if (QUERY_FLAG(stack, FLAG_UNPAID)) { 1233 if (QUERY_FLAG (stack, FLAG_UNPAID))
1149 if (numitems==numallocated) { 1234 {
1235 if (numitems == numallocated)
1236 {
1150 items=(shopinv*)realloc(items, sizeof(shopinv)*(numallocated+10)); 1237 items = (shopinv *) realloc (items, sizeof (shopinv) * (numallocated + 10));
1151 numallocated+=10; 1238 numallocated += 10;
1152 } 1239 }
1240
1153 add_shop_item(stack, items, &numitems, &numallocated); 1241 add_shop_item (stack, items, &numitems, &numallocated);
1154 } 1242 }
1243
1155 stack = stack->above; 1244 stack = stack->above;
1156 } 1245 }
1246 }
1247 }
1157 } 1248 }
1158 } 1249
1159 }
1160 free(map_mark); 1250 free (map_mark);
1251
1161 if (numitems == 0) { 1252 if (numitems == 0)
1253 {
1162 new_draw_info(NDI_UNIQUE, 0, op, "The shop is currently empty.\n"); 1254 new_draw_info (NDI_UNIQUE, 0, op, "The shop is currently empty.\n");
1163 free(items); 1255 free (items);
1164 return; 1256 return;
1165 } 1257 }
1258
1166 qsort(items, numitems, sizeof(shopinv), (int (*)(const void*, const void*))shop_sort); 1259 qsort (items, numitems, sizeof (shopinv), (int (*)(const void *, const void *)) shop_sort);
1167 1260
1168 for (i=0; i<numitems; i++) { 1261 for (i = 0; i < numitems; i++)
1262 {
1169 /* Collapse items of the same name together */ 1263 /* Collapse items of the same name together */
1170 if ((i+1)<numitems && !strcmp(items[i].item_real, items[i+1].item_real)) { 1264 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real))
1265 {
1171 items[i+1].nrof += items[i].nrof; 1266 items[i + 1].nrof += items[i].nrof;
1172 free(items[i].item_sort); 1267 free (items[i].item_sort);
1173 free(items[i].item_real); 1268 free (items[i].item_real);
1174 } else { 1269 }
1270 else
1271 {
1175 new_draw_info_format(NDI_UNIQUE, 0, op, "%d %s", 1272 new_draw_info_format (NDI_UNIQUE, 0, op, "%d %s",
1176 items[i].nrof? items[i].nrof:1, 1273 items[i].nrof ? items[i].nrof : 1, items[i].nrof == 1 ? items[i].item_sort : items[i].item_real);
1177 items[i].nrof==1?items[i].item_sort: items[i].item_real);
1178 free(items[i].item_sort); 1274 free (items[i].item_sort);
1179 free(items[i].item_real); 1275 free (items[i].item_real);
1180 } 1276 }
1181 } 1277 }
1278
1182 free(items); 1279 free (items);
1183} 1280}
1281
1282/* elmex: this function checks whether the object is in a shop */
1283bool
1284is_in_shop (object *o)
1285{
1286 if (!o->map)
1287 return false;
1288
1289 return is_in_shop (o->map, o->x, o->y);
1290}
1291
1292/* elmex: this function checks whether we are in a shop or not */
1293bool
1294is_in_shop (maptile *map, int x, int y)
1295{
1296 for (object *floor = GET_MAP_OB (map, x, y); floor; floor = floor->above)
1297 if (floor->type == SHOP_FLOOR)
1298 return true;
1299
1300 return false;
1301}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines