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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines