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.2 by elmex, Mon Aug 14 04:22:05 2006 UTC vs.
Revision 1.23 by root, Thu Dec 14 22:45:41 2006 UTC

1/*
2 * static char *rcsid_shop_c =
3 * "$Id: shop.C,v 1.2 2006/08/14 04:22:05 elmex Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 22*/
28 23
29#include <global.h> 24#include <global.h>
30#include <spells.h> 25#include <spells.h>
31#include <skills.h> 26#include <skills.h>
32#include <living.h> 27#include <living.h>
33#include <newclient.h> 28#include <newclient.h>
34#ifndef __CEXTRACT__ 29#ifndef __CEXTRACT__
35#include <sproto.h> 30# include <sproto.h>
36#endif 31#endif
37#include <math.h> 32#include <math.h>
38 33
39/* this is a measure of how effective store specialisation is. A general store 34/* this is a measure of how effective store specialisation is. A general store
40 * will offer this proportion of the 'maximum' price, a specialised store will 35 * will offer this proportion of the 'maximum' price, a specialised store will
46#define SPECIALISATION_EFFECT 0.5 41#define SPECIALISATION_EFFECT 0.5
47 42
48/* price a shopkeeper will give someone they neither like nor dislike */ 43/* price a shopkeeper will give someone they neither like nor dislike */
49#define NEUTRAL_RATIO 0.8 44#define NEUTRAL_RATIO 0.8
50 45
51static uint64 pay_from_container(object *pl, object *pouch, uint64 to_pay); 46static void pay_from_container (object *pl, object *pouch, sint64 &to_pay);
52static uint64 value_limit(uint64 val, int quantity, const object *who, int isshop); 47static sint64 value_limit (sint64 val, int quantity, const object *who, int isshop);
53static double shop_specialisation_ratio(const object *item, const mapstruct *map); 48static double shop_specialisation_ratio (const object *item, const maptile *map);
54static double shop_greed(const mapstruct *map); 49static double shop_greed (const maptile *map);
55 50
56#define NUM_COINS 4 /* number of coin types */ 51#define NUM_COINS 4 /* number of coin types */
57static const char* const coins[] = {"royalty", "platinacoin", "goldcoin", "silvercoin", NULL}; 52static const char *const coins[] = { "royalty", "platinacoin", "goldcoin", "silvercoin", NULL };
58 53
59/* Added F_TRUE flag to define.h to mean that the price should not 54/* Added F_TRUE flag to define.h to mean that the price should not
60 * be adjusted by players charisma. With F_TRUE, it returns the amount 55 * be adjusted by players charisma. With F_TRUE, it returns the amount
61 * that the item is worth, if it was sold, but unadjusted by charisma. 56 * that the item is worth, if it was sold, but unadjusted by charisma.
62 * This is needed for alchemy, to to determine what value of gold nuggets 57 * This is needed for alchemy, to to determine what value of gold nuggets
79 * thus remained 0. 74 * thus remained 0.
80 * 75 *
81 * Mark Wedel (mwedel@pyramid.com) 76 * Mark Wedel (mwedel@pyramid.com)
82 */ 77 */
83 78
84static uint64 approx_range; 79static sint64 approx_range;
85 80
81sint64
86uint64 query_cost(const object *tmp, object *who, int flag) { 82query_cost (const object *tmp, object *who, int flag)
83{
87 double val; 84 double val;
88 int number; /* used to better calculate value */ 85 int number; /* used to better calculate value */
89 int no_bargain; 86 int no_bargain;
90 int identified; 87 int identified;
91 int not_cursed; 88 int not_cursed;
92 int approximate; 89 int approximate;
93 int shop; 90 int shop;
94 double diff; 91 double diff;
95 92
96 approx_range = 0; 93 approx_range = 0;
97 94
98 no_bargain = flag & F_NO_BARGAIN; 95 no_bargain = flag & F_NO_BARGAIN;
99 identified = flag & F_IDENTIFIED; 96 identified = flag & F_IDENTIFIED;
100 not_cursed = flag & F_NOT_CURSED; 97 not_cursed = flag & F_NOT_CURSED;
101 approximate = flag & F_APPROX; 98 approximate = flag & F_APPROX;
102 shop = flag & F_SHOP; 99 shop = flag & F_SHOP;
103 flag &= ~(F_NO_BARGAIN|F_IDENTIFIED|F_NOT_CURSED|F_APPROX|F_SHOP); 100 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP);
104 101
105 if (tmp->type==MONEY) return (tmp->nrof * tmp->value); 102 if (tmp->type == MONEY)
103 return tmp->nrof * tmp->value;
104
106 if (tmp->type==GEM) { 105 if (tmp->type == GEM)
107 if (flag==F_TRUE) return (tmp->nrof * tmp->value);
108 if (flag==F_BUY) return (uint64) (1.03 * tmp->nrof * tmp->value);
109 if (flag==F_SELL) return (uint64) (0.97 * tmp->nrof * tmp->value);
110 LOG(llevError,"Query_cost: Gem type with unknown flag : %d\n", flag);
111 return 0;
112 } 106 {
107 if (flag == F_TRUE)
108 return (tmp->nrof * tmp->value);
109
110 if (flag == F_BUY)
111 return (sint64) (1.03 * tmp->nrof * tmp->value);
112
113 if (flag == F_SELL)
114 return (sint64) (0.97 * tmp->nrof * tmp->value);
115
116 LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ());
117 return 0;
118 }
119
113 number = tmp->nrof; 120 number = tmp->nrof;
114 if (number==0) number=1; 121 if (number == 0)
122 number = 1;
115 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED) || !need_identify(tmp) || identified) { 123 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified)
124 {
116 if (!not_cursed && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) 125 if (!not_cursed && (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)))
117 return 0; 126 return 0;
118 else 127 else
119 val=tmp->value * number; 128 val = tmp->value * number;
120 } 129 }
121 /* This area deals with objects that are not identified, but can be */ 130 /* This area deals with objects that are not identified, but can be */
122 else { 131 else
132 {
123 if (tmp->arch != NULL) { 133 if (tmp->arch != NULL)
134 {
124 if (flag == F_BUY) { 135 if (flag == F_BUY)
136 {
125 LOG(llevError, "Asking for buy-value of unidentified object.\n"); 137 LOG (llevError, "Asking for buy-value of unidentified object.\n");
126 val = tmp->arch->clone.value * 50 * number; 138 val = tmp->arch->clone.value * 50 * number;
127 } 139 }
128 else { /* Trying to sell something, or get true value */ 140 else
141 { /* Trying to sell something, or get true value */
129 if (tmp->type == POTION) 142 if (tmp->type == POTION)
130 val = number * 40; /* Don't want to give anything away */ 143 val = number * 40; /* Don't want to give anything away */
131 else { 144 else
145 {
132 /* Get 2/3'rd value for applied objects, 1/3'rd for totally 146 /* Get 2/3'rd value for applied objects, 1/3'rd for totally
133 * unknown objects 147 * unknown objects
134 */ 148 */
135 if (QUERY_FLAG(tmp, FLAG_BEEN_APPLIED)) 149 if (QUERY_FLAG (tmp, FLAG_BEEN_APPLIED))
136 val = number * tmp->arch->clone.value *2 / 3; 150 val = number * tmp->arch->clone.value * 2 / 3;
151 else
152 val = number * tmp->arch->clone.value / 3;
153 }
154 }
155 }
137 else 156 else
138 val = number * tmp->arch->clone.value / 3; 157 { /* No archetype with this object */
139 }
140 }
141 } else { /* No archetype with this object */
142 LOG(llevDebug,"In sell item: Have object with no archetype: %s\n", tmp->name); 158 LOG (llevDebug, "In sell item: Have object with no archetype: %s\n", &tmp->name);
143 if (flag == F_BUY) { 159 if (flag == F_BUY)
160 {
144 LOG(llevError, "Asking for buy-value of unidentified object without arch.\n"); 161 LOG (llevError, "Asking for buy-value of unidentified object without arch.\n");
145 val = number * tmp->value * 10; 162 val = number * tmp->value * 10;
163 }
164 else
165 val = number * tmp->value / 5;
166 }
146 } 167 }
147 else
148 val = number * tmp->value / 5;
149 }
150 }
151 168
152 /* If the item has been applied or identifed or does not need to be 169 /* If the item has been applied or identifed or does not need to be
153 * identified, AND the object is magical and the archetype is non 170 * identified, AND the object is magical and the archetype is non
154 * magical, then change values accordingly. The tmp->arch==NULL is 171 * magical, then change values accordingly. The tmp->arch==NULL is
155 * really just a check to prevent core dumps for when it checks 172 * really just a check to prevent core dumps for when it checks
156 * tmp->arch->clone.magic for any magic. The check for archetype 173 * tmp->arch->clone.magic for any magic. The check for archetype
157 * magic is to not give extra money for archetypes that are by 174 * magic is to not give extra money for archetypes that are by
158 * default magical. This is because the archetype value should have 175 * default magical. This is because the archetype value should have
159 * already figured in that value. 176 * already figured in that value.
160 */ 177 */
161 if((QUERY_FLAG(tmp, FLAG_IDENTIFIED)||!need_identify(tmp)||identified|| 178 if ((QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified ||
162 QUERY_FLAG(tmp, FLAG_BEEN_APPLIED)) && 179 QUERY_FLAG (tmp, FLAG_BEEN_APPLIED)) && tmp->magic && (tmp->arch == NULL || !tmp->arch->clone.magic))
163 tmp->magic&&(tmp->arch==NULL||!tmp->arch->clone.magic)) { 180 {
164 if(tmp->magic>0) 181 if (tmp->magic > 0)
165 val*=(3*tmp->magic*tmp->magic*tmp->magic); 182 val *= (3 * tmp->magic * tmp->magic * tmp->magic);
166 else 183 else
167 /* Note that tmp->magic is negative, so that this 184 /* Note that tmp->magic is negative, so that this
168 * will actually be something like val /=2, /=3, etc. 185 * will actually be something like val /=2, /=3, etc.
169 */
170 val/=(1-tmp->magic);
171 }
172
173 if (tmp->type==WAND) {
174 /* Value of the wand is multiplied by the number of
175 * charges. the treasure code already sets up the value
176 * 50 charges is used as the baseline.
177 */
178 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED) || !need_identify(tmp) || identified)
179 val=(val*tmp->stats.food) / 50;
180 else /* if not identified, presume one charge */
181 val/=50;
182 }
183
184 /* Limit amount of money you can get for really great items. */
185 if (flag==F_SELL)
186 val=value_limit(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 = (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 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 *
335static const 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 tmp->remove ();
596 coin_objs[i]->nrof += tmp->nrof;
597 esrv_del_item (pl->contr, tmp->count);
598 tmp->destroy ();
599 }
600 else
601 {
602 tmp->remove ();
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] = get_object(); 629 coin_objs[i] = arch_to_object (at);
582 copy_object(&at->clone, coin_objs[i]);
583 coin_objs[i]->nrof = 0; 630 coin_objs[i]->nrof = 0;
584 } 631 }
585 632
586 for (i=0; i<NUM_COINS; i++) { 633 for (i = 0; i < NUM_COINS; i++)
587 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;
588 638
589 if (coin_objs[i]->nrof*coin_objs[i]->value> remain) { 639 coin.nrof -= num_coins;
590 num_coins = remain / coin_objs[i]->value;
591 if ((uint64)num_coins*(uint64)coin_objs[i]->value < remain) num_coins++;
592 } else {
593 num_coins = coin_objs[i]->nrof;
594 }
595 remain -= (sint64) num_coins * (sint64)coin_objs[i]->value;
596 coin_objs[i]->nrof -= num_coins;
597 /* Now start making change. Start at the coin value 640 /* Now start making change. Start at the coin value
598 * below the one we just did, and work down to 641 * below the one we just did, and work down to
599 * the lowest value. 642 * the lowest value.
600 */ 643 */
601 count=i-1; 644 count = i - 1;
602 while (remain<0 && count>=0) { 645
646 while (to_pay < 0 && count >= 0)
647 {
603 num_coins = -remain/ coin_objs[count]->value; 648 num_coins = (-to_pay) / coin_objs[count]->value;
604 coin_objs[count]->nrof += num_coins; 649 coin_objs[count]->nrof += num_coins;
605 remain += num_coins * coin_objs[count]->value; 650 to_pay += num_coins * coin_objs[count]->value;
606 count--; 651 count--;
607 } 652 }
608 } 653 }
654
609 for (i=0; i<NUM_COINS; i++) { 655 for (i = 0; i < NUM_COINS; i++)
656 {
610 if (coin_objs[i]->nrof) { 657 if (coin_objs[i]->nrof)
658 {
611 object *tmp = insert_ob_in_ob(coin_objs[i], pouch); 659 object *tmp = insert_ob_in_ob (coin_objs[i], pouch);
612 660
613 esrv_send_item(pl, tmp); 661 esrv_send_item (pl, tmp);
614 esrv_send_item (pl, pouch); 662 esrv_send_item (pl, pouch);
615 if (pl != pouch) esrv_update_item (UPD_WEIGHT, pl, pouch); 663
664 if (pl != pouch)
665 esrv_update_item (UPD_WEIGHT, pl, pouch);
666
616 if (pl->type != PLAYER) { 667 if (pl->type != PLAYER)
617 esrv_send_item (pl, pl); 668 esrv_send_item (pl, pl);
669 }
670 else
671 coin_objs[i]->destroy ();
618 } 672 }
619 } else {
620 free_object(coin_objs[i]);
621 }
622 }
623 return(remain);
624} 673}
625 674
626/* 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
627 * 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.
628 * 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
629 * to the player 678 * to the player
630 */ 679 */
631 680int
632int can_pay(object *pl) { 681can_pay (object *pl)
682{
633 int unpaid_count = 0, i; 683 int unpaid_count = 0;
634 uint64 unpaid_price = 0; 684 sint64 unpaid_price = 0;
635 uint64 player_wealth = query_money(pl); 685 sint64 player_wealth = query_money (pl);
636 object *item; 686
637 uint32 coincount[NUM_COINS];
638 if (!pl || pl->type != PLAYER) { 687 if (!pl || pl->type != PLAYER)
688 {
639 LOG(llevError, "can_pay(): called against something that isn't a player\n"); 689 LOG (llevError, "can_pay(): called against something that isn't a player\n");
640 return 0; 690 return 0;
641 } 691 }
642 for (i=0; i< NUM_COINS; i++) coincount[i] = 0; 692
643 for (item = pl->inv;item;) { 693 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item)
644 if QUERY_FLAG(item, FLAG_UNPAID) { 694 if (QUERY_FLAG (item, FLAG_UNPAID))
695 {
645 unpaid_count++; 696 unpaid_count++;
646 unpaid_price += query_cost(item, pl, F_BUY | F_SHOP); 697 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP);
647 }
648 /* merely converting the player's monetary wealth won't do, if we did that,
649 * we could print the wrong numbers for the coins, so we count the money instead
650 */
651 for (i=0; i< NUM_COINS; i++)
652 if (!strcmp(coins[i], item->arch->name))
653 coincount[i] += item->nrof;
654 if (item->inv) item = item->inv;
655 else if (item->below) item = item->below;
656 else if (item->env && item->env != pl && item->env->below) item = item->env->below;
657 else item = NULL;
658 } 698 }
699
659 if (unpaid_price > player_wealth) { 700 if (unpaid_price > player_wealth)
660 char buf[MAX_BUF], coinbuf[MAX_BUF]; 701 {
661 int denominations = 0; 702 char buf[MAX_BUF];
662 int has_coins = NUM_COINS;
663 char cost[MAX_BUF]; 703 char cost[MAX_BUF];
664 char missing[MAX_BUF]; 704 char missing[MAX_BUF];
665 705
666 sprintf(cost, "%s", cost_string_from_value (unpaid_price, 0)); 706 snprintf (cost, MAX_BUF, "%s", cost_string_from_value (unpaid_price, 0));
667 sprintf(missing, "%s", cost_string_from_value (unpaid_price - player_wealth, 0)); 707 snprintf (missing, MAX_BUF, "%s", cost_string_from_value (unpaid_price - player_wealth, 0));
668 708
669 sprintf(buf, "You have %d unpaid items that would cost you %s. You need another %s to be able to afford that.", 709 snprintf (buf, MAX_BUF, "You have %d unpaid items that would cost you %s. You need another %s to be able to afford that.",
670 unpaid_count, cost, missing); 710 unpaid_count, cost, missing);
671 new_draw_info(NDI_UNIQUE, 0, pl, buf); 711 new_draw_info (NDI_UNIQUE, 0, pl, buf);
672 return 0; 712
713 return 0;
673 } 714 }
715 else
674 else return 1; 716 return 1;
675} 717}
676
677 718
678/* Better get_payment, descends containers looking for 719/* Better get_payment, descends containers looking for
679 * unpaid items, and pays for them. 720 * unpaid items, and pays for them.
680 * returns 0 if the player still has unpaid items. 721 * returns 0 if the player still has unpaid items.
681 * returns 1 if the player has paid for everything. 722 * returns 1 if the player has paid for everything.
682 * pl is the player buying the stuff. 723 * pl is the player buying the stuff.
683 * op is the object we are examining. If op has
684 * and inventory, we examine that. IF there are objects
685 * below op, we descend down.
686 */ 724 */
687int get_payment(object *pl, object *op) { 725int
726get_payment (object *pl)
727{
728 for (;;)
729 {
730 next_item:
731
732 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op)
733 {
734 if (QUERY_FLAG (op, FLAG_UNPAID))
735 {
688 char buf[MAX_BUF]; 736 char buf[MAX_BUF];
689 int ret=1; 737 snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP));
690 738
691 if (op!=NULL&&op->inv)
692 ret = get_payment(pl, op->inv);
693
694 if (!ret)
695 return 0;
696
697 if (op!=NULL&&op->below)
698 ret = get_payment (pl, op->below);
699
700 if (!ret)
701 return 0;
702
703 if(op!=NULL&&QUERY_FLAG(op,FLAG_UNPAID)) {
704 strncpy(buf,query_cost_string(op,pl,F_BUY | F_SHOP),MAX_BUF);
705 buf[MAX_BUF-1] = '\0';
706 if(!pay_for_item(op,pl)) { 739 if (!pay_for_item (op, pl))
740 {
707 uint64 i=query_cost(op,pl,F_BUY | F_SHOP) - query_money(pl); 741 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl);
742
708 CLEAR_FLAG(op, FLAG_UNPAID); 743 CLEAR_FLAG (op, FLAG_UNPAID);
709 new_draw_info_format(NDI_UNIQUE, 0, pl, 744 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op));
710 "You lack %s to buy %s.", cost_string_from_value (i, 0),
711 query_name(op));
712 SET_FLAG(op, FLAG_UNPAID); 745 SET_FLAG (op, FLAG_UNPAID);
713 return 0; 746 return 0;
747 }
714 } else { 748 else
715 object *tmp; 749 {
716 tag_t c = op->count; 750 object *tmp;
717 751
718 CLEAR_FLAG(op, FLAG_UNPAID); 752 CLEAR_FLAG (op, FLAG_UNPAID);
719 CLEAR_FLAG(op, FLAG_PLAYER_SOLD); 753 CLEAR_FLAG (op, FLAG_PLAYER_SOLD);
720 new_draw_info_format(NDI_UNIQUE, 0, op, 754 new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op));
721 "You paid %s for %s.",buf,query_name(op)); 755 tmp = merge_ob (op, NULL);
722 tmp=merge_ob(op,NULL); 756
723 if (pl->type == PLAYER) { 757 if (pl->type == PLAYER)
724 if (tmp) { /* it was merged */ 758 {
725 esrv_del_item (pl->contr, c); 759 if (tmp)
726 op = tmp; 760 { /* it was merged */
727 } 761 esrv_del_item (pl->contr, op->count);
762 op = tmp;
763 }
764
728 esrv_send_item(pl, op); 765 esrv_send_item (pl, op);
729 } 766 }
730 } 767
731 } 768 goto next_item;
769 }
770 }
771 }
772
732 return 1; 773 return 1;
774 }
733} 775}
734 776
735/* written by elmex: 777/* written by elmex:
736 * moved this code from sell_item () here to have a function 778 * moved this code from sell_item () here to have a function
737 * that pays the player an amount. Mainly put the code here to 779 * that pays the player an amount. Mainly put the code here to
741 * in his inventory anyway. This is the best alternative to not pay any money 783 * in his inventory anyway. This is the best alternative to not pay any money
742 * or put it on the ground under the player. This way the player can still 784 * or put it on the ground under the player. This way the player can still
743 * go somewhere and unload the money at a safe place. 785 * go somewhere and unload the money at a safe place.
744 * 786 *
745 */ 787 */
788void
746void pay_player (object *pl, uint64 amount) { 789pay_player (object *pl, sint64 amount)
790{
747 int count = 0; 791 int count = 0;
748 archetype *at = 0; 792 archetype *at = 0;
749 object *pouch = 0, *tmp = 0; 793 object *pouch = 0, *tmp = 0;
750 794
751 for (count = 0; coins[count] != NULL; count++) 795 for (count = 0; coins[count] != NULL; count++)
752 { 796 {
753 at = find_archetype (coins[count]); 797 at = archetype::find (coins[count]);
754 798
755 if (at == NULL) 799 if (at == NULL)
756 LOG(llevError, "Could not find %s archetype\n", coins[count]); 800 LOG (llevError, "Could not find %s archetype\n", coins[count]);
757 else if ((amount / at->clone.value) > 0) 801 else if ((amount / at->clone.value) > 0)
758 { 802 {
759 for (pouch=pl->inv; pouch; pouch=pouch->below) 803 for (pouch = pl->inv; pouch; pouch = pouch->below)
760 { 804 {
761 if (pouch->type == CONTAINER 805 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && pouch->race && strstr (pouch->race, "gold"))
762 && QUERY_FLAG (pouch, FLAG_APPLIED)
763 && pouch->race
764 && strstr (pouch->race, "gold"))
765 { 806 {
766 int w = at->clone.weight * (100 - pouch->stats.Str) / 100; 807 int w = at->clone.weight * (100 - pouch->stats.Str) / 100;
767 int n = amount / at->clone.value; 808 int n = amount / at->clone.value;
768 809
769 if (w == 0) 810 if (w == 0)
770 w = 1; /* Prevent divide by zero */ 811 w = 1; /* Prevent divide by zero */
771 812
772 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit)) 813 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit))
773 { 814 {
774 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n) 815 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n)
775 n = (pouch->weight_limit - pouch->carrying) / w; 816 n = (pouch->weight_limit - pouch->carrying) / w;
776 817
777 tmp = get_object (); 818 tmp = arch_to_object (at);
778 copy_object (&at->clone, tmp);
779 tmp->nrof = n; 819 tmp->nrof = n;
780 amount -= (uint64)tmp->nrof * (uint64)tmp->value; 820 amount -= tmp->nrof * tmp->value;
781 tmp = insert_ob_in_ob (tmp, pouch); 821 tmp = insert_ob_in_ob (tmp, pouch);
782 esrv_send_item (pl, tmp); 822 esrv_send_item (pl, tmp);
783 esrv_send_item (pl, pouch); 823 esrv_send_item (pl, pouch);
784 esrv_update_item (UPD_WEIGHT, pl, pouch); 824 esrv_update_item (UPD_WEIGHT, pl, pouch);
785 esrv_send_item (pl, pl); 825 esrv_send_item (pl, pl);
787 } 827 }
788 } 828 }
789 829
790 if (amount / at->clone.value > 0) 830 if (amount / at->clone.value > 0)
791 { 831 {
792 tmp = get_object (); 832 tmp = arch_to_object (at);
793 copy_object (&at->clone, tmp);
794 tmp->nrof = amount / tmp->value; 833 tmp->nrof = amount / tmp->value;
795 amount -= (uint64)tmp->nrof * (uint64)tmp->value; 834 amount -= tmp->nrof * tmp->value;
796 tmp = insert_ob_in_ob (tmp, pl); 835 tmp = insert_ob_in_ob (tmp, pl);
797 esrv_send_item (pl, tmp); 836 esrv_send_item (pl, tmp);
798 esrv_send_item (pl, pl); 837 esrv_send_item (pl, pl);
799 } 838 }
800 } 839 }
801 } 840 }
802 841
803 if (amount != 0) 842 if (amount != 0)
804#ifndef WIN32
805 LOG (llevError,"Warning - payment in pay_player () not zero: %llu\n", amount); 843 LOG (llevError, "Warning - payment in pay_player () not zero: %llu\n", amount);
806#else
807 LOG (llevError,"Warning - payment in pay_player () not zero: %I64u\n", amount);
808#endif
809} 844}
810 845
811/* elmex: this is for the bank plugin :( */ 846/* elmex: this is for the bank plugin :( */
847sint64
812uint64 pay_player_arch (object *pl, const char *arch, uint64 amount) { 848pay_player_arch (object *pl, const char *arch, sint64 amount)
849{
813 archetype *at = find_archetype (arch); 850 archetype *at = archetype::find (arch);
814 object *tmp = NULL; 851 object *tmp = NULL;
815 852
816 if (at == NULL) 853 if (at == NULL)
817 return 0; 854 return 0;
818 855
819 if (amount > 0) 856 if (amount > 0)
820 { 857 {
821 tmp = get_object (); 858 tmp = arch_to_object (at);
822 copy_object (&at->clone, tmp);
823 tmp->nrof = amount; 859 tmp->nrof = amount;
824 tmp = insert_ob_in_ob (tmp, pl); 860 tmp = insert_ob_in_ob (tmp, pl);
825 esrv_send_item (pl, tmp); 861 esrv_send_item (pl, tmp);
826 esrv_send_item (pl, pl); 862 esrv_send_item (pl, pl);
827 } 863 }
834 * buy item. 870 * buy item.
835 * 871 *
836 * Modified to fill available race: gold containers before dumping 872 * Modified to fill available race: gold containers before dumping
837 * remaining coins in character's inventory. 873 * remaining coins in character's inventory.
838 */ 874 */
875void
839void sell_item(object *op, object *pl) { 876sell_item (object *op, object *pl)
877{
840 uint64 amount = query_cost (op,pl,F_SELL | F_SHOP), extra_gain; 878 sint64 amount = query_cost (op, pl, F_SELL | F_SHOP), extra_gain;
841 879
842 if(pl==NULL || pl->type != PLAYER) 880 if (pl == NULL || pl->type != PLAYER)
843 { 881 {
844 LOG(llevDebug,"Object other than player tried to sell something.\n"); 882 LOG (llevDebug, "Object other than player tried to sell something.\n");
845 return; 883 return;
846 } 884 }
847 885
848 if(op->custom_name) 886 op->custom_name = 0;
849 FREE_AND_CLEAR_STR (op->custom_name);
850 887
851 if(!amount) 888 if (!amount)
852 { 889 {
853 new_draw_info_format (NDI_UNIQUE, 0, pl, 890 new_draw_info_format (NDI_UNIQUE, 0, pl, "We're not interested in %s.", query_name (op));
854 "We're not interested in %s.", query_name (op));
855 891
856 /* Even if the character doesn't get anything for it, it may still be 892 /* Even if the character doesn't get anything for it, it may still be
857 * worth something. If so, make it unpaid 893 * worth something. If so, make it unpaid
858 */ 894 */
859 if (op->value) 895 if (op->value)
860 { 896 {
861 SET_FLAG(op, FLAG_UNPAID); 897 SET_FLAG (op, FLAG_UNPAID);
862 SET_FLAG(op, FLAG_PLAYER_SOLD); 898 SET_FLAG (op, FLAG_PLAYER_SOLD);
863 } 899 }
864 900
865 identify (op); 901 identify (op);
866 return; 902 return;
867 } 903 }
872 * exp/10 -> 1 for each gold coin 908 * exp/10 -> 1 for each gold coin
873 */ 909 */
874 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP); 910 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP);
875 911
876 if (extra_gain > 0) 912 if (extra_gain > 0)
877 change_exp(pl, extra_gain / 10, "bargaining", SK_EXP_NONE); 913 change_exp (pl, extra_gain / 10, "bargaining", SK_EXP_NONE);
878 914
879 pay_player (pl, amount); 915 pay_player (pl, amount);
880 916
881 new_draw_info_format (NDI_UNIQUE, 0, pl, 917 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.", query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op));
882 "You receive %s for %s.", query_cost_string (op, pl, F_SELL | F_SHOP),
883 query_name (op));
884 918
885 SET_FLAG (op, FLAG_UNPAID); 919 SET_FLAG (op, FLAG_UNPAID);
886 identify (op); 920 identify (op);
887} 921}
888 922
890/* returns a double that is the ratio of the price that a shop will offer for 924/* returns a double that is the ratio of the price that a shop will offer for
891 * item based on the shops specialisation. Does not take account of greed, 925 * item based on the shops specialisation. Does not take account of greed,
892 * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any 926 * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any
893 * event is never less than 0.1 (calling functions divide by it) 927 * event is never less than 0.1 (calling functions divide by it)
894 */ 928 */
929static double
895static double shop_specialisation_ratio(const object *item, const mapstruct *map) { 930shop_specialisation_ratio (const object *item, const maptile *map)
931{
896 shopitems *items=map->shopitems; 932 shopitems *items = map->shopitems;
897 double ratio = SPECIALISATION_EFFECT, likedness=0.001; 933 double ratio = SPECIALISATION_EFFECT, likedness = 0.001;
898 int i; 934 int i;
899 935
900 if (item==NULL) { 936 if (item == NULL)
937 {
901 LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path); 938 LOG (llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path);
902 return 0; 939 return 0;
903 } 940 }
941
904 if (!item->type) { 942 if (!item->type)
943 {
905 LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type\n"); 944 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
906 /* 945 /*
907 * I'm not really sure what the /right/ thing to do here is, these types of 946 * I'm not really sure what the /right/ thing to do here is, these types of
908 * item shouldn't exist anyway, but returning the ratio is probably the best bet.." 947 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
909 */ 948 */
910 return ratio; 949 return ratio;
911 } 950 }
951
912 if (map->shopitems) { 952 if (map->shopitems)
953 {
913 for (i=0; i<items[0].index; i++) 954 for (i = 0; i < items[0].index; i++)
914 if (items[i].typenum==item->type || (!items[i].typenum && likedness == 0.001)) 955 if (items[i].typenum == item->type || (!items[i].typenum && likedness == 0.001))
915 likedness = items[i].strength/100.0; 956 likedness = items[i].strength / 100.0;
916 } 957 }
917 if (likedness > 1.0) { /* someone has been rather silly with the map headers. */ 958
959 if (likedness > 1.0)
960 { /* someone has been rather silly with the map headers. */
918 LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", 961 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, map->path);
919 item->type, map->path);
920 likedness = 1.0; 962 likedness = 1.0;
921 } 963 }
964
922 if (likedness < -1.0) { 965 if (likedness < -1.0)
966 {
923 LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", 967 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, map->path);
924 item->type, map->path);
925 likedness = -1.0; 968 likedness = -1.0;
926 } 969 }
970
927 ratio = ratio + (1.0-ratio) * likedness; 971 ratio = ratio + (1.0 - ratio) * likedness;
928 if (ratio <= 0.1) ratio=0.1; /* if the ratio were much lower than this, we would get silly prices */ 972
973 if (ratio <= 0.1)
974 ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */
975
929 return ratio; 976 return ratio;
930} 977}
931 978
932/*returns the greed of the shop on map, or 1 if it isn't specified. */ 979/*returns the greed of the shop on map, or 1 if it isn't specified. */
933static double shop_greed(const mapstruct *map) { 980static double
981shop_greed (const maptile *map)
982{
934 double greed=1.0; 983 double greed = 1.0;
984
935 if (map->shopgreed) 985 if (map->shopgreed)
936 return map->shopgreed; 986 return map->shopgreed;
937 return greed; 987 return greed;
938} 988}
939 989
940/* Returns a double based on how much the shopkeeper approves of the player. 990/* Returns a double based on how much the shopkeeper approves of the player.
941 * this is based on the race of the shopkeeper and that of the player. 991 * this is based on the race of the shopkeeper and that of the player.
942 */ 992 */
993double
943double shopkeeper_approval(const mapstruct *map, const object *player) { 994shopkeeper_approval (const maptile *map, const object *player)
995{
944 double approval=1.0; 996 double approval = 1.0;
945 997
946 if (map->shoprace) { 998 if (map->shoprace)
999 {
947 approval=NEUTRAL_RATIO; 1000 approval = NEUTRAL_RATIO;
948 if (player->race && !strcmp(player->race, map->shoprace)) approval = 1.0; 1001 if (player->race && !strcmp (player->race, map->shoprace))
1002 approval = 1.0;
949 } 1003 }
1004
950 return approval; 1005 return approval;
951} 1006}
952 1007
953/* limit the value of items based on the wealth of the shop. If the item is close 1008/* limit the value of items based on the wealth of the shop. If the item is close
954 * to the maximum value a shop will offer, we start to reduce it, if the item is 1009 * to the maximum value a shop will offer, we start to reduce it, if the item is
955 * below the minimum value the shop is prepared to trade in, then we don't 1010 * below the minimum value the shop is prepared to trade in, then we don't
956 * want it and offer nothing. If it isn't a shop, check whether we should do generic 1011 * want it and offer nothing. If it isn't a shop, check whether we should do generic
957 * value reduction. 1012 * value reduction.
958 * 1013 *
959 */ 1014 */
1015static sint64
960static uint64 value_limit (uint64 val, int quantity, const object *who, int isshop) { 1016value_limit (sint64 val, int quantity, const object *who, int isshop)
1017{
961 uint64 newval, unit_price, tmpshopmax; 1018 sint64 newval, unit_price, tmpshopmax;
962 mapstruct *map; 1019 maptile *map;
963 1020
964 unit_price = val / quantity; 1021 unit_price = val / quantity;
965 1022
966 if (!isshop || !who) 1023 if (!isshop || !who)
967 { 1024 {
968 if (unit_price > 250000) 1025 if (unit_price > 250000)
969 newval = (uint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.); 1026 newval = (sint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.);
970 else 1027 else
971 newval = unit_price; 1028 newval = unit_price;
972 } 1029 }
973 else 1030 else
974 { 1031 {
975 if (!who->map) 1032 if (!who->map)
976 { 1033 {
977 LOG(llevError, "value_limit: asked shop price for ob %s on NULL map\n", who->name); 1034 LOG (llevError, "value_limit: asked shop price for ob %s on NULL map\n", &who->name);
978 return val; 1035 return val;
979 } 1036 }
980 1037
981 map = who->map; 1038 map = who->map;
982 1039
983 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default 1040 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default
984 1041
985 if (map->shopmin && unit_price < map->shopmin) 1042 if (map->shopmin && unit_price < map->shopmin)
986 return 0; 1043 return 0;
987 else if (unit_price > tmpshopmax / 2) 1044 else if (unit_price > tmpshopmax / 2)
988 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax); 1045 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax);
989 else 1046 else
990 newval=unit_price; 1047 newval = unit_price;
991 } 1048 }
992 1049
993 newval *= quantity; 1050 newval *= quantity;
994 1051
995 return newval; 1052 return newval;
996} 1053}
997 1054
998/* gives a desciption of the shop on their current map to the player op. */ 1055/* gives a desciption of the shop on their current map to the player op. */
1056int
999int describe_shop(const object *op) { 1057describe_shop (const object *op)
1058{
1000 mapstruct *map = op->map; 1059 maptile *map = op->map;
1060
1001 /*shopitems *items=map->shopitems;*/ 1061 /*shopitems *items=map->shopitems; */
1002 int pos=0, i; 1062 int pos = 0, i;
1003 double opinion=0; 1063 double opinion = 0;
1004 char tmp[MAX_BUF]="\0"; 1064 char tmp[MAX_BUF] = "\0";
1065
1005 if (op->type != PLAYER) return 0; 1066 if (op->type != PLAYER)
1067 return 0;
1006 1068
1007 /*check if there is a shop specified for this map */ 1069 /*check if there is a shop specified for this map */
1008 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax) { 1070 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax)
1071 {
1009 new_draw_info(NDI_UNIQUE,0,op,"From looking at the nearby shop you determine that it trades in:"); 1072 new_draw_info (NDI_UNIQUE, 0, op, "From looking at the nearby shop you determine that it trades in:");
1073
1010 if (map->shopitems) { 1074 if (map->shopitems)
1011 for (i=0; i < map->shopitems[0].index; i++) { 1075 for (i = 0; i < map->shopitems[0].index; i++)
1012 if (map->shopitems[i].name && map->shopitems[i].strength > 10) { 1076 if (map->shopitems[i].name && map->shopitems[i].strength > 10)
1077 {
1013 snprintf(tmp+pos, sizeof(tmp)-pos, "%s, ", map->shopitems[i].name_pl); 1078 snprintf (tmp + pos, sizeof (tmp) - pos, "%s, ", map->shopitems[i].name_pl);
1014 pos += strlen(tmp+pos); 1079 pos += strlen (tmp + pos);
1015 } 1080 }
1016 } 1081
1017 } 1082 if (!pos)
1018 if (!pos) strcat(tmp, "a little of everything."); 1083 strcat (tmp, "a little of everything.");
1019 1084
1020 /* format the string into a list */ 1085 /* format the string into a list */
1021 make_list_like(tmp); 1086 make_list_like (tmp);
1022 new_draw_info_format(NDI_UNIQUE, 0, op, "%s", tmp); 1087 new_draw_info_format (NDI_UNIQUE, 0, op, "%s", tmp);
1023 1088
1024 if (map->shopmax) 1089 if (map->shopmax)
1025 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade for items above %s.", 1090 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade for items above %s.", cost_string_from_value (map->shopmax, 0));
1026 cost_string_from_value(map->shopmax, 0)); 1091
1027 if (map->shopmin) 1092 if (map->shopmin)
1028 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade in items worth less than %s.", 1093 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade in items worth less than %s.", cost_string_from_value (map->shopmin, 0));
1029 cost_string_from_value(map->shopmin, 0)); 1094
1030 if (map->shopgreed) { 1095 if (map->shopgreed)
1096 {
1031 if (map->shopgreed >2.0) 1097 if (map->shopgreed > 2.0)
1032 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge massively."); 1098 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge massively.");
1033 else if (map->shopgreed >1.5) 1099 else if (map->shopgreed > 1.5)
1034 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge substantially."); 1100 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge substantially.");
1035 else if (map->shopgreed >1.1) 1101 else if (map->shopgreed > 1.1)
1036 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge slightly."); 1102 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge slightly.");
1037 else if (map->shopgreed <0.9) 1103 else if (map->shopgreed < 0.9)
1038 new_draw_info(NDI_UNIQUE,0,op,"It tends to undercharge."); 1104 new_draw_info (NDI_UNIQUE, 0, op, "It tends to undercharge.");
1039 } 1105 }
1106
1040 if (map->shoprace) { 1107 if (map->shoprace)
1108 {
1041 opinion=shopkeeper_approval(map, op); 1109 opinion = shopkeeper_approval (map, op);
1042 if (opinion > 0.8) 1110 if (opinion > 0.8)
1043 new_draw_info(NDI_UNIQUE,0,op,"You think the shopkeeper likes you."); 1111 new_draw_info (NDI_UNIQUE, 0, op, "You think the shopkeeper likes you.");
1044 else if (opinion > 0.5) 1112 else if (opinion > 0.5)
1045 new_draw_info(NDI_UNIQUE,0,op,"The shopkeeper seems unconcerned by you."); 1113 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper seems unconcerned by you.");
1046 else 1114 else
1047 new_draw_info(NDI_UNIQUE,0,op,"The shopkeeper seems to have taken a dislike to you."); 1115 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper seems to have taken a dislike to you.");
1048 } 1116 }
1049 } 1117 }
1118 else
1050 else new_draw_info(NDI_UNIQUE,0,op,"There is no shop nearby."); 1119 new_draw_info (NDI_UNIQUE, 0, op, "There is no shop nearby.");
1051 1120
1052 return 1; 1121 return 1;
1053} 1122}
1054typedef struct shopinv { 1123
1124struct shopinv
1125{
1055 char *item_sort; 1126 char *item_sort;
1056 char *item_real; 1127 char *item_real;
1057 uint16 type; 1128 uint16 type;
1058 uint32 nrof; 1129 uint32 nrof;
1059} shopinv; 1130};
1060 1131
1061/* There are a lot fo extra casts in here just to suppress warnings - it 1132/* There are a lot fo extra casts in here just to suppress warnings - it
1062 * makes it look uglier than it really it. 1133 * makes it look uglier than it really it.
1063 * The format of the strings we get is type:name. So we first want to 1134 * The format of the strings we get is type:name. So we first want to
1064 * sort by type (numerical) - if the same type, then sort by name. 1135 * sort by type (numerical) - if the same type, then sort by name.
1065 */ 1136 */
1137static int
1066static int shop_sort(const void *a1, const void *a2) 1138shop_sort (const void *a1, const void *a2)
1067{ 1139{
1068 shopinv *s1 = (shopinv*)a1, *s2= (shopinv*)a2; 1140 shopinv *s1 = (shopinv *) a1, *s2 = (shopinv *) a2;
1069 1141
1070 if (s1->type<s2->type) return -1; 1142 if (s1->type < s2->type)
1143 return -1;
1071 if (s1->type>s2->type) return 1; 1144 if (s1->type > s2->type)
1145 return 1;
1146
1072 /* the type is the same (what atoi gets), so do a strcasecmp to sort 1147 /* the type is the same (what atoi gets), so do a strcasecmp to sort
1073 * via alphabetical order 1148 * via alphabetical order
1074 */ 1149 */
1075 return strcasecmp(s1->item_sort, s2->item_sort); 1150 return strcasecmp (s1->item_sort, s2->item_sort);
1076} 1151}
1077 1152
1153static void
1078static void add_shop_item(object *tmp, shopinv *items, int *numitems, int *numallocated) 1154add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated)
1079{ 1155{
1080#if 0 1156#if 0
1081 char buf[MAX_BUF]; 1157 char buf[MAX_BUF];
1082#endif 1158#endif
1083 /* clear unpaid flag so that doesn't come up in query 1159 /* clear unpaid flag so that doesn't come up in query
1084 * string. We clear nrof so that we can better sort 1160 * string. We clear nrof so that we can better sort
1085 * the object names. 1161 * the object names.
1086 */ 1162 */
1087 1163
1088 CLEAR_FLAG(tmp, FLAG_UNPAID); 1164 CLEAR_FLAG (tmp, FLAG_UNPAID);
1089 items[*numitems].nrof=tmp->nrof; 1165 items[*numitems].nrof = tmp->nrof;
1090 /* Non mergable items have nrof of 0, but count them as one 1166 /* Non mergable items have nrof of 0, but count them as one
1091 * so the display is properly. 1167 * so the display is properly.
1092 */ 1168 */
1093 if (tmp->nrof == 0) items[*numitems].nrof++; 1169 if (tmp->nrof == 0)
1170 items[*numitems].nrof++;
1094 items[*numitems].type=tmp->type; 1171 items[*numitems].type = tmp->type;
1095 1172
1096 switch (tmp->type) { 1173 switch (tmp->type)
1174 {
1097#if 0 1175#if 0
1098 case BOOTS: 1176 case BOOTS:
1099 case GLOVES: 1177 case GLOVES:
1100 case RING: 1178 case RING:
1101 case AMULET: 1179 case AMULET:
1102 case BRACERS: 1180 case BRACERS:
1103 case GIRDLE: 1181 case GIRDLE:
1104 sprintf(buf,"%s %s",query_base_name(tmp,0),describe_item(tmp, NULL)); 1182 sprintf (buf, "%s %s", query_base_name (tmp, 0), describe_item (tmp, NULL));
1105 items[*numitems].item_sort = strdup_local(buf); 1183 items[*numitems].item_sort = strdup (buf);
1106 sprintf(buf,"%s %s",query_name(tmp),describe_item(tmp, NULL)); 1184 sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL));
1107 items[*numitems].item_real = strdup_local(buf); 1185 items[*numitems].item_real = strdup (buf);
1108 (*numitems)++; 1186 (*numitems)++;
1109 break; 1187 break;
1110#endif 1188#endif
1111 1189
1112 default: 1190 default:
1113 items[*numitems].item_sort = strdup_local(query_base_name(tmp, 0)); 1191 items[*numitems].item_sort = strdup (query_base_name (tmp, 0));
1114 items[*numitems].item_real = strdup_local(query_base_name(tmp, 1)); 1192 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1115 (*numitems)++; 1193 (*numitems)++;
1116 break; 1194 break;
1117 } 1195 }
1118 SET_FLAG(tmp, FLAG_UNPAID); 1196 SET_FLAG (tmp, FLAG_UNPAID);
1119} 1197}
1120 1198
1199void
1121void shop_listing(object *op) 1200shop_listing (object *op)
1122{ 1201{
1123 int i,j,numitems=0,numallocated=0, nx, ny; 1202 int i, j, numitems = 0, numallocated = 0, nx, ny;
1124 char *map_mark = (char *) calloc(MAGIC_MAP_SIZE * MAGIC_MAP_SIZE,1); 1203 char *map_mark = (char *) calloc (MAGIC_MAP_SIZE * MAGIC_MAP_SIZE, 1);
1125 object *stack; 1204 object *stack;
1126 shopinv *items; 1205 shopinv *items;
1127 1206
1128 /* Should never happen, but just in case a monster does apply a sign */ 1207 /* Should never happen, but just in case a monster does apply a sign */
1129 if (op->type!=PLAYER) return; 1208 if (op->type != PLAYER)
1209 return;
1130 1210
1131 new_draw_info(NDI_UNIQUE, 0, op, "\nThe shop contains:"); 1211 new_draw_info (NDI_UNIQUE, 0, op, "\nThe shop contains:");
1132 1212
1133 magic_mapping_mark(op, map_mark, 3); 1213 magic_mapping_mark (op, map_mark, 3);
1134 items=(shopinv*)malloc(40*sizeof(shopinv)); 1214 items = (shopinv *) malloc (40 * sizeof (shopinv));
1135 numallocated=40; 1215 numallocated = 40;
1136 1216
1137 /* Find all the appropriate items */ 1217 /* Find all the appropriate items */
1138 for (i=0; i<MAP_WIDTH(op->map); i++) { 1218 for (i = 0; i < MAP_WIDTH (op->map); i++)
1219 {
1139 for (j=0; j<MAP_HEIGHT(op->map); j++) { 1220 for (j = 0; j < MAP_HEIGHT (op->map); j++)
1221 {
1140 /* magic map code now centers the map on the object at MAGIC_MAP_HALF. 1222 /* magic map code now centers the map on the object at MAGIC_MAP_HALF.
1141 * 1223 *
1142 */ 1224 */
1143 nx = i - op->x + MAGIC_MAP_HALF; 1225 nx = i - op->x + MAGIC_MAP_HALF;
1144 ny = j - op->y + MAGIC_MAP_HALF; 1226 ny = j - op->y + MAGIC_MAP_HALF;
1145 /* unlikely, but really big shops could run into this issue */ 1227 /* unlikely, but really big shops could run into this issue */
1146 if (nx < 0 || ny < 0 || nx > MAGIC_MAP_SIZE || ny > MAGIC_MAP_SIZE) continue; 1228 if (nx < 0 || ny < 0 || nx > MAGIC_MAP_SIZE || ny > MAGIC_MAP_SIZE)
1229 continue;
1147 1230
1148 if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR) { 1231 if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR)
1149 stack =get_map_ob(op->map,i,j); 1232 {
1233 stack = get_map_ob (op->map, i, j);
1150 1234
1151 while (stack) { 1235 while (stack)
1236 {
1152 if (QUERY_FLAG(stack, FLAG_UNPAID)) { 1237 if (QUERY_FLAG (stack, FLAG_UNPAID))
1153 if (numitems==numallocated) { 1238 {
1239 if (numitems == numallocated)
1240 {
1154 items=(shopinv*)realloc(items, sizeof(shopinv)*(numallocated+10)); 1241 items = (shopinv *) realloc (items, sizeof (shopinv) * (numallocated + 10));
1155 numallocated+=10; 1242 numallocated += 10;
1156 } 1243 }
1157 add_shop_item(stack, items, &numitems, &numallocated); 1244 add_shop_item (stack, items, &numitems, &numallocated);
1158 } 1245 }
1159 stack = stack->above; 1246 stack = stack->above;
1160 } 1247 }
1248 }
1249 }
1161 } 1250 }
1162 } 1251
1163 }
1164 free(map_mark); 1252 free (map_mark);
1253
1165 if (numitems == 0) { 1254 if (numitems == 0)
1255 {
1166 new_draw_info(NDI_UNIQUE, 0, op, "The shop is currently empty.\n"); 1256 new_draw_info (NDI_UNIQUE, 0, op, "The shop is currently empty.\n");
1167 free(items); 1257 free (items);
1168 return; 1258 return;
1169 } 1259 }
1260
1170 qsort(items, numitems, sizeof(shopinv), (int (*)(const void*, const void*))shop_sort); 1261 qsort (items, numitems, sizeof (shopinv), (int (*)(const void *, const void *)) shop_sort);
1171 1262
1172 for (i=0; i<numitems; i++) { 1263 for (i = 0; i < numitems; i++)
1264 {
1173 /* Collapse items of the same name together */ 1265 /* Collapse items of the same name together */
1174 if ((i+1)<numitems && !strcmp(items[i].item_real, items[i+1].item_real)) { 1266 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real))
1267 {
1175 items[i+1].nrof += items[i].nrof; 1268 items[i + 1].nrof += items[i].nrof;
1176 free(items[i].item_sort); 1269 free (items[i].item_sort);
1177 free(items[i].item_real); 1270 free (items[i].item_real);
1178 } else { 1271 }
1272 else
1273 {
1179 new_draw_info_format(NDI_UNIQUE, 0, op, "%d %s", 1274 new_draw_info_format (NDI_UNIQUE, 0, op, "%d %s",
1180 items[i].nrof? items[i].nrof:1, 1275 items[i].nrof ? items[i].nrof : 1, items[i].nrof == 1 ? items[i].item_sort : items[i].item_real);
1181 items[i].nrof==1?items[i].item_sort: items[i].item_real);
1182 free(items[i].item_sort); 1276 free (items[i].item_sort);
1183 free(items[i].item_real); 1277 free (items[i].item_real);
1184 } 1278 }
1185 } 1279 }
1186 free(items); 1280 free (items);
1187} 1281}
1282
1283/* elmex: this function checks whether the object is in a shop */
1284bool
1285is_in_shop (object *o)
1286{
1287 if (!o->map)
1288 return false;
1289
1290 return is_in_shop (o->map, o->x, o->y);
1291}
1292
1293/* elmex: this function checks whether we are in a shop or not */
1294bool
1295is_in_shop (maptile *map, int x, int y)
1296{
1297 for (object *floor = get_map_ob (map, x, y); floor; floor = floor->above)
1298 if (floor->type == SHOP_FLOOR)
1299 return true;
1300
1301 return false;
1302}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines