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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines