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.1 by elmex, Sun Aug 13 17:16:04 2006 UTC vs.
Revision 1.24 by root, Fri Dec 15 19:59:20 2006 UTC

1/*
2 * static char *rcsid_shop_c =
3 * "$Id: shop.C,v 1.1 2006/08/13 17:16:04 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>
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)
87 uint64 val; 80{
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(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 += (uint64) (val * diff);
239 else if (flag == F_SELL) val -= (uint64) (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=(uint64) ( 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=(uint64) ( 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=(uint64) (
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=(uint64) (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 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 *
335static const 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] = get_object(); 626 coin_objs[i] = arch_to_object (at);
582 copy_object(&at->clone, coin_objs[i]);
583 coin_objs[i]->nrof = 0; 627 coin_objs[i]->nrof = 0;
584 } 628 }
585 629
586 for (i=0; i<NUM_COINS; i++) { 630 for (i = 0; i < NUM_COINS; i++)
587 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;
588 635
589 if (coin_objs[i]->nrof*coin_objs[i]->value> remain) { 636 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 637 /* Now start making change. Start at the coin value
598 * below the one we just did, and work down to 638 * below the one we just did, and work down to
599 * the lowest value. 639 * the lowest value.
600 */ 640 */
601 count=i-1; 641 count = i - 1;
602 while (remain<0 && count>=0) { 642
643 while (to_pay < 0 && count >= 0)
644 {
603 num_coins = -remain/ coin_objs[count]->value; 645 num_coins = (-to_pay) / coin_objs[count]->value;
604 coin_objs[count]->nrof += num_coins; 646 coin_objs[count]->nrof += num_coins;
605 remain += num_coins * coin_objs[count]->value; 647 to_pay += num_coins * coin_objs[count]->value;
606 count--; 648 count--;
607 } 649 }
608 } 650 }
651
609 for (i=0; i<NUM_COINS; i++) { 652 for (i = 0; i < NUM_COINS; i++)
653 {
610 if (coin_objs[i]->nrof) { 654 if (coin_objs[i]->nrof)
655 {
611 object *tmp = insert_ob_in_ob(coin_objs[i], pouch); 656 object *tmp = insert_ob_in_ob (coin_objs[i], pouch);
612 657
613 esrv_send_item(pl, tmp); 658 esrv_send_item (pl, tmp);
614 esrv_send_item (pl, pouch); 659 esrv_send_item (pl, pouch);
615 if (pl != pouch) esrv_update_item (UPD_WEIGHT, pl, pouch); 660
661 if (pl != pouch)
662 esrv_update_item (UPD_WEIGHT, pl, pouch);
663
616 if (pl->type != PLAYER) { 664 if (pl->type != PLAYER)
617 esrv_send_item (pl, pl); 665 esrv_send_item (pl, pl);
666 }
667 else
668 coin_objs[i]->destroy ();
618 } 669 }
619 } else {
620 free_object(coin_objs[i]);
621 }
622 }
623 return(remain);
624} 670}
625 671
626/* 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
627 * 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.
628 * 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
629 * to the player 675 * to the player
630 */ 676 */
631 677int
632int can_pay(object *pl) { 678can_pay (object *pl)
679{
633 int unpaid_count = 0, i; 680 int unpaid_count = 0;
634 uint64 unpaid_price = 0; 681 sint64 unpaid_price = 0;
635 uint64 player_wealth = query_money(pl); 682 sint64 player_wealth = query_money (pl);
636 object *item; 683
637 uint32 coincount[NUM_COINS];
638 if (!pl || pl->type != PLAYER) { 684 if (!pl || pl->type != PLAYER)
685 {
639 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");
640 return 0; 687 return 0;
641 } 688 }
642 for (i=0; i< NUM_COINS; i++) coincount[i] = 0; 689
643 for (item = pl->inv;item;) { 690 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item)
644 if QUERY_FLAG(item, FLAG_UNPAID) { 691 if (QUERY_FLAG (item, FLAG_UNPAID))
692 {
645 unpaid_count++; 693 unpaid_count++;
646 unpaid_price += query_cost(item, pl, F_BUY | F_SHOP); 694 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 } 695 }
696
659 if (unpaid_price > player_wealth) { 697 if (unpaid_price > player_wealth)
660 char buf[MAX_BUF], coinbuf[MAX_BUF]; 698 {
661 int denominations = 0; 699 char buf[MAX_BUF];
662 int has_coins = NUM_COINS;
663 char cost[MAX_BUF]; 700 char cost[MAX_BUF];
664 char missing[MAX_BUF]; 701 char missing[MAX_BUF];
665 702
666 sprintf(cost, "%s", cost_string_from_value (unpaid_price, 0)); 703 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)); 704 snprintf (missing, MAX_BUF, "%s", cost_string_from_value (unpaid_price - player_wealth, 0));
668 705
669 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.",
670 unpaid_count, cost, missing); 707 unpaid_count, cost, missing);
671 new_draw_info(NDI_UNIQUE, 0, pl, buf); 708 new_draw_info (NDI_UNIQUE, 0, pl, buf);
672 return 0; 709
710 return 0;
673 } 711 }
712 else
674 else return 1; 713 return 1;
675} 714}
676
677 715
678/* Better get_payment, descends containers looking for 716/* Better get_payment, descends containers looking for
679 * unpaid items, and pays for them. 717 * unpaid items, and pays for them.
680 * returns 0 if the player still has unpaid items. 718 * returns 0 if the player still has unpaid items.
681 * returns 1 if the player has paid for everything. 719 * returns 1 if the player has paid for everything.
682 * pl is the player buying the stuff. 720 * 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 */ 721 */
687int 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 {
688 char buf[MAX_BUF]; 733 char buf[MAX_BUF];
689 int ret=1; 734 snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP));
690 735
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)) { 736 if (!pay_for_item (op, pl))
737 {
707 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
708 CLEAR_FLAG(op, FLAG_UNPAID); 740 CLEAR_FLAG (op, FLAG_UNPAID);
709 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));
710 "You lack %s to buy %s.", cost_string_from_value (i, 0),
711 query_name(op));
712 SET_FLAG(op, FLAG_UNPAID); 742 SET_FLAG (op, FLAG_UNPAID);
713 return 0; 743 return 0;
744 }
714 } else { 745 else
715 object *tmp; 746 {
716 tag_t c = op->count; 747 object *tmp;
717 748
718 CLEAR_FLAG(op, FLAG_UNPAID); 749 CLEAR_FLAG (op, FLAG_UNPAID);
719 CLEAR_FLAG(op, FLAG_PLAYER_SOLD); 750 CLEAR_FLAG (op, FLAG_PLAYER_SOLD);
720 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));
721 "You paid %s for %s.",buf,query_name(op)); 752 tmp = merge_ob (op, NULL);
722 tmp=merge_ob(op,NULL); 753
723 if (pl->type == PLAYER) { 754 if (pl->type == PLAYER)
724 if (tmp) { /* it was merged */ 755 {
725 esrv_del_item (pl->contr, c); 756 if (tmp)
726 op = tmp; 757 { /* it was merged */
727 } 758 esrv_del_item (pl->contr, op->count);
759 op = tmp;
760 }
761
728 esrv_send_item(pl, op); 762 esrv_send_item (pl, op);
729 } 763 }
730 } 764
731 } 765 goto next_item;
766 }
767 }
768 }
769
732 return 1; 770 return 1;
771 }
733} 772}
734 773
735/* written by elmex: 774/* written by elmex:
736 * moved this code from sell_item () here to have a function 775 * moved this code from sell_item () here to have a function
737 * 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
741 * 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
742 * 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
743 * go somewhere and unload the money at a safe place. 782 * go somewhere and unload the money at a safe place.
744 * 783 *
745 */ 784 */
785void
746void pay_player (object *pl, uint64 amount) { 786pay_player (object *pl, sint64 amount)
787{
747 int count = 0; 788 int count = 0;
748 archetype *at = 0; 789 archetype *at = 0;
749 object *pouch = 0, *tmp = 0; 790 object *pouch = 0, *tmp = 0;
750 791
751 for (count = 0; coins[count] != NULL; count++) 792 for (count = 0; coins[count] != NULL; count++)
752 { 793 {
753 at = find_archetype (coins[count]); 794 at = archetype::find (coins[count]);
754 795
755 if (at == NULL) 796 if (at == NULL)
756 LOG(llevError, "Could not find %s archetype\n", coins[count]); 797 LOG (llevError, "Could not find %s archetype\n", coins[count]);
757 else if ((amount / at->clone.value) > 0) 798 else if ((amount / at->clone.value) > 0)
758 { 799 {
759 for (pouch=pl->inv; pouch; pouch=pouch->below) 800 for (pouch = pl->inv; pouch; pouch = pouch->below)
760 { 801 {
761 if (pouch->type == CONTAINER 802 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 { 803 {
766 int w = at->clone.weight * (100 - pouch->stats.Str) / 100; 804 int w = at->clone.weight * (100 - pouch->stats.Str) / 100;
767 int n = amount / at->clone.value; 805 int n = amount / at->clone.value;
768 806
769 if (w == 0) 807 if (w == 0)
770 w = 1; /* Prevent divide by zero */ 808 w = 1; /* Prevent divide by zero */
771 809
772 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))
773 { 811 {
774 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n) 812 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n)
775 n = (pouch->weight_limit - pouch->carrying) / w; 813 n = (pouch->weight_limit - pouch->carrying) / w;
776 814
777 tmp = get_object (); 815 tmp = arch_to_object (at);
778 copy_object (&at->clone, tmp);
779 tmp->nrof = n; 816 tmp->nrof = n;
780 amount -= (uint64)tmp->nrof * (uint64)tmp->value; 817 amount -= tmp->nrof * tmp->value;
781 tmp = insert_ob_in_ob (tmp, pouch); 818 tmp = insert_ob_in_ob (tmp, pouch);
782 esrv_send_item (pl, tmp); 819 esrv_send_item (pl, tmp);
783 esrv_send_item (pl, pouch); 820 esrv_send_item (pl, pouch);
784 esrv_update_item (UPD_WEIGHT, pl, pouch); 821 esrv_update_item (UPD_WEIGHT, pl, pouch);
785 esrv_send_item (pl, pl); 822 esrv_send_item (pl, pl);
787 } 824 }
788 } 825 }
789 826
790 if (amount / at->clone.value > 0) 827 if (amount / at->clone.value > 0)
791 { 828 {
792 tmp = get_object (); 829 tmp = arch_to_object (at);
793 copy_object (&at->clone, tmp);
794 tmp->nrof = amount / tmp->value; 830 tmp->nrof = amount / tmp->value;
795 amount -= (uint64)tmp->nrof * (uint64)tmp->value; 831 amount -= tmp->nrof * tmp->value;
796 tmp = insert_ob_in_ob (tmp, pl); 832 tmp = insert_ob_in_ob (tmp, pl);
797 esrv_send_item (pl, tmp); 833 esrv_send_item (pl, tmp);
798 esrv_send_item (pl, pl); 834 esrv_send_item (pl, pl);
799 } 835 }
800 } 836 }
801 } 837 }
802 838
803 if (amount != 0) 839 if (amount != 0)
804#ifndef WIN32
805 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);
806#else
807 LOG (llevError,"Warning - payment in pay_player () not zero: %I64u\n", amount);
808#endif
809} 841}
810 842
811/* elmex: this is for the bank plugin :( */ 843/* elmex: this is for the bank plugin :( */
844sint64
812uint64 pay_player_arch (object *pl, const char *arch, uint64 amount) { 845pay_player_arch (object *pl, const char *arch, sint64 amount)
846{
813 archetype *at = find_archetype (arch); 847 archetype *at = archetype::find (arch);
814 object *tmp = NULL; 848 object *tmp = NULL;
815 849
816 if (at == NULL) 850 if (at == NULL)
817 return 0; 851 return 0;
818 852
819 if (amount > 0) 853 if (amount > 0)
820 { 854 {
821 tmp = get_object (); 855 tmp = arch_to_object (at);
822 copy_object (&at->clone, tmp);
823 tmp->nrof = amount; 856 tmp->nrof = amount;
824 tmp = insert_ob_in_ob (tmp, pl); 857 tmp = insert_ob_in_ob (tmp, pl);
825 esrv_send_item (pl, tmp); 858 esrv_send_item (pl, tmp);
826 esrv_send_item (pl, pl); 859 esrv_send_item (pl, pl);
827 } 860 }
834 * buy item. 867 * buy item.
835 * 868 *
836 * Modified to fill available race: gold containers before dumping 869 * Modified to fill available race: gold containers before dumping
837 * remaining coins in character's inventory. 870 * remaining coins in character's inventory.
838 */ 871 */
872void
839void sell_item(object *op, object *pl) { 873sell_item (object *op, object *pl)
874{
840 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;
841 876
842 if(pl==NULL || pl->type != PLAYER) 877 if (pl == NULL || pl->type != PLAYER)
843 { 878 {
844 LOG(llevDebug,"Object other than player tried to sell something.\n"); 879 LOG (llevDebug, "Object other than player tried to sell something.\n");
845 return; 880 return;
846 } 881 }
847 882
848 if(op->custom_name) 883 op->custom_name = 0;
849 FREE_AND_CLEAR_STR (op->custom_name);
850 884
851 if(!amount) 885 if (!amount)
852 { 886 {
853 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));
854 "We're not interested in %s.", query_name (op));
855 888
856 /* 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
857 * worth something. If so, make it unpaid 890 * worth something. If so, make it unpaid
858 */ 891 */
859 if (op->value) 892 if (op->value)
860 { 893 {
861 SET_FLAG(op, FLAG_UNPAID); 894 SET_FLAG (op, FLAG_UNPAID);
862 SET_FLAG(op, FLAG_PLAYER_SOLD); 895 SET_FLAG (op, FLAG_PLAYER_SOLD);
863 } 896 }
864 897
865 identify (op); 898 identify (op);
866 return; 899 return;
867 } 900 }
872 * exp/10 -> 1 for each gold coin 905 * exp/10 -> 1 for each gold coin
873 */ 906 */
874 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);
875 908
876 if (extra_gain > 0) 909 if (extra_gain > 0)
877 change_exp(pl, extra_gain / 10, "bargaining", SK_EXP_NONE); 910 change_exp (pl, extra_gain / 10, "bargaining", SK_EXP_NONE);
878 911
879 pay_player (pl, amount); 912 pay_player (pl, amount);
880 913
881 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));
882 "You receive %s for %s.", query_cost_string (op, pl, F_SELL | F_SHOP),
883 query_name (op));
884 915
885 SET_FLAG (op, FLAG_UNPAID); 916 SET_FLAG (op, FLAG_UNPAID);
886 identify (op); 917 identify (op);
887} 918}
888 919
890/* 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
891 * 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,
892 * 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
893 * 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)
894 */ 925 */
926static double
895static double shop_specialisation_ratio(const object *item, const mapstruct *map) { 927shop_specialisation_ratio (const object *item, const maptile *map)
928{
896 shopitems *items=map->shopitems; 929 shopitems *items = map->shopitems;
897 double ratio = SPECIALISATION_EFFECT, likedness=0.001; 930 double ratio = SPECIALISATION_EFFECT, likedness = 0.001;
898 int i; 931 int i;
899 932
900 if (item==NULL) { 933 if (item == NULL)
934 {
901 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);
902 return 0; 936 return 0;
903 } 937 }
938
904 if (!item->type) { 939 if (!item->type)
940 {
905 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");
906 /* 942 /*
907 * 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
908 * 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.."
909 */ 945 */
910 return ratio; 946 return ratio;
911 } 947 }
948
912 if (map->shopitems) { 949 if (map->shopitems)
950 {
913 for (i=0; i<items[0].index; i++) 951 for (i = 0; i < items[0].index; i++)
914 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))
915 likedness = items[i].strength/100.0; 953 likedness = items[i].strength / 100.0;
916 } 954 }
917 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. */
918 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);
919 item->type, map->path);
920 likedness = 1.0; 959 likedness = 1.0;
921 } 960 }
961
922 if (likedness < -1.0) { 962 if (likedness < -1.0)
963 {
923 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);
924 item->type, map->path);
925 likedness = -1.0; 965 likedness = -1.0;
926 } 966 }
967
927 ratio = ratio + (1.0-ratio) * likedness; 968 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 */ 969
970 if (ratio <= 0.1)
971 ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */
972
929 return ratio; 973 return ratio;
930} 974}
931 975
932/*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. */
933static double shop_greed(const mapstruct *map) { 977static double
978shop_greed (const maptile *map)
979{
934 double greed=1.0; 980 double greed = 1.0;
981
935 if (map->shopgreed) 982 if (map->shopgreed)
936 return map->shopgreed; 983 return map->shopgreed;
937 return greed; 984 return greed;
938} 985}
939 986
940/* 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.
941 * 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.
942 */ 989 */
990double
943double shopkeeper_approval(const mapstruct *map, const object *player) { 991shopkeeper_approval (const maptile *map, const object *player)
992{
944 double approval=1.0; 993 double approval = 1.0;
945 994
946 if (map->shoprace) { 995 if (map->shoprace)
996 {
947 approval=NEUTRAL_RATIO; 997 approval = NEUTRAL_RATIO;
948 if (player->race && !strcmp(player->race, map->shoprace)) approval = 1.0; 998 if (player->race && !strcmp (player->race, map->shoprace))
999 approval = 1.0;
949 } 1000 }
1001
950 return approval; 1002 return approval;
951} 1003}
952 1004
953/* 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
954 * 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
955 * 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
956 * 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
957 * value reduction. 1009 * value reduction.
958 * 1010 *
959 */ 1011 */
1012static sint64
960static uint64 value_limit (uint64 val, int quantity, const object *who, int isshop) { 1013value_limit (sint64 val, int quantity, const object *who, int isshop)
1014{
961 uint64 newval, unit_price, tmpshopmax; 1015 sint64 newval, unit_price, tmpshopmax;
962 mapstruct *map; 1016 maptile *map;
963 1017
964 unit_price = val / quantity; 1018 unit_price = val / quantity;
965 1019
966 if (!isshop || !who) 1020 if (!isshop || !who)
967 { 1021 {
968 if (unit_price > 250000) 1022 if (unit_price > 250000)
969 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.);
970 else 1024 else
971 newval = unit_price; 1025 newval = unit_price;
972 } 1026 }
973 else 1027 else
974 { 1028 {
975 if (!who->map) 1029 if (!who->map)
976 { 1030 {
977 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);
978 return val; 1032 return val;
979 } 1033 }
980 1034
981 map = who->map; 1035 map = who->map;
982 1036
983 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default 1037 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default
984 1038
985 if (map->shopmin && unit_price < map->shopmin) 1039 if (map->shopmin && unit_price < map->shopmin)
986 return 0; 1040 return 0;
987 else if (unit_price > tmpshopmax / 2) 1041 else if (unit_price > tmpshopmax / 2)
988 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax); 1042 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax);
989 else 1043 else
990 newval=unit_price; 1044 newval = unit_price;
991 } 1045 }
992 1046
993 newval *= quantity; 1047 newval *= quantity;
994 1048
995 return newval; 1049 return newval;
996} 1050}
997 1051
998/* 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
999int describe_shop(const object *op) { 1054describe_shop (const object *op)
1055{
1000 mapstruct *map = op->map; 1056 maptile *map = op->map;
1057
1001 /*shopitems *items=map->shopitems;*/ 1058 /*shopitems *items=map->shopitems; */
1002 int pos=0, i; 1059 int pos = 0, i;
1003 double opinion=0; 1060 double opinion = 0;
1004 char tmp[MAX_BUF]="\0"; 1061 char tmp[MAX_BUF] = "\0";
1062
1005 if (op->type != PLAYER) return 0; 1063 if (op->type != PLAYER)
1064 return 0;
1006 1065
1007 /*check if there is a shop specified for this map */ 1066 /*check if there is a shop specified for this map */
1008 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax) { 1067 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax)
1068 {
1009 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
1010 if (map->shopitems) { 1071 if (map->shopitems)
1011 for (i=0; i < map->shopitems[0].index; i++) { 1072 for (i = 0; i < map->shopitems[0].index; i++)
1012 if (map->shopitems[i].name && map->shopitems[i].strength > 10) { 1073 if (map->shopitems[i].name && map->shopitems[i].strength > 10)
1074 {
1013 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);
1014 pos += strlen(tmp+pos); 1076 pos += strlen (tmp + pos);
1015 } 1077 }
1016 } 1078
1017 } 1079 if (!pos)
1018 if (!pos) strcat(tmp, "a little of everything."); 1080 strcat (tmp, "a little of everything.");
1019 1081
1020 /* format the string into a list */ 1082 /* format the string into a list */
1021 make_list_like(tmp); 1083 make_list_like (tmp);
1022 new_draw_info_format(NDI_UNIQUE, 0, op, "%s", tmp); 1084 new_draw_info_format (NDI_UNIQUE, 0, op, "%s", tmp);
1023 1085
1024 if (map->shopmax) 1086 if (map->shopmax)
1025 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));
1026 cost_string_from_value(map->shopmax, 0)); 1088
1027 if (map->shopmin) 1089 if (map->shopmin)
1028 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));
1029 cost_string_from_value(map->shopmin, 0)); 1091
1030 if (map->shopgreed) { 1092 if (map->shopgreed)
1093 {
1031 if (map->shopgreed >2.0) 1094 if (map->shopgreed > 2.0)
1032 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.");
1033 else if (map->shopgreed >1.5) 1096 else if (map->shopgreed > 1.5)
1034 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.");
1035 else if (map->shopgreed >1.1) 1098 else if (map->shopgreed > 1.1)
1036 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.");
1037 else if (map->shopgreed <0.9) 1100 else if (map->shopgreed < 0.9)
1038 new_draw_info(NDI_UNIQUE,0,op,"It tends to undercharge."); 1101 new_draw_info (NDI_UNIQUE, 0, op, "It tends to undercharge.");
1039 } 1102 }
1103
1040 if (map->shoprace) { 1104 if (map->shoprace)
1105 {
1041 opinion=shopkeeper_approval(map, op); 1106 opinion = shopkeeper_approval (map, op);
1042 if (opinion > 0.8) 1107 if (opinion > 0.8)
1043 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.");
1044 else if (opinion > 0.5) 1109 else if (opinion > 0.5)
1045 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.");
1046 else 1111 else
1047 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.");
1048 } 1113 }
1049 } 1114 }
1115 else
1050 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.");
1051 1117
1052 return 1; 1118 return 1;
1053} 1119}
1054typedef struct shopinv { 1120
1121struct shopinv
1122{
1055 char *item_sort; 1123 char *item_sort;
1056 char *item_real; 1124 char *item_real;
1057 uint16 type; 1125 uint16 type;
1058 uint32 nrof; 1126 uint32 nrof;
1059} shopinv; 1127};
1060 1128
1061/* 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
1062 * makes it look uglier than it really it. 1130 * makes it look uglier than it really it.
1063 * 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
1064 * 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.
1065 */ 1133 */
1134static int
1066static int shop_sort(const void *a1, const void *a2) 1135shop_sort (const void *a1, const void *a2)
1067{ 1136{
1068 shopinv *s1 = (shopinv*)a1, *s2= (shopinv*)a2; 1137 shopinv *s1 = (shopinv *) a1, *s2 = (shopinv *) a2;
1069 1138
1070 if (s1->type<s2->type) return -1; 1139 if (s1->type < s2->type)
1140 return -1;
1071 if (s1->type>s2->type) return 1; 1141 if (s1->type > s2->type)
1142 return 1;
1143
1072 /* 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
1073 * via alphabetical order 1145 * via alphabetical order
1074 */ 1146 */
1075 return strcasecmp(s1->item_sort, s2->item_sort); 1147 return strcasecmp (s1->item_sort, s2->item_sort);
1076} 1148}
1077 1149
1150static void
1078static void add_shop_item(object *tmp, shopinv *items, int *numitems, int *numallocated) 1151add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated)
1079{ 1152{
1080#if 0 1153#if 0
1081 char buf[MAX_BUF]; 1154 char buf[MAX_BUF];
1082#endif 1155#endif
1083 /* clear unpaid flag so that doesn't come up in query 1156 /* clear unpaid flag so that doesn't come up in query
1084 * string. We clear nrof so that we can better sort 1157 * string. We clear nrof so that we can better sort
1085 * the object names. 1158 * the object names.
1086 */ 1159 */
1087 1160
1088 CLEAR_FLAG(tmp, FLAG_UNPAID); 1161 CLEAR_FLAG (tmp, FLAG_UNPAID);
1089 items[*numitems].nrof=tmp->nrof; 1162 items[*numitems].nrof = tmp->nrof;
1090 /* 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
1091 * so the display is properly. 1164 * so the display is properly.
1092 */ 1165 */
1093 if (tmp->nrof == 0) items[*numitems].nrof++; 1166 if (tmp->nrof == 0)
1167 items[*numitems].nrof++;
1094 items[*numitems].type=tmp->type; 1168 items[*numitems].type = tmp->type;
1095 1169
1096 switch (tmp->type) { 1170 switch (tmp->type)
1171 {
1097#if 0 1172#if 0
1098 case BOOTS: 1173 case BOOTS:
1099 case GLOVES: 1174 case GLOVES:
1100 case RING: 1175 case RING:
1101 case AMULET: 1176 case AMULET:
1102 case BRACERS: 1177 case BRACERS:
1103 case GIRDLE: 1178 case GIRDLE:
1104 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));
1105 items[*numitems].item_sort = strdup_local(buf); 1180 items[*numitems].item_sort = strdup (buf);
1106 sprintf(buf,"%s %s",query_name(tmp),describe_item(tmp, NULL)); 1181 sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL));
1107 items[*numitems].item_real = strdup_local(buf); 1182 items[*numitems].item_real = strdup (buf);
1108 (*numitems)++; 1183 (*numitems)++;
1109 break; 1184 break;
1110#endif 1185#endif
1111 1186
1112 default: 1187 default:
1113 items[*numitems].item_sort = strdup_local(query_base_name(tmp, 0)); 1188 items[*numitems].item_sort = strdup (query_base_name (tmp, 0));
1114 items[*numitems].item_real = strdup_local(query_base_name(tmp, 1)); 1189 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1115 (*numitems)++; 1190 (*numitems)++;
1116 break; 1191 break;
1117 } 1192 }
1118 SET_FLAG(tmp, FLAG_UNPAID); 1193 SET_FLAG (tmp, FLAG_UNPAID);
1119} 1194}
1120 1195
1196void
1121void shop_listing(object *op) 1197shop_listing (object *op)
1122{ 1198{
1123 int i,j,numitems=0,numallocated=0, nx, ny; 1199 int i, j, numitems = 0, numallocated = 0, nx, ny;
1124 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);
1125 object *stack; 1201 object *stack;
1126 shopinv *items; 1202 shopinv *items;
1127 1203
1128 /* 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 */
1129 if (op->type!=PLAYER) return; 1205 if (op->type != PLAYER)
1206 return;
1130 1207
1131 new_draw_info(NDI_UNIQUE, 0, op, "\nThe shop contains:"); 1208 new_draw_info (NDI_UNIQUE, 0, op, "\nThe shop contains:");
1132 1209
1133 magic_mapping_mark(op, map_mark, 3); 1210 magic_mapping_mark (op, map_mark, 3);
1134 items=(shopinv*)malloc(40*sizeof(shopinv)); 1211 items = (shopinv *) malloc (40 * sizeof (shopinv));
1135 numallocated=40; 1212 numallocated = 40;
1136 1213
1137 /* Find all the appropriate items */ 1214 /* Find all the appropriate items */
1138 for (i=0; i<MAP_WIDTH(op->map); i++) { 1215 for (i = 0; i < MAP_WIDTH (op->map); i++)
1216 {
1139 for (j=0; j<MAP_HEIGHT(op->map); j++) { 1217 for (j = 0; j < MAP_HEIGHT (op->map); j++)
1218 {
1140 /* 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.
1141 * 1220 *
1142 */ 1221 */
1143 nx = i - op->x + MAGIC_MAP_HALF; 1222 nx = i - op->x + MAGIC_MAP_HALF;
1144 ny = j - op->y + MAGIC_MAP_HALF; 1223 ny = j - op->y + MAGIC_MAP_HALF;
1145 /* unlikely, but really big shops could run into this issue */ 1224 /* 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; 1225 if (nx < 0 || ny < 0 || nx > MAGIC_MAP_SIZE || ny > MAGIC_MAP_SIZE)
1226 continue;
1147 1227
1148 if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR) { 1228 if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR)
1149 stack =get_map_ob(op->map,i,j); 1229 {
1230 stack = get_map_ob (op->map, i, j);
1150 1231
1151 while (stack) { 1232 while (stack)
1233 {
1152 if (QUERY_FLAG(stack, FLAG_UNPAID)) { 1234 if (QUERY_FLAG (stack, FLAG_UNPAID))
1153 if (numitems==numallocated) { 1235 {
1236 if (numitems == numallocated)
1237 {
1154 items=(shopinv*)realloc(items, sizeof(shopinv)*(numallocated+10)); 1238 items = (shopinv *) realloc (items, sizeof (shopinv) * (numallocated + 10));
1155 numallocated+=10; 1239 numallocated += 10;
1156 } 1240 }
1157 add_shop_item(stack, items, &numitems, &numallocated); 1241 add_shop_item (stack, items, &numitems, &numallocated);
1158 } 1242 }
1159 stack = stack->above; 1243 stack = stack->above;
1160 } 1244 }
1245 }
1246 }
1161 } 1247 }
1162 } 1248
1163 }
1164 free(map_mark); 1249 free (map_mark);
1250
1165 if (numitems == 0) { 1251 if (numitems == 0)
1252 {
1166 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");
1167 free(items); 1254 free (items);
1168 return; 1255 return;
1169 } 1256 }
1257
1170 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);
1171 1259
1172 for (i=0; i<numitems; i++) { 1260 for (i = 0; i < numitems; i++)
1261 {
1173 /* Collapse items of the same name together */ 1262 /* Collapse items of the same name together */
1174 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 {
1175 items[i+1].nrof += items[i].nrof; 1265 items[i + 1].nrof += items[i].nrof;
1176 free(items[i].item_sort); 1266 free (items[i].item_sort);
1177 free(items[i].item_real); 1267 free (items[i].item_real);
1178 } else { 1268 }
1269 else
1270 {
1179 new_draw_info_format(NDI_UNIQUE, 0, op, "%d %s", 1271 new_draw_info_format (NDI_UNIQUE, 0, op, "%d %s",
1180 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);
1181 items[i].nrof==1?items[i].item_sort: items[i].item_real);
1182 free(items[i].item_sort); 1273 free (items[i].item_sort);
1183 free(items[i].item_real); 1274 free (items[i].item_real);
1184 } 1275 }
1185 } 1276 }
1186 free(items); 1277 free (items);
1187} 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