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.17 by root, Thu Sep 14 23:13:49 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 mapstruct *map);
54static double shop_greed(const mapstruct *map); 49static double shop_greed (const mapstruct *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 object *item;
636 uint32 coincount[NUM_COINS]; 687
637 if (!pl || pl->type != PLAYER) { 688 if (!pl || pl->type != PLAYER)
689 {
638 LOG(llevError, "can_pay(): called against something that isn't a player\n"); 690 LOG (llevError, "can_pay(): called against something that isn't a player\n");
639 return 0; 691 return 0;
640 } 692 }
641 for (i=0; i< NUM_COINS; i++) coincount[i] = 0; 693
642 for (item = pl->inv;item;) { 694 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item)
643 if QUERY_FLAG(item, FLAG_UNPAID) { 695 if (QUERY_FLAG (item, FLAG_UNPAID))
696 {
644 unpaid_count++; 697 unpaid_count++;
645 unpaid_price += query_cost(item, pl, F_BUY | F_SHOP); 698 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 } 699 }
700
658 if (unpaid_price > player_wealth) { 701 if (unpaid_price > player_wealth)
659 char buf[MAX_BUF], coinbuf[MAX_BUF]; 702 {
660 int denominations = 0; 703 char buf[MAX_BUF];
661 int has_coins = NUM_COINS;
662 char cost[MAX_BUF]; 704 char cost[MAX_BUF];
663 char missing[MAX_BUF]; 705 char missing[MAX_BUF];
664 706
665 sprintf(cost, "%s", cost_string_from_value (unpaid_price, 0)); 707 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)); 708 snprintf (missing, MAX_BUF, "%s", cost_string_from_value (unpaid_price - player_wealth, 0));
667 709
668 sprintf(buf, "You have %d unpaid items that would cost you %s. You need another %s to be able to afford that.", 710 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); 711 unpaid_count, cost, missing);
670 new_draw_info(NDI_UNIQUE, 0, pl, buf); 712 new_draw_info (NDI_UNIQUE, 0, pl, buf);
671 return 0; 713
714 return 0;
672 } 715 }
716 else
673 else return 1; 717 return 1;
674} 718}
675
676 719
677/* Better get_payment, descends containers looking for 720/* Better get_payment, descends containers looking for
678 * unpaid items, and pays for them. 721 * unpaid items, and pays for them.
679 * returns 0 if the player still has unpaid items. 722 * returns 0 if the player still has unpaid items.
680 * returns 1 if the player has paid for everything. 723 * returns 1 if the player has paid for everything.
681 * pl is the player buying the stuff. 724 * 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 */ 725 */
686int get_payment(object *pl, object *op) { 726int
727get_payment (object *pl)
728{
729 for (;;)
730 {
731 next_item:
732
733 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op)
734 {
735 if (QUERY_FLAG (op, FLAG_UNPAID))
736 {
687 char buf[MAX_BUF]; 737 char buf[MAX_BUF];
688 int ret=1; 738 snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP));
689 739
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)) { 740 if (!pay_for_item (op, pl))
741 {
706 uint64 i=query_cost(op,pl,F_BUY | F_SHOP) - query_money(pl); 742 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl);
743
707 CLEAR_FLAG(op, FLAG_UNPAID); 744 CLEAR_FLAG (op, FLAG_UNPAID);
708 new_draw_info_format(NDI_UNIQUE, 0, pl, 745 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); 746 SET_FLAG (op, FLAG_UNPAID);
712 return 0; 747 return 0;
748 }
713 } else { 749 else
714 object *tmp; 750 {
715 tag_t c = op->count; 751 object *tmp;
716 752
717 CLEAR_FLAG(op, FLAG_UNPAID); 753 CLEAR_FLAG (op, FLAG_UNPAID);
718 CLEAR_FLAG(op, FLAG_PLAYER_SOLD); 754 CLEAR_FLAG (op, FLAG_PLAYER_SOLD);
719 new_draw_info_format(NDI_UNIQUE, 0, op, 755 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)); 756 tmp = merge_ob (op, NULL);
721 tmp=merge_ob(op,NULL); 757
722 if (pl->type == PLAYER) { 758 if (pl->type == PLAYER)
723 if (tmp) { /* it was merged */ 759 {
724 esrv_del_item (pl->contr, c); 760 if (tmp)
725 op = tmp; 761 { /* it was merged */
726 } 762 esrv_del_item (pl->contr, op->count);
763 op = tmp;
764 }
765
727 esrv_send_item(pl, op); 766 esrv_send_item (pl, op);
728 } 767 }
729 } 768
730 } 769 goto next_item;
770 }
771 }
772 }
773
731 return 1; 774 return 1;
775 }
732} 776}
733 777
734/* written by elmex: 778/* written by elmex:
735 * moved this code from sell_item () here to have a function 779 * moved this code from sell_item () here to have a function
736 * that pays the player an amount. Mainly put the code here to 780 * 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 784 * 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 785 * 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. 786 * go somewhere and unload the money at a safe place.
743 * 787 *
744 */ 788 */
789void
745void pay_player (object *pl, uint64 amount) { 790pay_player (object *pl, sint64 amount)
791{
746 int count = 0; 792 int count = 0;
747 archetype *at = 0; 793 archetype *at = 0;
748 object *pouch = 0, *tmp = 0; 794 object *pouch = 0, *tmp = 0;
749 795
750 for (count = 0; coins[count] != NULL; count++) 796 for (count = 0; coins[count] != NULL; count++)
751 { 797 {
752 at = find_archetype (coins[count]); 798 at = archetype::find (coins[count]);
753 799
754 if (at == NULL) 800 if (at == NULL)
755 LOG(llevError, "Could not find %s archetype\n", coins[count]); 801 LOG (llevError, "Could not find %s archetype\n", coins[count]);
756 else if ((amount / at->clone.value) > 0) 802 else if ((amount / at->clone.value) > 0)
757 { 803 {
758 for (pouch=pl->inv; pouch; pouch=pouch->below) 804 for (pouch = pl->inv; pouch; pouch = pouch->below)
759 { 805 {
760 if (pouch->type == CONTAINER 806 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 { 807 {
765 int w = at->clone.weight * (100 - pouch->stats.Str) / 100; 808 int w = at->clone.weight * (100 - pouch->stats.Str) / 100;
766 int n = amount / at->clone.value; 809 int n = amount / at->clone.value;
767 810
768 if (w == 0) 811 if (w == 0)
769 w = 1; /* Prevent divide by zero */ 812 w = 1; /* Prevent divide by zero */
770 813
771 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit)) 814 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit))
772 { 815 {
773 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n) 816 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n)
774 n = (pouch->weight_limit - pouch->carrying) / w; 817 n = (pouch->weight_limit - pouch->carrying) / w;
775 818
776 tmp = arch_to_object (at); 819 tmp = arch_to_object (at);
777 tmp->nrof = n; 820 tmp->nrof = n;
778 amount -= (uint64)tmp->nrof * (uint64)tmp->value; 821 amount -= tmp->nrof * tmp->value;
779 tmp = insert_ob_in_ob (tmp, pouch); 822 tmp = insert_ob_in_ob (tmp, pouch);
780 esrv_send_item (pl, tmp); 823 esrv_send_item (pl, tmp);
781 esrv_send_item (pl, pouch); 824 esrv_send_item (pl, pouch);
782 esrv_update_item (UPD_WEIGHT, pl, pouch); 825 esrv_update_item (UPD_WEIGHT, pl, pouch);
783 esrv_send_item (pl, pl); 826 esrv_send_item (pl, pl);
787 830
788 if (amount / at->clone.value > 0) 831 if (amount / at->clone.value > 0)
789 { 832 {
790 tmp = arch_to_object (at); 833 tmp = arch_to_object (at);
791 tmp->nrof = amount / tmp->value; 834 tmp->nrof = amount / tmp->value;
792 amount -= (uint64)tmp->nrof * (uint64)tmp->value; 835 amount -= tmp->nrof * tmp->value;
793 tmp = insert_ob_in_ob (tmp, pl); 836 tmp = insert_ob_in_ob (tmp, pl);
794 esrv_send_item (pl, tmp); 837 esrv_send_item (pl, tmp);
795 esrv_send_item (pl, pl); 838 esrv_send_item (pl, pl);
796 } 839 }
797 } 840 }
798 } 841 }
799 842
800 if (amount != 0) 843 if (amount != 0)
801#ifndef WIN32 844#ifndef WIN32
802 LOG (llevError,"Warning - payment in pay_player () not zero: %llu\n", amount); 845 LOG (llevError, "Warning - payment in pay_player () not zero: %llu\n", amount);
803#else 846#else
804 LOG (llevError,"Warning - payment in pay_player () not zero: %I64u\n", amount); 847 LOG (llevError, "Warning - payment in pay_player () not zero: %I64u\n", amount);
805#endif 848#endif
806} 849}
807 850
808/* elmex: this is for the bank plugin :( */ 851/* elmex: this is for the bank plugin :( */
852sint64
809uint64 pay_player_arch (object *pl, const char *arch, uint64 amount) { 853pay_player_arch (object *pl, const char *arch, sint64 amount)
854{
810 archetype *at = find_archetype (arch); 855 archetype *at = archetype::find (arch);
811 object *tmp = NULL; 856 object *tmp = NULL;
812 857
813 if (at == NULL) 858 if (at == NULL)
814 return 0; 859 return 0;
815 860
830 * buy item. 875 * buy item.
831 * 876 *
832 * Modified to fill available race: gold containers before dumping 877 * Modified to fill available race: gold containers before dumping
833 * remaining coins in character's inventory. 878 * remaining coins in character's inventory.
834 */ 879 */
880void
835void sell_item(object *op, object *pl) { 881sell_item (object *op, object *pl)
882{
836 uint64 amount = query_cost (op,pl,F_SELL | F_SHOP), extra_gain; 883 sint64 amount = query_cost (op, pl, F_SELL | F_SHOP), extra_gain;
837 884
838 if(pl==NULL || pl->type != PLAYER) 885 if (pl == NULL || pl->type != PLAYER)
839 { 886 {
840 LOG(llevDebug,"Object other than player tried to sell something.\n"); 887 LOG (llevDebug, "Object other than player tried to sell something.\n");
841 return; 888 return;
842 } 889 }
843 890
844 if(op->custom_name) 891 op->custom_name = 0;
845 FREE_AND_CLEAR_STR (op->custom_name);
846 892
847 if(!amount) 893 if (!amount)
848 { 894 {
849 new_draw_info_format (NDI_UNIQUE, 0, pl, 895 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 896
852 /* Even if the character doesn't get anything for it, it may still be 897 /* Even if the character doesn't get anything for it, it may still be
853 * worth something. If so, make it unpaid 898 * worth something. If so, make it unpaid
854 */ 899 */
855 if (op->value) 900 if (op->value)
856 { 901 {
857 SET_FLAG(op, FLAG_UNPAID); 902 SET_FLAG (op, FLAG_UNPAID);
858 SET_FLAG(op, FLAG_PLAYER_SOLD); 903 SET_FLAG (op, FLAG_PLAYER_SOLD);
859 } 904 }
860 905
861 identify (op); 906 identify (op);
862 return; 907 return;
863 } 908 }
868 * exp/10 -> 1 for each gold coin 913 * exp/10 -> 1 for each gold coin
869 */ 914 */
870 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP); 915 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP);
871 916
872 if (extra_gain > 0) 917 if (extra_gain > 0)
873 change_exp(pl, extra_gain / 10, "bargaining", SK_EXP_NONE); 918 change_exp (pl, extra_gain / 10, "bargaining", SK_EXP_NONE);
874 919
875 pay_player (pl, amount); 920 pay_player (pl, amount);
876 921
877 new_draw_info_format (NDI_UNIQUE, 0, pl, 922 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 923
881 SET_FLAG (op, FLAG_UNPAID); 924 SET_FLAG (op, FLAG_UNPAID);
882 identify (op); 925 identify (op);
883} 926}
884 927
886/* returns a double that is the ratio of the price that a shop will offer for 929/* 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, 930 * 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 931 * 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) 932 * event is never less than 0.1 (calling functions divide by it)
890 */ 933 */
934static double
891static double shop_specialisation_ratio(const object *item, const mapstruct *map) { 935shop_specialisation_ratio (const object *item, const mapstruct *map)
936{
892 shopitems *items=map->shopitems; 937 shopitems *items = map->shopitems;
893 double ratio = SPECIALISATION_EFFECT, likedness=0.001; 938 double ratio = SPECIALISATION_EFFECT, likedness = 0.001;
894 int i; 939 int i;
895 940
896 if (item==NULL) { 941 if (item == NULL)
942 {
897 LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path); 943 LOG (llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path);
898 return 0; 944 return 0;
899 } 945 }
946
900 if (!item->type) { 947 if (!item->type)
948 {
901 LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type\n"); 949 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
902 /* 950 /*
903 * I'm not really sure what the /right/ thing to do here is, these types of 951 * 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.." 952 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
905 */ 953 */
906 return ratio; 954 return ratio;
907 } 955 }
956
908 if (map->shopitems) { 957 if (map->shopitems)
958 {
909 for (i=0; i<items[0].index; i++) 959 for (i = 0; i < items[0].index; i++)
910 if (items[i].typenum==item->type || (!items[i].typenum && likedness == 0.001)) 960 if (items[i].typenum == item->type || (!items[i].typenum && likedness == 0.001))
911 likedness = items[i].strength/100.0; 961 likedness = items[i].strength / 100.0;
912 } 962 }
913 if (likedness > 1.0) { /* someone has been rather silly with the map headers. */ 963
964 if (likedness > 1.0)
965 { /* 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", 966 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; 967 likedness = 1.0;
917 } 968 }
969
918 if (likedness < -1.0) { 970 if (likedness < -1.0)
971 {
919 LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", 972 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; 973 likedness = -1.0;
922 } 974 }
975
923 ratio = ratio + (1.0-ratio) * likedness; 976 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 */ 977
978 if (ratio <= 0.1)
979 ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */
980
925 return ratio; 981 return ratio;
926} 982}
927 983
928/*returns the greed of the shop on map, or 1 if it isn't specified. */ 984/*returns the greed of the shop on map, or 1 if it isn't specified. */
985static double
929static double shop_greed(const mapstruct *map) { 986shop_greed (const mapstruct *map)
987{
930 double greed=1.0; 988 double greed = 1.0;
989
931 if (map->shopgreed) 990 if (map->shopgreed)
932 return map->shopgreed; 991 return map->shopgreed;
933 return greed; 992 return greed;
934} 993}
935 994
936/* Returns a double based on how much the shopkeeper approves of the player. 995/* 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. 996 * this is based on the race of the shopkeeper and that of the player.
938 */ 997 */
998double
939double shopkeeper_approval(const mapstruct *map, const object *player) { 999shopkeeper_approval (const mapstruct *map, const object *player)
1000{
940 double approval=1.0; 1001 double approval = 1.0;
941 1002
942 if (map->shoprace) { 1003 if (map->shoprace)
1004 {
943 approval=NEUTRAL_RATIO; 1005 approval = NEUTRAL_RATIO;
944 if (player->race && !strcmp(player->race, map->shoprace)) approval = 1.0; 1006 if (player->race && !strcmp (player->race, map->shoprace))
1007 approval = 1.0;
945 } 1008 }
1009
946 return approval; 1010 return approval;
947} 1011}
948 1012
949/* limit the value of items based on the wealth of the shop. If the item is close 1013/* 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 1014 * 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 1015 * 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 1016 * want it and offer nothing. If it isn't a shop, check whether we should do generic
953 * value reduction. 1017 * value reduction.
954 * 1018 *
955 */ 1019 */
1020static sint64
956static uint64 value_limit (uint64 val, int quantity, const object *who, int isshop) { 1021value_limit (sint64 val, int quantity, const object *who, int isshop)
1022{
957 uint64 newval, unit_price, tmpshopmax; 1023 sint64 newval, unit_price, tmpshopmax;
958 mapstruct *map; 1024 mapstruct *map;
959 1025
960 unit_price = val / quantity; 1026 unit_price = val / quantity;
961 1027
962 if (!isshop || !who) 1028 if (!isshop || !who)
963 { 1029 {
964 if (unit_price > 250000) 1030 if (unit_price > 250000)
965 newval = (uint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.); 1031 newval = (sint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.);
966 else 1032 else
967 newval = unit_price; 1033 newval = unit_price;
968 } 1034 }
969 else 1035 else
970 { 1036 {
971 if (!who->map) 1037 if (!who->map)
972 { 1038 {
973 LOG(llevError, "value_limit: asked shop price for ob %s on NULL map\n", who->name); 1039 LOG (llevError, "value_limit: asked shop price for ob %s on NULL map\n", &who->name);
974 return val; 1040 return val;
975 } 1041 }
976 1042
977 map = who->map; 1043 map = who->map;
978 1044
979 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default 1045 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default
980 1046
981 if (map->shopmin && unit_price < map->shopmin) 1047 if (map->shopmin && unit_price < map->shopmin)
982 return 0; 1048 return 0;
983 else if (unit_price > tmpshopmax / 2) 1049 else if (unit_price > tmpshopmax / 2)
984 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax); 1050 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax);
985 else 1051 else
986 newval=unit_price; 1052 newval = unit_price;
987 } 1053 }
988 1054
989 newval *= quantity; 1055 newval *= quantity;
990 1056
991 return newval; 1057 return newval;
992} 1058}
993 1059
994/* gives a desciption of the shop on their current map to the player op. */ 1060/* gives a desciption of the shop on their current map to the player op. */
1061int
995int describe_shop(const object *op) { 1062describe_shop (const object *op)
1063{
996 mapstruct *map = op->map; 1064 mapstruct *map = op->map;
1065
997 /*shopitems *items=map->shopitems;*/ 1066 /*shopitems *items=map->shopitems; */
998 int pos=0, i; 1067 int pos = 0, i;
999 double opinion=0; 1068 double opinion = 0;
1000 char tmp[MAX_BUF]="\0"; 1069 char tmp[MAX_BUF] = "\0";
1070
1001 if (op->type != PLAYER) return 0; 1071 if (op->type != PLAYER)
1072 return 0;
1002 1073
1003 /*check if there is a shop specified for this map */ 1074 /*check if there is a shop specified for this map */
1004 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax) { 1075 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax)
1076 {
1005 new_draw_info(NDI_UNIQUE,0,op,"From looking at the nearby shop you determine that it trades in:"); 1077 new_draw_info (NDI_UNIQUE, 0, op, "From looking at the nearby shop you determine that it trades in:");
1078
1006 if (map->shopitems) { 1079 if (map->shopitems)
1007 for (i=0; i < map->shopitems[0].index; i++) { 1080 for (i = 0; i < map->shopitems[0].index; i++)
1008 if (map->shopitems[i].name && map->shopitems[i].strength > 10) { 1081 if (map->shopitems[i].name && map->shopitems[i].strength > 10)
1082 {
1009 snprintf(tmp+pos, sizeof(tmp)-pos, "%s, ", map->shopitems[i].name_pl); 1083 snprintf (tmp + pos, sizeof (tmp) - pos, "%s, ", map->shopitems[i].name_pl);
1010 pos += strlen(tmp+pos); 1084 pos += strlen (tmp + pos);
1011 } 1085 }
1012 } 1086
1013 } 1087 if (!pos)
1014 if (!pos) strcat(tmp, "a little of everything."); 1088 strcat (tmp, "a little of everything.");
1015 1089
1016 /* format the string into a list */ 1090 /* format the string into a list */
1017 make_list_like(tmp); 1091 make_list_like (tmp);
1018 new_draw_info_format(NDI_UNIQUE, 0, op, "%s", tmp); 1092 new_draw_info_format (NDI_UNIQUE, 0, op, "%s", tmp);
1019 1093
1020 if (map->shopmax) 1094 if (map->shopmax)
1021 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade for items above %s.", 1095 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)); 1096
1023 if (map->shopmin) 1097 if (map->shopmin)
1024 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade in items worth less than %s.", 1098 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)); 1099
1026 if (map->shopgreed) { 1100 if (map->shopgreed)
1101 {
1027 if (map->shopgreed >2.0) 1102 if (map->shopgreed > 2.0)
1028 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge massively."); 1103 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge massively.");
1029 else if (map->shopgreed >1.5) 1104 else if (map->shopgreed > 1.5)
1030 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge substantially."); 1105 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge substantially.");
1031 else if (map->shopgreed >1.1) 1106 else if (map->shopgreed > 1.1)
1032 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge slightly."); 1107 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge slightly.");
1033 else if (map->shopgreed <0.9) 1108 else if (map->shopgreed < 0.9)
1034 new_draw_info(NDI_UNIQUE,0,op,"It tends to undercharge."); 1109 new_draw_info (NDI_UNIQUE, 0, op, "It tends to undercharge.");
1035 } 1110 }
1111
1036 if (map->shoprace) { 1112 if (map->shoprace)
1113 {
1037 opinion=shopkeeper_approval(map, op); 1114 opinion = shopkeeper_approval (map, op);
1038 if (opinion > 0.8) 1115 if (opinion > 0.8)
1039 new_draw_info(NDI_UNIQUE,0,op,"You think the shopkeeper likes you."); 1116 new_draw_info (NDI_UNIQUE, 0, op, "You think the shopkeeper likes you.");
1040 else if (opinion > 0.5) 1117 else if (opinion > 0.5)
1041 new_draw_info(NDI_UNIQUE,0,op,"The shopkeeper seems unconcerned by you."); 1118 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper seems unconcerned by you.");
1042 else 1119 else
1043 new_draw_info(NDI_UNIQUE,0,op,"The shopkeeper seems to have taken a dislike to you."); 1120 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper seems to have taken a dislike to you.");
1044 } 1121 }
1045 } 1122 }
1123 else
1046 else new_draw_info(NDI_UNIQUE,0,op,"There is no shop nearby."); 1124 new_draw_info (NDI_UNIQUE, 0, op, "There is no shop nearby.");
1047 1125
1048 return 1; 1126 return 1;
1049} 1127}
1050typedef struct shopinv { 1128
1129struct shopinv
1130{
1051 char *item_sort; 1131 char *item_sort;
1052 char *item_real; 1132 char *item_real;
1053 uint16 type; 1133 uint16 type;
1054 uint32 nrof; 1134 uint32 nrof;
1055} shopinv; 1135};
1056 1136
1057/* There are a lot fo extra casts in here just to suppress warnings - it 1137/* There are a lot fo extra casts in here just to suppress warnings - it
1058 * makes it look uglier than it really it. 1138 * makes it look uglier than it really it.
1059 * The format of the strings we get is type:name. So we first want to 1139 * 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. 1140 * sort by type (numerical) - if the same type, then sort by name.
1061 */ 1141 */
1142static int
1062static int shop_sort(const void *a1, const void *a2) 1143shop_sort (const void *a1, const void *a2)
1063{ 1144{
1064 shopinv *s1 = (shopinv*)a1, *s2= (shopinv*)a2; 1145 shopinv *s1 = (shopinv *) a1, *s2 = (shopinv *) a2;
1065 1146
1066 if (s1->type<s2->type) return -1; 1147 if (s1->type < s2->type)
1148 return -1;
1067 if (s1->type>s2->type) return 1; 1149 if (s1->type > s2->type)
1150 return 1;
1151
1068 /* the type is the same (what atoi gets), so do a strcasecmp to sort 1152 /* the type is the same (what atoi gets), so do a strcasecmp to sort
1069 * via alphabetical order 1153 * via alphabetical order
1070 */ 1154 */
1071 return strcasecmp(s1->item_sort, s2->item_sort); 1155 return strcasecmp (s1->item_sort, s2->item_sort);
1072} 1156}
1073 1157
1158static void
1074static void add_shop_item(object *tmp, shopinv *items, int *numitems, int *numallocated) 1159add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated)
1075{ 1160{
1076#if 0 1161#if 0
1077 char buf[MAX_BUF]; 1162 char buf[MAX_BUF];
1078#endif 1163#endif
1079 /* clear unpaid flag so that doesn't come up in query 1164 /* clear unpaid flag so that doesn't come up in query
1080 * string. We clear nrof so that we can better sort 1165 * string. We clear nrof so that we can better sort
1081 * the object names. 1166 * the object names.
1082 */ 1167 */
1083 1168
1084 CLEAR_FLAG(tmp, FLAG_UNPAID); 1169 CLEAR_FLAG (tmp, FLAG_UNPAID);
1085 items[*numitems].nrof=tmp->nrof; 1170 items[*numitems].nrof = tmp->nrof;
1086 /* Non mergable items have nrof of 0, but count them as one 1171 /* Non mergable items have nrof of 0, but count them as one
1087 * so the display is properly. 1172 * so the display is properly.
1088 */ 1173 */
1089 if (tmp->nrof == 0) items[*numitems].nrof++; 1174 if (tmp->nrof == 0)
1175 items[*numitems].nrof++;
1090 items[*numitems].type=tmp->type; 1176 items[*numitems].type = tmp->type;
1091 1177
1092 switch (tmp->type) { 1178 switch (tmp->type)
1179 {
1093#if 0 1180#if 0
1094 case BOOTS: 1181 case BOOTS:
1095 case GLOVES: 1182 case GLOVES:
1096 case RING: 1183 case RING:
1097 case AMULET: 1184 case AMULET:
1098 case BRACERS: 1185 case BRACERS:
1099 case GIRDLE: 1186 case GIRDLE:
1100 sprintf(buf,"%s %s",query_base_name(tmp,0),describe_item(tmp, NULL)); 1187 sprintf (buf, "%s %s", query_base_name (tmp, 0), describe_item (tmp, NULL));
1101 items[*numitems].item_sort = strdup_local(buf); 1188 items[*numitems].item_sort = strdup_local (buf);
1102 sprintf(buf,"%s %s",query_name(tmp),describe_item(tmp, NULL)); 1189 sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL));
1103 items[*numitems].item_real = strdup_local(buf); 1190 items[*numitems].item_real = strdup_local (buf);
1104 (*numitems)++; 1191 (*numitems)++;
1105 break; 1192 break;
1106#endif 1193#endif
1107 1194
1108 default: 1195 default:
1109 items[*numitems].item_sort = strdup_local(query_base_name(tmp, 0)); 1196 items[*numitems].item_sort = strdup_local (query_base_name (tmp, 0));
1110 items[*numitems].item_real = strdup_local(query_base_name(tmp, 1)); 1197 items[*numitems].item_real = strdup_local (query_base_name (tmp, 1));
1111 (*numitems)++; 1198 (*numitems)++;
1112 break; 1199 break;
1113 } 1200 }
1114 SET_FLAG(tmp, FLAG_UNPAID); 1201 SET_FLAG (tmp, FLAG_UNPAID);
1115} 1202}
1116 1203
1204void
1117void shop_listing(object *op) 1205shop_listing (object *op)
1118{ 1206{
1119 int i,j,numitems=0,numallocated=0, nx, ny; 1207 int i, j, numitems = 0, numallocated = 0, nx, ny;
1120 char *map_mark = (char *) calloc(MAGIC_MAP_SIZE * MAGIC_MAP_SIZE,1); 1208 char *map_mark = (char *) calloc (MAGIC_MAP_SIZE * MAGIC_MAP_SIZE, 1);
1121 object *stack; 1209 object *stack;
1122 shopinv *items; 1210 shopinv *items;
1123 1211
1124 /* Should never happen, but just in case a monster does apply a sign */ 1212 /* Should never happen, but just in case a monster does apply a sign */
1125 if (op->type!=PLAYER) return; 1213 if (op->type != PLAYER)
1214 return;
1126 1215
1127 new_draw_info(NDI_UNIQUE, 0, op, "\nThe shop contains:"); 1216 new_draw_info (NDI_UNIQUE, 0, op, "\nThe shop contains:");
1128 1217
1129 magic_mapping_mark(op, map_mark, 3); 1218 magic_mapping_mark (op, map_mark, 3);
1130 items=(shopinv*)malloc(40*sizeof(shopinv)); 1219 items = (shopinv *) malloc (40 * sizeof (shopinv));
1131 numallocated=40; 1220 numallocated = 40;
1132 1221
1133 /* Find all the appropriate items */ 1222 /* Find all the appropriate items */
1134 for (i=0; i<MAP_WIDTH(op->map); i++) { 1223 for (i = 0; i < MAP_WIDTH (op->map); i++)
1224 {
1135 for (j=0; j<MAP_HEIGHT(op->map); j++) { 1225 for (j = 0; j < MAP_HEIGHT (op->map); j++)
1226 {
1136 /* magic map code now centers the map on the object at MAGIC_MAP_HALF. 1227 /* magic map code now centers the map on the object at MAGIC_MAP_HALF.
1137 * 1228 *
1138 */ 1229 */
1139 nx = i - op->x + MAGIC_MAP_HALF; 1230 nx = i - op->x + MAGIC_MAP_HALF;
1140 ny = j - op->y + MAGIC_MAP_HALF; 1231 ny = j - op->y + MAGIC_MAP_HALF;
1141 /* unlikely, but really big shops could run into this issue */ 1232 /* 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; 1233 if (nx < 0 || ny < 0 || nx > MAGIC_MAP_SIZE || ny > MAGIC_MAP_SIZE)
1234 continue;
1143 1235
1144 if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR) { 1236 if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR)
1145 stack =get_map_ob(op->map,i,j); 1237 {
1238 stack = get_map_ob (op->map, i, j);
1146 1239
1147 while (stack) { 1240 while (stack)
1241 {
1148 if (QUERY_FLAG(stack, FLAG_UNPAID)) { 1242 if (QUERY_FLAG (stack, FLAG_UNPAID))
1149 if (numitems==numallocated) { 1243 {
1244 if (numitems == numallocated)
1245 {
1150 items=(shopinv*)realloc(items, sizeof(shopinv)*(numallocated+10)); 1246 items = (shopinv *) realloc (items, sizeof (shopinv) * (numallocated + 10));
1151 numallocated+=10; 1247 numallocated += 10;
1152 } 1248 }
1153 add_shop_item(stack, items, &numitems, &numallocated); 1249 add_shop_item (stack, items, &numitems, &numallocated);
1154 } 1250 }
1155 stack = stack->above; 1251 stack = stack->above;
1156 } 1252 }
1253 }
1254 }
1157 } 1255 }
1158 } 1256
1159 }
1160 free(map_mark); 1257 free (map_mark);
1258
1161 if (numitems == 0) { 1259 if (numitems == 0)
1260 {
1162 new_draw_info(NDI_UNIQUE, 0, op, "The shop is currently empty.\n"); 1261 new_draw_info (NDI_UNIQUE, 0, op, "The shop is currently empty.\n");
1163 free(items); 1262 free (items);
1164 return; 1263 return;
1165 } 1264 }
1265
1166 qsort(items, numitems, sizeof(shopinv), (int (*)(const void*, const void*))shop_sort); 1266 qsort (items, numitems, sizeof (shopinv), (int (*)(const void *, const void *)) shop_sort);
1167 1267
1168 for (i=0; i<numitems; i++) { 1268 for (i = 0; i < numitems; i++)
1269 {
1169 /* Collapse items of the same name together */ 1270 /* Collapse items of the same name together */
1170 if ((i+1)<numitems && !strcmp(items[i].item_real, items[i+1].item_real)) { 1271 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real))
1272 {
1171 items[i+1].nrof += items[i].nrof; 1273 items[i + 1].nrof += items[i].nrof;
1172 free(items[i].item_sort); 1274 free (items[i].item_sort);
1173 free(items[i].item_real); 1275 free (items[i].item_real);
1174 } else { 1276 }
1277 else
1278 {
1175 new_draw_info_format(NDI_UNIQUE, 0, op, "%d %s", 1279 new_draw_info_format (NDI_UNIQUE, 0, op, "%d %s",
1176 items[i].nrof? items[i].nrof:1, 1280 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); 1281 free (items[i].item_sort);
1179 free(items[i].item_real); 1282 free (items[i].item_real);
1180 } 1283 }
1181 } 1284 }
1182 free(items); 1285 free (items);
1183} 1286}
1287
1288/* elmex: this function checks whether the object is in a shop */
1289bool
1290is_in_shop (object *o)
1291{
1292 if (!o->map)
1293 return false;
1294
1295 return is_in_shop (o->map, o->x, o->y);
1296}
1297
1298/* elmex: this function checks whether we are in a shop or not */
1299bool
1300is_in_shop (mapstruct *map, int x, int y)
1301{
1302 for (object *floor = get_map_ob (map, x, y); floor; floor = floor->above)
1303 if (floor->type == SHOP_FLOOR)
1304 return true;
1305
1306 return false;
1307}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines