ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/treasure.C
(Generate patch)

Comparing deliantra/server/common/treasure.C (file contents):
Revision 1.1 by elmex, Sun Aug 13 17:16:01 2006 UTC vs.
Revision 1.31 by pippijn, Sat Jan 6 14:42:29 2007 UTC

1
2/*
3 * static char *rcs_treasure_c =
4 * "$Id: treasure.C,v 1.1 2006/08/13 17:16:01 elmex Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
12 7
13 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
22 17
23 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 21
27 The authors can be reached via e-mail at crossfire-devel@real-time.com 22 The authors can be reached via e-mail at <crossfire@schmorp.de>
28*/ 23*/
29 24
30#define ALLOWED_COMBINATION 25#define ALLOWED_COMBINATION
31 26
32/* TREASURE_DEBUG does some checking on the treasurelists after loading. 27/* TREASURE_DEBUG does some checking on the treasurelists after loading.
35 * left on 30 * left on
36 */ 31 */
37#define TREASURE_DEBUG 32#define TREASURE_DEBUG
38 33
39/* TREASURE_VERBOSE enables copious output concerning artifact generation */ 34/* TREASURE_VERBOSE enables copious output concerning artifact generation */
35
40/* #define TREASURE_VERBOSE */ 36/* #define TREASURE_VERBOSE */
41 37
42#include <global.h> 38#include <global.h>
43#include <treasure.h> 39#include <treasure.h>
44#include <funcpoint.h> 40#include <funcpoint.h>
45#include <loader.h> 41#include <loader.h>
46 42
47 43
48static void change_treasure(treasure *t, object *op); /* overrule default values */ 44static void change_treasure (treasure *t, object *op); /* overrule default values */
49extern char *spell_mapping[]; 45extern char *spell_mapping[];
50 46
51/* 47/*
52 * Initialize global archtype pointers: 48 * Initialize global archtype pointers:
53 */ 49 */
54 50
51void
55void init_archetype_pointers() { 52init_archetype_pointers ()
53{
56 int prev_warn = warn_archetypes; 54 int prev_warn = warn_archetypes;
55
57 warn_archetypes = 1; 56 warn_archetypes = 1;
58 if (ring_arch == NULL) 57 if (ring_arch == NULL)
59 ring_arch = find_archetype("ring"); 58 ring_arch = archetype::find ("ring");
60 if (amulet_arch == NULL) 59 if (amulet_arch == NULL)
61 amulet_arch = find_archetype("amulet"); 60 amulet_arch = archetype::find ("amulet");
62 if (staff_arch == NULL) 61 if (staff_arch == NULL)
63 staff_arch = find_archetype("staff"); 62 staff_arch = archetype::find ("staff");
64 if (crown_arch == NULL) 63 if (crown_arch == NULL)
65 crown_arch = find_archetype("crown"); 64 crown_arch = archetype::find ("crown");
66 warn_archetypes = prev_warn; 65 warn_archetypes = prev_warn;
67} 66}
68 67
69/* 68/*
70 * Allocate and return the pointer to an empty treasurelist structure. 69 * Allocate and return the pointer to an empty treasurelist structure.
71 */ 70 */
72 71
73static treasurelist *get_empty_treasurelist(void) { 72static treasurelist *
74 treasurelist *tl = (treasurelist *) malloc(sizeof(treasurelist)); 73get_empty_treasurelist (void)
75 if(tl==NULL) 74{
76 fatal(OUT_OF_MEMORY); 75 return new treasurelist;
77 memset(tl, 0, sizeof(treasurelist));
78 return tl;
79} 76}
80 77
81/* 78/*
82 * Allocate and return the pointer to an empty treasure structure. 79 * Allocate and return the pointer to an empty treasure structure.
83 */ 80 */
81//TODO: make this a constructor
82static treasure *
83get_empty_treasure (void)
84{
85 treasure *t = new treasure;
84 86
85static treasure *get_empty_treasure(void) {
86 treasure *t = (treasure *) calloc(1,sizeof(treasure));
87 if(t==NULL)
88 fatal(OUT_OF_MEMORY);
89 t->item=NULL;
90 t->name=NULL;
91 t->next=NULL;
92 t->next_yes=NULL;
93 t->next_no=NULL;
94 t->chance=100; 87 t->chance = 100;
95 t->magic=0; 88
96 t->nrof=0;
97 return t; 89 return t;
98} 90}
99 91
100/* 92/*
101 * Reads the lib/treasure file from disk, and parses the contents 93 * Reads the lib/treasure file from disk, and parses the contents
102 * into an internal treasure structure (very linked lists) 94 * into an internal treasure structure (very linked lists)
103 */ 95 */
104 96
97static treasure *
105static treasure *load_treasure(FILE *fp, int *line) { 98load_treasure (FILE * fp, int *line)
99{
106 char buf[MAX_BUF], *cp, variable[MAX_BUF]; 100 char buf[MAX_BUF], *cp, variable[MAX_BUF];
107 treasure *t=get_empty_treasure(); 101 treasure *t = get_empty_treasure ();
108 int value; 102 int value;
109 103
110 nroftreasures++; 104 nroftreasures++;
111 while(fgets(buf,MAX_BUF,fp)!=NULL) { 105 while (fgets (buf, MAX_BUF, fp) != NULL)
112 (*line)++; 106 {
107 (*line)++;
113 108
114 if(*buf=='#') 109 if (*buf == '#')
115 continue; 110 continue;
116 if((cp=strchr(buf,'\n'))!=NULL) 111 if ((cp = strchr (buf, '\n')) != NULL)
117 *cp='\0'; 112 *cp = '\0';
118 cp=buf; 113 cp = buf;
119 while(isspace(*cp)) /* Skip blanks */ 114 while (isspace (*cp)) /* Skip blanks */
120 cp++; 115 cp++;
121 116
122 if(sscanf(cp,"arch %s",variable)) { 117 if (sscanf (cp, "arch %s", variable))
118 {
123 if((t->item=find_archetype(variable))==NULL) 119 if ((t->item = archetype::find (variable)) == NULL)
124 LOG(llevError,"Treasure lacks archetype: %s\n",variable); 120 LOG (llevError, "Treasure lacks archetype: %s\n", variable);
121 }
125 } else if (sscanf(cp, "list %s", variable)) 122 else if (sscanf (cp, "list %s", variable))
126 t->name = add_string(variable); 123 t->name = variable;
127 else if (sscanf(cp, "change_name %s", variable)) 124 else if (sscanf (cp, "change_name %s", variable))
128 t->change_arch.name = add_string(variable); 125 t->change_arch.name = variable;
129 else if (sscanf(cp, "change_title %s", variable)) 126 else if (sscanf (cp, "change_title %s", variable))
130 t->change_arch.title = add_string(variable); 127 t->change_arch.title = variable;
131 else if (sscanf(cp, "change_slaying %s", variable)) 128 else if (sscanf (cp, "change_slaying %s", variable))
132 t->change_arch.slaying = add_string(variable); 129 t->change_arch.slaying = variable;
133 else if(sscanf(cp,"chance %d",&value)) 130 else if (sscanf (cp, "chance %d", &value))
134 t->chance=(uint8) value; 131 t->chance = (uint8) value;
135 else if(sscanf(cp,"nrof %d",&value)) 132 else if (sscanf (cp, "nrof %d", &value))
136 t->nrof=(uint16) value; 133 t->nrof = (uint16) value;
137 else if(sscanf(cp,"magic %d",&value)) 134 else if (sscanf (cp, "magic %d", &value))
138 t->magic=(uint8) value; 135 t->magic = (uint8) value;
139 else if(!strcmp(cp,"yes")) 136 else if (!strcmp (cp, "yes"))
140 t->next_yes=load_treasure(fp, line); 137 t->next_yes = load_treasure (fp, line);
141 else if(!strcmp(cp,"no")) 138 else if (!strcmp (cp, "no"))
142 t->next_no=load_treasure(fp, line); 139 t->next_no = load_treasure (fp, line);
143 else if(!strcmp(cp,"end")) 140 else if (!strcmp (cp, "end"))
144 return t; 141 return t;
145 else if(!strcmp(cp,"more")) { 142 else if (!strcmp (cp, "more"))
143 {
146 t->next=load_treasure(fp, line); 144 t->next = load_treasure (fp, line);
147 return t; 145 return t;
148 } else 146 }
147 else
149 LOG(llevError,"Unknown treasure-command: '%s', last entry %s, line %d\n", 148 LOG (llevError, "Unknown treasure-command: '%s', last entry %s, line %d\n", cp, &t->name, *line);
150 cp,t->name?t->name:"null", *line);
151 } 149 }
152 LOG(llevError,"treasure lacks 'end'.\n"); 150 LOG (llevError, "treasure lacks 'end'.\n");
153 return t; 151 return t;
154} 152}
155 153
156#ifdef TREASURE_DEBUG 154#ifdef TREASURE_DEBUG
155
157/* recursived checks the linked list. Treasurelist is passed only 156/* recursived checks the linked list. Treasurelist is passed only
158 * so that the treasure name can be printed out 157 * so that the treasure name can be printed out
159 */ 158 */
159static void
160static void check_treasurelist(const treasure *t, const treasurelist *tl) 160check_treasurelist (const treasure *t, const treasurelist * tl)
161{ 161{
162 if (t->item==NULL && t->name==NULL)
163 LOG(llevError,"Treasurelist %s has element with no name or archetype\n", tl->name);
164 if (t->chance>=100 && t->next_yes && (t->next || t->next_no)) 162 if (t->chance >= 100 && t->next_yes && (t->next || t->next_no))
165 LOG(llevError,"Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", 163 LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name);
166 tl->name);
167 /* find_treasurelist will print out its own error message */ 164 /* find_treasurelist will print out its own error message */
168 if (t->name && strcmp(t->name,"NONE")) 165 if (t->name && *t->name)
169 (void) find_treasurelist(t->name); 166 find_treasurelist (t->name);
167 if (t->next)
170 if (t->next) check_treasurelist(t->next, tl); 168 check_treasurelist (t->next, tl);
169 if (t->next_yes)
171 if (t->next_yes) check_treasurelist(t->next_yes,tl); 170 check_treasurelist (t->next_yes, tl);
171 if (t->next_no)
172 if (t->next_no) check_treasurelist(t->next_no, tl); 172 check_treasurelist (t->next_no, tl);
173} 173}
174#endif 174#endif
175 175
176/* 176/*
177 * Opens LIBDIR/treasure and reads all treasure-declarations from it. 177 * Opens LIBDIR/treasure and reads all treasure-declarations from it.
178 * Each treasure is parsed with the help of load_treasure(). 178 * Each treasure is parsed with the help of load_treasure().
179 */ 179 */
180 180
181void
181void load_treasures(void) { 182load_treasures (void)
183{
182 FILE *fp; 184 FILE *fp;
183 char filename[MAX_BUF], buf[MAX_BUF], name[MAX_BUF]; 185 char filename[MAX_BUF], buf[MAX_BUF], name[MAX_BUF];
184 treasurelist *previous=NULL; 186 treasurelist *previous = NULL;
185 treasure *t; 187 treasure *t;
186 int comp, line=0; 188 int comp, line = 0;
187 189
188 sprintf(filename,"%s/%s",settings.datadir,settings.treasures); 190 sprintf (filename, "%s/%s", settings.datadir, settings.treasures);
189 if((fp=open_and_uncompress(filename,0,&comp))==NULL) { 191 if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
192 {
190 LOG(llevError,"Can't open treasure file.\n"); 193 LOG (llevError, "Can't open treasure file.\n");
191 return; 194 return;
192 } 195 }
193 while(fgets(buf,MAX_BUF,fp)!=NULL) { 196 while (fgets (buf, MAX_BUF, fp) != NULL)
194 line++; 197 {
195 if(*buf=='#') 198 line++;
199 if (*buf == '#')
196 continue; 200 continue;
197 201
198 if(sscanf(buf,"treasureone %s\n",name) || sscanf(buf,"treasure %s\n",name)) { 202 if (sscanf (buf, "treasureone %s\n", name) || sscanf (buf, "treasure %s\n", name))
203 {
199 treasurelist *tl=get_empty_treasurelist(); 204 treasurelist *tl = get_empty_treasurelist ();
200 tl->name=add_string(name); 205
206 tl->name = name;
201 if(previous==NULL) 207 if (previous == NULL)
202 first_treasurelist=tl; 208 first_treasurelist = tl;
203 else 209 else
204 previous->next=tl; 210 previous->next = tl;
205 previous=tl; 211 previous = tl;
206 tl->items=load_treasure(fp, &line); 212 tl->items = load_treasure (fp, &line);
207 213
208 /* This is a one of the many items on the list should be generated. 214 /* This is a one of the many items on the list should be generated.
209 * Add up the chance total, and check to make sure the yes & no 215 * Add up the chance total, and check to make sure the yes & no
210 * fields of the treasures are not being used. 216 * fields of the treasures are not being used.
211 */ 217 */
212 if (!strncmp(buf,"treasureone",11)) { 218 if (!strncmp (buf, "treasureone", 11))
219 {
213 for (t=tl->items; t!=NULL; t=t->next) { 220 for (t = tl->items; t != NULL; t = t->next)
221 {
214#ifdef TREASURE_DEBUG 222#ifdef TREASURE_DEBUG
215 if (t->next_yes || t->next_no) { 223 if (t->next_yes || t->next_no)
216 LOG(llevError,"Treasure %s is one item, but on treasure %s\n", 224 {
217 tl->name, t->item ? t->item->name : t->name); 225 LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name);
218 LOG(llevError," the next_yes or next_no field is set\n"); 226 LOG (llevError, " the next_yes or next_no field is set\n");
219 } 227 }
220#endif 228#endif
221 tl->total_chance += t->chance; 229 tl->total_chance += t->chance;
222 } 230 }
223 } 231 }
224 } else 232 }
233 else
225 LOG(llevError,"Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line); 234 LOG (llevError, "Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line);
226 } 235 }
227 close_and_delete(fp, comp); 236 close_and_delete (fp, comp);
228 237
229#ifdef TREASURE_DEBUG 238#ifdef TREASURE_DEBUG
230 /* Perform some checks on how valid the treasure data actually is. 239 /* Perform some checks on how valid the treasure data actually is.
231 * verify that list transitions work (ie, the list that it is supposed 240 * verify that list transitions work (ie, the list that it is supposed
232 * to transition to exists). Also, verify that at least the name 241 * to transition to exists). Also, verify that at least the name
233 * or archetype is set for each treasure element. 242 * or archetype is set for each treasure element.
234 */ 243 */
235 for (previous=first_treasurelist; previous!=NULL; previous=previous->next) 244 for (previous = first_treasurelist; previous != NULL; previous = previous->next)
236 check_treasurelist(previous->items, previous); 245 check_treasurelist (previous->items, previous);
237#endif 246#endif
238} 247}
239 248
240/* 249/*
241 * Searches for the given treasurelist in the globally linked list 250 * Searches for the given treasurelist in the globally linked list
242 * of treasurelists which has been built by load_treasures(). 251 * of treasurelists which has been built by load_treasures().
243 */ 252 */
244 253
245treasurelist *find_treasurelist(const char *name) {
246 const char *tmp=find_string(name);
247 treasurelist *tl; 254treasurelist *
255find_treasurelist (const char *name)
256{
257 shstr_cmp name_ (name);
248 258
249 /* Special cases - randomitems of none is to override default. If 259 if (!name_)
250 * first_treasurelist is null, it means we are on the first pass of 260 return 0;
251 * of loading archetyps, so for now, just return - second pass will 261
252 * init these values.
253 */
254 if (!strcmp(name,"none") || (!first_treasurelist)) return NULL;
255 if(tmp!=NULL)
256 for(tl=first_treasurelist;tl!=NULL;tl=tl->next) 262 for (treasurelist *tl = first_treasurelist; tl != 0; tl = tl->next)
257 if(tmp==tl->name) 263 if (name_ == tl->name)
258 return tl; 264 return tl;
265
266 if (first_treasurelist)
259 LOG(llevError,"Couldn't find treasurelist %s\n",name); 267 LOG (llevError, "Couldn't find treasurelist %s\n", name);
268
260 return NULL; 269 return 0;
261} 270}
262 271
263 272
264/* 273/*
265 * Generates the objects specified by the given treasure. 274 * Generates the objects specified by the given treasure.
270 * being generated. 279 * being generated.
271 * If flag is GT_INVISIBLE, only invisible objects are generated (ie, only 280 * If flag is GT_INVISIBLE, only invisible objects are generated (ie, only
272 * abilities. This is used by summon spells, thus no summoned monsters 281 * abilities. This is used by summon spells, thus no summoned monsters
273 * start with equipment, but only their abilities). 282 * start with equipment, but only their abilities).
274 */ 283 */
275 284static void
276
277static void put_treasure (object *op, object *creator, int flags) 285put_treasure (object *op, object *creator, int flags)
278{ 286{
279 object *tmp; 287 object *tmp;
280 288
281 /* Bit of a hack - spells should never be put onto the map. The entire 289 /* Bit of a hack - spells should never be put onto the map. The entire
282 * treasure stuff is a problem - there is no clear idea of knowing 290 * treasure stuff is a problem - there is no clear idea of knowing
283 * this is the original object, or if this is an object that should be created 291 * this is the original object, or if this is an object that should be created
284 * by another object. 292 * by another object.
285 */ 293 */
286 if (flags & GT_ENVIRONMENT && op->type != SPELL) { 294 if (flags & GT_ENVIRONMENT && op->type != SPELL)
287 op->x = creator->x; 295 {
288 op->y = creator->y;
289 SET_FLAG(op, FLAG_OBJ_ORIGINAL); 296 SET_FLAG (op, FLAG_OBJ_ORIGINAL);
290 insert_ob_in_map (op, creator->map,op,INS_NO_MERGE | INS_NO_WALK_ON); 297 op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON);
291 } else { 298 }
292 op = insert_ob_in_ob (op, creator); 299 else
300 {
301 op = creator->insert (op);
302
293 if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER)) 303 if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER))
294 monster_check_apply(creator, op); 304 monster_check_apply (creator, op);
305
295 if ((flags & GT_UPDATE_INV) && (tmp = is_player_inv (creator)) != NULL) 306 if ((flags & GT_UPDATE_INV) && (tmp = creator->in_player ()))
296 esrv_send_item(tmp, op); 307 esrv_send_item (tmp, op);
297 } 308 }
298} 309}
299 310
300/* if there are change_xxx commands in the treasure, we include the changes 311/* if there are change_xxx commands in the treasure, we include the changes
301 * in the generated object 312 * in the generated object
302 */ 313 */
314static void
303static void change_treasure(treasure *t, object *op) 315change_treasure (treasure *t, object *op)
304{ 316{
305 /* CMD: change_name xxxx */ 317 /* CMD: change_name xxxx */
306 if(t->change_arch.name) 318 if (t->change_arch.name)
307 {
308 FREE_AND_COPY(op->name, t->change_arch.name);
309 /* not great, but better than something that is completely wrong */
310 FREE_AND_COPY(op->name_pl, t->change_arch.name);
311 }
312 319 {
320 op->name = t->change_arch.name;
321 op->name_pl = t->change_arch.name;
322 }
323
313 if(t->change_arch.title) 324 if (t->change_arch.title)
314 {
315 if(op->title)
316 free_string(op->title);
317 op->title = add_string(t->change_arch.title); 325 op->title = t->change_arch.title;
318 }
319 326
320 if(t->change_arch.slaying) 327 if (t->change_arch.slaying)
321 {
322 if(op->slaying)
323 free_string(op->slaying);
324 op->slaying = add_string(t->change_arch.slaying); 328 op->slaying = t->change_arch.slaying;
325 }
326
327} 329}
328 330
331void
329void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries) { 332create_all_treasures (treasure *t, object *op, int flag, int difficulty, int tries)
333{
330 object *tmp; 334 object *tmp;
331 335
332
333 if((int)t->chance >= 100 || (RANDOM()%100 + 1) < (int) t->chance) { 336 if ((int) t->chance >= 100 || (RANDOM () % 100 + 1) < (int) t->chance)
337 {
334 if (t->name) { 338 if (t->name)
335 if (strcmp(t->name,"NONE") && difficulty>=t->magic) 339 {
336 create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries); 340 if (difficulty >= t->magic)
337 } 341 {
342 treasurelist *tl = find_treasurelist (t->name);
343 if (tl)
344 create_treasure (tl, op, flag, difficulty, tries);
345 }
346 }
338 else { 347 else
348 {
339 if(t->item->clone.invisible != 0 || ! (flag & GT_INVISIBLE)) { 349 if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE)))
350 {
340 tmp=arch_to_object(t->item); 351 tmp = arch_to_object (t->item);
352 if (t->nrof && tmp->nrof <= 1)
353 tmp->nrof = RANDOM () % ((int) t->nrof) + 1;
354 fix_generated_item (tmp, op, difficulty, t->magic, flag);
355 change_treasure (t, tmp);
356 put_treasure (tmp, op, flag);
357 }
358 }
359
360 if (t->next_yes != NULL)
361 create_all_treasures (t->next_yes, op, flag, difficulty, tries);
362 }
363 else if (t->next_no != NULL)
364 create_all_treasures (t->next_no, op, flag, difficulty, tries);
365
366 if (t->next != NULL)
367 create_all_treasures (t->next, op, flag, difficulty, tries);
368}
369
370void
371create_one_treasure (treasurelist * tl, object *op, int flag, int difficulty, int tries)
372{
373 int value = RANDOM () % tl->total_chance;
374 treasure *t;
375
376 if (tries++ > 100)
377 {
378 LOG (llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n");
379 return;
380 }
381
382 for (t = tl->items; t != NULL; t = t->next)
383 {
384 value -= t->chance;
385
386 if (value < 0)
387 break;
388 }
389
390 if (!t || value >= 0)
391 {
392 LOG (llevError, "create_one_treasure: got null object or not able to find treasure\n");
393 abort ();
394 return;
395 }
396
397 if (t->name)
398 {
399 if (difficulty >= t->magic)
400 {
401 treasurelist *tl = find_treasurelist (t->name);
402 if (tl)
403 create_treasure (tl, op, flag, difficulty, tries);
404 }
405 else if (t->nrof)
406 create_one_treasure (tl, op, flag, difficulty, tries);
407
408 return;
409 }
410
411 if (t->item && (t->item->clone.invisible != 0 || flag != GT_INVISIBLE))
412 {
413 object *tmp = arch_to_object (t->item);
414
415 if (!tmp)
416 return;
417
341 if(t->nrof&&tmp->nrof<=1) 418 if (t->nrof && tmp->nrof <= 1)
342 tmp->nrof = RANDOM()%((int) t->nrof) + 1; 419 tmp->nrof = RANDOM () % ((int) t->nrof) + 1;
420
343 fix_generated_item (tmp, op, difficulty, t->magic, flag); 421 fix_generated_item (tmp, op, difficulty, t->magic, flag);
344 change_treasure(t, tmp); 422 change_treasure (t, tmp);
345 put_treasure (tmp, op, flag); 423 put_treasure (tmp, op, flag);
346 }
347 }
348 if(t->next_yes!=NULL)
349 create_all_treasures(t->next_yes,op,flag,difficulty, tries);
350 } else
351 if(t->next_no!=NULL)
352 create_all_treasures(t->next_no,op,flag,difficulty,tries);
353 if(t->next!=NULL)
354 create_all_treasures(t->next,op,flag,difficulty, tries);
355}
356
357void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty,
358 int tries)
359{
360 int value = RANDOM() % tl->total_chance;
361 treasure *t;
362
363 if (tries++>100) {
364 LOG(llevDebug,"create_one_treasure: tries exceeded 100, returning without making treasure\n");
365 return;
366 }
367 for (t=tl->items; t!=NULL; t=t->next) {
368 value -= t->chance;
369 if (value<0) break;
370 }
371
372 if (!t || value>=0) {
373 LOG(llevError, "create_one_treasure: got null object or not able to find treasure\n");
374 abort();
375 return;
376 }
377 if (t->name) {
378 if (!strcmp(t->name,"NONE")) return;
379 if (difficulty>=t->magic)
380 create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries);
381 else if (t->nrof)
382 create_one_treasure(tl, op, flag, difficulty, tries);
383 return;
384 }
385 if((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) {
386 object *tmp=arch_to_object(t->item);
387 if (!tmp) return;
388 if(t->nrof && tmp->nrof<=1)
389 tmp->nrof = RANDOM()%((int) t->nrof) + 1;
390 fix_generated_item (tmp, op, difficulty, t->magic, flag);
391 change_treasure(t, tmp);
392 put_treasure (tmp, op, flag);
393 } 424 }
394} 425}
395 426
396/* This calls the appropriate treasure creation function. tries is passed 427/* This calls the appropriate treasure creation function. tries is passed
397 * to determine how many list transitions or attempts to create treasure 428 * to determine how many list transitions or attempts to create treasure
398 * have been made. It is really in place to prevent infinite loops with 429 * have been made. It is really in place to prevent infinite loops with
399 * list transitions, or so that excessively good treasure will not be 430 * list transitions, or so that excessively good treasure will not be
400 * created on weak maps, because it will exceed the number of allowed tries 431 * created on weak maps, because it will exceed the number of allowed tries
401 * to do that. 432 * to do that.
402 */ 433 */
434void
403void create_treasure(treasurelist *t, object *op, int flag, int difficulty, 435create_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries)
404 int tries)
405{ 436{
406 437
407 if (tries++>100) { 438 if (tries++ > 100)
439 {
408 LOG(llevDebug,"createtreasure: tries exceeded 100, returning without making treasure\n"); 440 LOG (llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n");
409 return; 441 return;
410 } 442 }
411 if (t->total_chance) 443 if (tl->total_chance)
412 create_one_treasure(t, op, flag,difficulty, tries); 444 create_one_treasure (tl, op, flag, difficulty, tries);
413 else 445 else
414 create_all_treasures(t->items, op, flag, difficulty, tries); 446 create_all_treasures (tl->items, op, flag, difficulty, tries);
415} 447}
416 448
417/* This is similar to the old generate treasure function. However, 449/* This is similar to the old generate treasure function. However,
418 * it instead takes a treasurelist. It is really just a wrapper around 450 * it instead takes a treasurelist. It is really just a wrapper around
419 * create_treasure. We create a dummy object that the treasure gets 451 * create_treasure. We create a dummy object that the treasure gets
420 * inserted into, and then return that treausre 452 * inserted into, and then return that treausre
421 */ 453 */
454object *
422object *generate_treasure(treasurelist *t, int difficulty) 455generate_treasure (treasurelist *tl, int difficulty)
423{ 456{
457 difficulty = clamp (difficulty, 1, settings.max_level);
458
424 object *ob = get_object(), *tmp; 459 object *ob = object::create (), *tmp;
425 460
426 create_treasure(t, ob, 0, difficulty, 0); 461 create_treasure (tl, ob, 0, difficulty, 0);
427 462
428 /* Don't want to free the object we are about to return */ 463 /* Don't want to free the object we are about to return */
429 tmp = ob->inv; 464 tmp = ob->inv;
430 if (tmp!=NULL) remove_ob(tmp); 465 if (tmp != NULL)
466 tmp->remove ();
467
431 if (ob->inv) { 468 if (ob->inv)
432 LOG(llevError,"In generate treasure, created multiple objects.\n"); 469 LOG (llevError, "In generate treasure, created multiple objects.\n");
433 } 470
434 free_object(ob); 471 ob->destroy ();
435 return tmp; 472 return tmp;
436} 473}
437 474
438/* 475/*
439 * This is a new way of calculating the chance for an item to have 476 * This is a new way of calculating the chance for an item to have
440 * a specific magical bonus. 477 * a specific magical bonus.
441 * The array has two arguments, the difficulty of the level, and the 478 * The array has two arguments, the difficulty of the level, and the
442 * magical bonus "wanted". 479 * magical bonus "wanted".
443 */ 480 */
444 481
445static int difftomagic_list[DIFFLEVELS][MAXMAGIC+1] = 482static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = {
446{ 483
447/*chance of magic difficulty*/ 484/*chance of magic difficulty*/
485
448/* +0 +1 +2 +3 +4 */ 486/* +0 +1 +2 +3 +4 */
449 { 95, 2, 2, 1, 0 }, /*1*/ 487 {95, 2, 2, 1, 0}, /*1 */
450 { 92, 5, 2, 1, 0 }, /*2*/ 488 {92, 5, 2, 1, 0}, /*2 */
451 { 85,10, 4, 1, 0 }, /*3*/ 489 {85, 10, 4, 1, 0}, /*3 */
452 { 80,14, 4, 2, 0 }, /*4*/ 490 {80, 14, 4, 2, 0}, /*4 */
453 { 75,17, 5, 2, 1 }, /*5*/ 491 {75, 17, 5, 2, 1}, /*5 */
454 { 70,18, 8, 3, 1 }, /*6*/ 492 {70, 18, 8, 3, 1}, /*6 */
455 { 65,21,10, 3, 1 }, /*7*/ 493 {65, 21, 10, 3, 1}, /*7 */
456 { 60,22,12, 4, 2 }, /*8*/ 494 {60, 22, 12, 4, 2}, /*8 */
457 { 55,25,14, 4, 2 }, /*9*/ 495 {55, 25, 14, 4, 2}, /*9 */
458 { 50,27,16, 5, 2 }, /*10*/ 496 {50, 27, 16, 5, 2}, /*10 */
459 { 45,28,18, 6, 3 }, /*11*/ 497 {45, 28, 18, 6, 3}, /*11 */
460 { 42,28,20, 7, 3 }, /*12*/ 498 {42, 28, 20, 7, 3}, /*12 */
461 { 40,27,21, 8, 4 }, /*13*/ 499 {40, 27, 21, 8, 4}, /*13 */
462 { 38,25,22,10, 5 }, /*14*/ 500 {38, 25, 22, 10, 5}, /*14 */
463 { 36,23,23,12, 6 }, /*15*/ 501 {36, 23, 23, 12, 6}, /*15 */
464 { 33,21,24,14, 8 }, /*16*/ 502 {33, 21, 24, 14, 8}, /*16 */
465 { 31,19,25,16, 9 }, /*17*/ 503 {31, 19, 25, 16, 9}, /*17 */
466 { 27,15,30,18,10 }, /*18*/ 504 {27, 15, 30, 18, 10}, /*18 */
467 { 20,12,30,25,13 }, /*19*/ 505 {20, 12, 30, 25, 13}, /*19 */
468 { 15,10,28,30,17 }, /*20*/ 506 {15, 10, 28, 30, 17}, /*20 */
469 { 13, 9,27,28,23 }, /*21*/ 507 {13, 9, 27, 28, 23}, /*21 */
470 { 10, 8,25,28,29 }, /*22*/ 508 {10, 8, 25, 28, 29}, /*22 */
471 { 8, 7,23,26,36 }, /*23*/ 509 {8, 7, 23, 26, 36}, /*23 */
472 { 6, 6,20,22,46 }, /*24*/ 510 {6, 6, 20, 22, 46}, /*24 */
473 { 4, 5,17,18,56 }, /*25*/ 511 {4, 5, 17, 18, 56}, /*25 */
474 { 2, 4,12,14,68 }, /*26*/ 512 {2, 4, 12, 14, 68}, /*26 */
475 { 0, 3, 7,10,80 }, /*27*/ 513 {0, 3, 7, 10, 80}, /*27 */
476 { 0, 0, 3, 7,90 }, /*28*/ 514 {0, 0, 3, 7, 90}, /*28 */
477 { 0, 0, 0, 3,97 }, /*29*/ 515 {0, 0, 0, 3, 97}, /*29 */
478 { 0, 0, 0, 0,100}, /*30*/ 516 {0, 0, 0, 0, 100}, /*30 */
479 { 0, 0, 0, 0,100}, /*31*/ 517 {0, 0, 0, 0, 100}, /*31 */
480}; 518};
481 519
482 520
483/* calculate the appropriate level for wands staves and scrolls. 521/* calculate the appropriate level for wands staves and scrolls.
484 * This code presumes that op has had its spell object created (in op->inv) 522 * This code presumes that op has had its spell object created (in op->inv)
485 * 523 *
486 * elmex Wed Aug 9 17:44:59 CEST 2006: 524 * elmex Wed Aug 9 17:44:59 CEST 2006:
487 * Removed multiplicator, too many high-level items were generated on low-difficulty maps. 525 * Removed multiplicator, too many high-level items were generated on low-difficulty maps.
488 */ 526 */
489 527
528int
490int level_for_item (const object *op, int difficulty) 529level_for_item (const object *op, int difficulty)
491{ 530{
492 int mult = 0, olevel = 0; 531 int olevel = 0;
493 532
494 if (!op->inv) 533 if (!op->inv)
495 { 534 {
496 LOG(llevError,"level_for_item: Object %s has no inventory!\n", op->name); 535 LOG (llevError, "level_for_item: Object %s has no inventory!\n", &op->name);
497 return 0; 536 return 0;
498 } 537 }
499 538
500 olevel = (int) (op->inv->level + (double) difficulty * (1 - drand48 () * drand48 () * 2)); 539 olevel = (int) (op->inv->level + (double) difficulty * (1 - drand48 () * drand48 () * 2));
501 540
502 if (olevel <= 0) 541 if (olevel <= 0)
517 * Scaling difficulty by max_level, as difficulty is a level and not some 556 * Scaling difficulty by max_level, as difficulty is a level and not some
518 * weird integer between 1-31. 557 * weird integer between 1-31.
519 * 558 *
520 */ 559 */
521 560
561int
522int magic_from_difficulty(int difficulty) 562magic_from_difficulty (int difficulty)
523{ 563{
524 int percent = 0, magic = 0; 564 int percent = 0, magic = 0;
525 int scaled_diff = (int) (((double) difficulty / settings.max_level) * DIFFLEVELS); 565 int scaled_diff = (int) (((double) difficulty / settings.max_level) * DIFFLEVELS);
526 566
527 scaled_diff--; 567 scaled_diff--;
528 568
529 if(scaled_diff < 0) 569 if (scaled_diff < 0)
530 scaled_diff = 0; 570 scaled_diff = 0;
531 571
532 if (scaled_diff >= DIFFLEVELS) 572 if (scaled_diff >= DIFFLEVELS)
533 scaled_diff = DIFFLEVELS-1; 573 scaled_diff = DIFFLEVELS - 1;
534 574
535 percent = RANDOM()%100; 575 percent = RANDOM () % 100;
536 576
537 for(magic = 0; magic < (MAXMAGIC + 1); magic++) 577 for (magic = 0; magic < (MAXMAGIC + 1); magic++)
538 { 578 {
539 percent -= difftomagic_list[scaled_diff][magic]; 579 percent -= difftomagic_list[scaled_diff][magic];
540 580
541 if (percent < 0) 581 if (percent < 0)
542 break; 582 break;
543 } 583 }
544 584
545 if (magic == (MAXMAGIC + 1)) 585 if (magic == (MAXMAGIC + 1))
546 { 586 {
547 LOG(llevError,"Warning, table for difficulty (scaled %d) %d bad.\n", scaled_diff, difficulty); 587 LOG (llevError, "Warning, table for difficulty (scaled %d) %d bad.\n", scaled_diff, difficulty);
548 magic = 0; 588 magic = 0;
549 } 589 }
550 590
551 magic = (RANDOM() % 3) ? magic : -magic; 591 magic = (RANDOM () % 3) ? magic : -magic;
552 /* LOG(llevDebug, "Chose magic %d for difficulty (scaled %d) %d\n", magic, scaled_diff, difficulty); */ 592 /* LOG(llevDebug, "Chose magic %d for difficulty (scaled %d) %d\n", magic, scaled_diff, difficulty); */
553 593
554 return magic; 594 return magic;
555} 595}
556 596
559 * the armour variable, and the effect on speed of armour. 599 * the armour variable, and the effect on speed of armour.
560 * This function doesn't work properly, should add use of archetypes 600 * This function doesn't work properly, should add use of archetypes
561 * to make it truly absolute. 601 * to make it truly absolute.
562 */ 602 */
563 603
604void
564void set_abs_magic(object *op, int magic) { 605set_abs_magic (object *op, int magic)
606{
565 if(!magic) 607 if (!magic)
566 return; 608 return;
567 609
568 op->magic=magic; 610 op->magic = magic;
569 if (op->arch) { 611 if (op->arch)
612 {
570 if (op->type == ARMOUR) 613 if (op->type == ARMOUR)
571 ARMOUR_SPEED(op)=(ARMOUR_SPEED(&op->arch->clone)*(100+magic*10))/100; 614 ARMOUR_SPEED (op) = (ARMOUR_SPEED (&op->arch->clone) * (100 + magic * 10)) / 100;
572 615
573 if (magic < 0 && !(RANDOM()%3)) /* You can't just check the weight always */ 616 if (magic < 0 && !(RANDOM () % 3)) /* You can't just check the weight always */
574 magic = (-magic); 617 magic = (-magic);
575 op->weight = (op->arch->clone.weight*(100-magic*10))/100; 618 op->weight = (op->arch->clone.weight * (100 - magic * 10)) / 100;
619 }
576 } else { 620 else
621 {
577 if(op->type==ARMOUR) 622 if (op->type == ARMOUR)
578 ARMOUR_SPEED(op)=(ARMOUR_SPEED(op)*(100+magic*10))/100; 623 ARMOUR_SPEED (op) = (ARMOUR_SPEED (op) * (100 + magic * 10)) / 100;
579 if (magic < 0 && !(RANDOM()%3)) /* You can't just check the weight always */ 624 if (magic < 0 && !(RANDOM () % 3)) /* You can't just check the weight always */
580 magic = (-magic); 625 magic = (-magic);
581 op->weight=(op->weight*(100-magic*10))/100; 626 op->weight = (op->weight * (100 - magic * 10)) / 100;
582 } 627 }
583} 628}
584 629
585/* 630/*
586 * Sets a random magical bonus in the given object based upon 631 * Sets a random magical bonus in the given object based upon
587 * the given difficulty, and the given max possible bonus. 632 * the given difficulty, and the given max possible bonus.
588 */ 633 */
589 634
635static void
590static void set_magic (int difficulty, object *op, int max_magic, int flags) 636set_magic (int difficulty, object *op, int max_magic, int flags)
591{ 637{
592 int i; 638 int i;
639
593 i = magic_from_difficulty(difficulty); 640 i = magic_from_difficulty (difficulty);
594 if ((flags & GT_ONLY_GOOD) && i < 0) 641 if ((flags & GT_ONLY_GOOD) && i < 0)
595 i = -i; 642 i = -i;
596 if(i > max_magic) 643 if (i > max_magic)
597 i = max_magic; 644 i = max_magic;
598 set_abs_magic(op,i); 645 set_abs_magic (op, i);
599 if (i < 0) 646 if (i < 0)
600 SET_FLAG(op, FLAG_CURSED); 647 SET_FLAG (op, FLAG_CURSED);
601} 648}
602 649
603/* 650/*
604 * Randomly adds one magical ability to the given object. 651 * Randomly adds one magical ability to the given object.
605 * Modified for Partial Resistance in many ways: 652 * Modified for Partial Resistance in many ways:
607 * is rolled again, increase it - the bonuses now stack with 654 * is rolled again, increase it - the bonuses now stack with
608 * other bonuses previously rolled and ones the item might natively have. 655 * other bonuses previously rolled and ones the item might natively have.
609 * 2) Add code to deal with new PR method. 656 * 2) Add code to deal with new PR method.
610 */ 657 */
611 658
659void
612void set_ring_bonus(object *op,int bonus) { 660set_ring_bonus (object *op, int bonus)
661{
613 662
614 int r=RANDOM()%(bonus>0?25:11); 663 int r = RANDOM () % (bonus > 0 ? 25 : 11);
615 664
616 if(op->type==AMULET) { 665 if (op->type == AMULET)
666 {
617 if(!(RANDOM()%21)) 667 if (!(RANDOM () % 21))
618 r=20+RANDOM()%2; 668 r = 20 + RANDOM () % 2;
619 else {
620 if(RANDOM()&2)
621 r=10;
622 else 669 else
623 r=11+RANDOM()%9; 670 {
624 } 671 if (RANDOM () & 2)
672 r = 10;
673 else
674 r = 11 + RANDOM () % 9;
675 }
625 } 676 }
626 677
627 switch(r) { 678 switch (r)
679 {
628 /* Redone by MSW 2000-11-26 to have much less code. Also, 680 /* Redone by MSW 2000-11-26 to have much less code. Also,
629 * bonuses and penalties will stack and add to existing values. 681 * bonuses and penalties will stack and add to existing values.
630 * of the item. 682 * of the item.
631 */ 683 */
632 case 0: 684 case 0:
633 case 1: 685 case 1:
634 case 2: 686 case 2:
635 case 3: 687 case 3:
636 case 4: 688 case 4:
637 case 5: 689 case 5:
638 case 6: 690 case 6:
639 set_attr_value(&op->stats, r, (signed char)(bonus + get_attr_value(&op->stats,r))); 691 set_attr_value (&op->stats, r, (signed char) (bonus + get_attr_value (&op->stats, r)));
640 break; 692 break;
641 693
642 case 7: 694 case 7:
643 op->stats.dam+=bonus; 695 op->stats.dam += bonus;
644 break; 696 break;
645 697
646 case 8: 698 case 8:
647 op->stats.wc+=bonus; 699 op->stats.wc += bonus;
648 break; 700 break;
649 701
650 case 9: 702 case 9:
651 op->stats.food+=bonus; /* hunger/sustenance */ 703 op->stats.food += bonus; /* hunger/sustenance */
652 break; 704 break;
653 705
654 case 10: 706 case 10:
655 op->stats.ac+=bonus; 707 op->stats.ac += bonus;
656 break; 708 break;
657 709
658 /* Item that gives protections/vulnerabilities */ 710 /* Item that gives protections/vulnerabilities */
659 case 11: 711 case 11:
660 case 12: 712 case 12:
661 case 13: 713 case 13:
662 case 14: 714 case 14:
663 case 15: 715 case 15:
664 case 16: 716 case 16:
665 case 17: 717 case 17:
666 case 18: 718 case 18:
667 case 19: 719 case 19:
668 { 720 {
669 int b=5+FABS(bonus),val,resist=RANDOM() % num_resist_table; 721 int b = 5 + FABS (bonus), val, resist = RANDOM () % num_resist_table;
670 722
671 /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */ 723 /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */
672 val = 10 + RANDOM() % b + RANDOM() % b + RANDOM() % b + RANDOM() % b; 724 val = 10 + RANDOM () % b + RANDOM () % b + RANDOM () % b + RANDOM () % b;
673 725
674 /* Cursed items need to have higher negative values to equal out with 726 /* Cursed items need to have higher negative values to equal out with
675 * positive values for how protections work out. Put another 727 * positive values for how protections work out. Put another
676 * little random element in since that they don't always end up with 728 * little random element in since that they don't always end up with
677 * even values. 729 * even values.
678 */ 730 */
679 if (bonus<0) val = 2*-val - RANDOM() % b; 731 if (bonus < 0)
680 if (val>35) val=35; /* Upper limit */ 732 val = 2 * -val - RANDOM () % b;
681 b=0; 733 if (val > 35)
734 val = 35; /* Upper limit */
735 b = 0;
682 while (op->resist[resist_table[resist]]!=0 && b<4) { 736 while (op->resist[resist_table[resist]] != 0 && b < 4)
737 {
683 resist=RANDOM() % num_resist_table; 738 resist = RANDOM () % num_resist_table;
684 } 739 }
685 if (b==4) return; /* Not able to find a free resistance */ 740 if (b == 4)
741 return; /* Not able to find a free resistance */
686 op->resist[resist_table[resist]] = val; 742 op->resist[resist_table[resist]] = val;
687 /* We should probably do something more clever here to adjust value 743 /* We should probably do something more clever here to adjust value
688 * based on how good a resistance we gave. 744 * based on how good a resistance we gave.
689 */ 745 */
690 break; 746 break;
691 } 747 }
692 case 20: 748 case 20:
693 if(op->type==AMULET) { 749 if (op->type == AMULET)
750 {
694 SET_FLAG(op,FLAG_REFL_SPELL); 751 SET_FLAG (op, FLAG_REFL_SPELL);
695 op->value*=11; 752 op->value *= 11;
696 } else { 753 }
754 else
755 {
697 op->stats.hp=1; /* regenerate hit points */ 756 op->stats.hp = 1; /* regenerate hit points */
698 op->value*=4; 757 op->value *= 4;
758 }
759 break;
760
761 case 21:
762 if (op->type == AMULET)
763 {
764 SET_FLAG (op, FLAG_REFL_MISSILE);
765 op->value *= 9;
766 }
767 else
768 {
769 op->stats.sp = 1; /* regenerate spell points */
770 op->value *= 3;
771 }
772 break;
773
774 case 22:
775 op->stats.exp += bonus; /* Speed! */
776 op->value = (op->value * 2) / 3;
777 break;
699 } 778 }
700 break;
701
702 case 21:
703 if(op->type==AMULET) {
704 SET_FLAG(op,FLAG_REFL_MISSILE);
705 op->value*=9;
706 } else {
707 op->stats.sp=1; /* regenerate spell points */
708 op->value*=3;
709 }
710 break;
711
712 case 22:
713 op->stats.exp+=bonus; /* Speed! */
714 op->value=(op->value*2)/3;
715 break;
716 }
717 if(bonus>0) 779 if (bonus > 0)
718 op->value*=2*bonus; 780 op->value *= 2 * bonus;
719 else 781 else
720 op->value= -(op->value*2*bonus)/3; 782 op->value = -(op->value * 2 * bonus) / 3;
721} 783}
722 784
723/* 785/*
724 * get_magic(diff) will return a random number between 0 and 4. 786 * get_magic(diff) will return a random number between 0 and 4.
725 * diff can be any value above 2. The higher the diff-variable, the 787 * diff can be any value above 2. The higher the diff-variable, the
727 * It is only used in fix_generated_treasure() to set bonuses on 789 * It is only used in fix_generated_treasure() to set bonuses on
728 * rings and amulets. 790 * rings and amulets.
729 * Another scheme is used to calculate the magic of weapons and armours. 791 * Another scheme is used to calculate the magic of weapons and armours.
730 */ 792 */
731 793
794int
732int get_magic(int diff) { 795get_magic (int diff)
796{
733 int i; 797 int i;
798
734 if(diff<3) 799 if (diff < 3)
735 diff=3; 800 diff = 3;
736 for(i=0;i<4;i++) 801 for (i = 0; i < 4; i++)
737 if(RANDOM()%diff) return i; 802 if (RANDOM () % diff)
803 return i;
738 return 4; 804 return 4;
739} 805}
740 806
741#define DICE2 (get_magic(2)==2?2:1) 807#define DICE2 (get_magic(2)==2?2:1)
742#define DICESPELL (RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3) 808#define DICESPELL (RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3)
744/* 810/*
745 * fix_generated_item(): This is called after an item is generated, in 811 * fix_generated_item(): This is called after an item is generated, in
746 * order to set it up right. This produced magical bonuses, puts spells 812 * order to set it up right. This produced magical bonuses, puts spells
747 * into scrolls/books/wands, makes it unidentified, hides the value, etc. 813 * into scrolls/books/wands, makes it unidentified, hides the value, etc.
748 */ 814 */
815
749/* 4/28/96 added creator object from which op may now inherit properties based on 816/* 4/28/96 added creator object from which op may now inherit properties based on
750 * op->type. Right now, which stuff the creator passes on is object type 817 * op->type. Right now, which stuff the creator passes on is object type
751 * dependant. I know this is a spagetti manuever, but is there a cleaner 818 * dependant. I know this is a spagetti manuever, but is there a cleaner
752 * way to do this? b.t. */ 819 * way to do this? b.t. */
820
753/* 821/*
754 * ! (flags & GT_ENVIRONMENT): 822 * ! (flags & GT_ENVIRONMENT):
755 * Automatically calls fix_flesh_item(). 823 * Automatically calls fix_flesh_item().
756 * 824 *
757 * flags: 825 * flags:
760 * GT_MINIMAL: Does minimal processing on the object - just enough to make it 828 * GT_MINIMAL: Does minimal processing on the object - just enough to make it
761 * a working object - don't change magic, value, etc, but set it material 829 * a working object - don't change magic, value, etc, but set it material
762 * type as appropriate, for objects that need spell objects, set those, etc 830 * type as appropriate, for objects that need spell objects, set those, etc
763 */ 831 */
764 832
833void
765void fix_generated_item (object * op, object * creator, int difficulty, 834fix_generated_item (object *op, object *creator, int difficulty, int max_magic, int flags)
766 int max_magic, int flags)
767{ 835{
768 int was_magic = op->magic, num_enchantments = 0, save_item_power = 0; 836 int was_magic = op->magic, num_enchantments = 0, save_item_power = 0;
769 837
770 if (!creator || creator->type == op->type) 838 if (!creator || creator->type == op->type)
771 creator = op; /*safety & to prevent polymorphed objects giving attributes */ 839 creator = op; /*safety & to prevent polymorphed objects giving attributes */
776 844
777 if (op->randomitems && op->type != SPELL) 845 if (op->randomitems && op->type != SPELL)
778 { 846 {
779 create_treasure (op->randomitems, op, flags, difficulty, 0); 847 create_treasure (op->randomitems, op, flags, difficulty, 0);
780 if (!op->inv) 848 if (!op->inv)
781 LOG (llevDebug,
782 "fix_generated_item: Unable to generate treasure for %s\n", 849 LOG (llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", &op->name);
783 op->name);
784 850
785 /* So the treasure doesn't get created again */ 851 /* So the treasure doesn't get created again */
786 op->randomitems = NULL; 852 op->randomitems = NULL;
787 } 853 }
788 854
789 if (difficulty < 1) 855 if (difficulty < 1)
790 difficulty = 1; 856 difficulty = 1;
857
858 if (INVOKE_OBJECT (ADD_BONUS, op,
859 ARG_OBJECT (creator != op ? creator : 0),
860 ARG_INT (difficulty), ARG_INT (max_magic),
861 ARG_INT (flags)))
862 return;
791 863
792 if (!(flags & GT_MINIMAL)) 864 if (!(flags & GT_MINIMAL))
793 { 865 {
794 if (op->arch == crown_arch) 866 if (op->arch == crown_arch)
795 { 867 {
802 if (!op->magic && max_magic) 874 if (!op->magic && max_magic)
803 set_magic (difficulty, op, max_magic, flags); 875 set_magic (difficulty, op, max_magic, flags);
804 876
805 num_enchantments = calc_item_power (op, 1); 877 num_enchantments = calc_item_power (op, 1);
806 878
807 if ((!was_magic && !(RANDOM () % CHANCE_FOR_ARTIFACT)) 879 if ((!was_magic && !(RANDOM () % CHANCE_FOR_ARTIFACT)) || op->type == HORN || difficulty >= settings.max_level) /* high difficulties always generate an artifact,
808 || op->type == HORN 880 * used for shop_floors or treasures */
809 || difficulty >= settings.max_level) /* high difficulties always generate an artifact,
810 * used for shop_floors or treasures */
811 generate_artifact (op, difficulty); 881 generate_artifact (op, difficulty);
812 } 882 }
813 883
814 /* Object was made an artifact. Calculate its item_power rating. 884 /* Object was made an artifact. Calculate its item_power rating.
815 * the item_power in the object is what the artfiact adds. 885 * the item_power in the object is what the artfiact adds.
822 * out the power from the base power plus what this one adds. Note 892 * out the power from the base power plus what this one adds. Note
823 * that since item_power is not quite linear, this actually ends up 893 * that since item_power is not quite linear, this actually ends up
824 * being somewhat of a bonus 894 * being somewhat of a bonus
825 */ 895 */
826 if (save_item_power) 896 if (save_item_power)
827 op->item_power =
828 save_item_power + get_power_from_ench (op->item_power); 897 op->item_power = save_item_power + get_power_from_ench (op->item_power);
829 else 898 else
830 op->item_power =
831 get_power_from_ench (op->item_power + num_enchantments); 899 op->item_power = get_power_from_ench (op->item_power + num_enchantments);
832 } 900 }
833 else if (save_item_power) 901 else if (save_item_power)
834 { 902 {
835 /* restore the item_power field to the object if we haven't changed it. 903 /* restore the item_power field to the object if we haven't changed it.
836 * we don't care about num_enchantments - that will basically just 904 * we don't care about num_enchantments - that will basically just
844 * was never previously calculated. Let's compute a value and see if 912 * was never previously calculated. Let's compute a value and see if
845 * it is non-zero. If it indeed is, then assign it as the new 913 * it is non-zero. If it indeed is, then assign it as the new
846 * item_power value. 914 * item_power value.
847 * - gros, 21th of July 2006. 915 * - gros, 21th of July 2006.
848 */ 916 */
849 op->item_power = calc_item_power(op,0); 917 op->item_power = calc_item_power (op, 0);
850 save_item_power = op->item_power; /* Just in case it would get used 918 save_item_power = op->item_power; /* Just in case it would get used
851 * again below */ 919 * again below */
852 } 920 }
853 } 921 }
854 922
855 /* materialtype modifications. Note we allow this on artifacts. */ 923 /* materialtype modifications. Note we allow this on artifacts. */
856 set_materialname (op, difficulty, NULL); 924 set_materialname (op, difficulty, NULL);
869 } 937 }
870 } 938 }
871 else if (!op->title) /* Only modify object if not special */ 939 else if (!op->title) /* Only modify object if not special */
872 switch (op->type) 940 switch (op->type)
873 { 941 {
874 case WEAPON: 942 case WEAPON:
875 case ARMOUR: 943 case ARMOUR:
876 case SHIELD: 944 case SHIELD:
877 case HELMET: 945 case HELMET:
878 case CLOAK: 946 case CLOAK:
879 if (QUERY_FLAG (op, FLAG_CURSED) && !(RANDOM () % 4)) 947 if (QUERY_FLAG (op, FLAG_CURSED) && !(RANDOM () % 4))
880 set_ring_bonus (op, -DICE2); 948 set_ring_bonus (op, -DICE2);
881 break; 949 break;
882 950
883 case BRACERS: 951 case BRACERS:
884 if (!(RANDOM () % (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20))) 952 if (!(RANDOM () % (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20)))
953 {
954 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2);
955 if (!QUERY_FLAG (op, FLAG_CURSED))
956 op->value *= 3;
957 }
958 break;
959
960 case POTION:
885 { 961 {
962 int too_many_tries = 0, is_special = 0;
963
964 /* Handle healing and magic power potions */
965 if (op->stats.sp && !op->randomitems)
966 {
967 object *tmp;
968
969 tmp = get_archetype (spell_mapping[op->stats.sp]);
970 insert_ob_in_ob (tmp, op);
971 op->stats.sp = 0;
972 }
973
974 while (!(is_special = special_potion (op)) && !op->inv)
975 {
976 generate_artifact (op, difficulty);
977 if (too_many_tries++ > 10)
978 break;
979 }
980
981 /* don't want to change value for healing/magic power potions,
982 * since the value set on those is already correct.
983 */
984 if (op->inv && op->randomitems)
985 {
986 /* value multiplier is same as for scrolls */
987 op->value = (op->value * op->inv->value);
988 op->level = op->inv->level / 2 + RANDOM () % difficulty + RANDOM () % difficulty;
989 }
990 else
991 {
992 op->name = "potion";
993 op->name_pl = "potions";
994 }
995
996 if (!(flags & GT_ONLY_GOOD) && RANDOM () % 2)
997 SET_FLAG (op, FLAG_CURSED);
998 break;
999 }
1000
1001 case AMULET:
1002 if (op->arch == amulet_arch)
1003 op->value *= 5; /* Since it's not just decoration */
1004
1005 case RING:
1006 if (op->arch == NULL)
1007 {
1008 op->destroy ();
1009 op = 0;
1010 break;
1011 }
1012
1013 if (op->arch != ring_arch && op->arch != amulet_arch) /* It's a special artifact! */
1014 break;
1015
1016 if (!(flags & GT_ONLY_GOOD) && !(RANDOM () % 3))
1017 SET_FLAG (op, FLAG_CURSED);
1018
886 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2); 1019 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2);
887 if (!QUERY_FLAG (op, FLAG_CURSED))
888 op->value *= 3;
889 }
890 break;
891 1020
892 case POTION: 1021 if (op->type != RING) /* Amulets have only one ability */
893 {
894 int too_many_tries = 0, is_special = 0;
895
896 /* Handle healing and magic power potions */
897 if (op->stats.sp && !op->randomitems)
898 {
899 object *tmp;
900
901 tmp = get_archetype (spell_mapping[op->stats.sp]);
902 insert_ob_in_ob (tmp, op);
903 op->stats.sp = 0;
904 }
905
906 while (!(is_special = special_potion (op)) && !op->inv)
907 {
908 generate_artifact (op, difficulty);
909 if (too_many_tries++ > 10)
910 break; 1022 break;
911 }
912
913 /* don't want to change value for healing/magic power potions,
914 * since the value set on those is already correct.
915 */
916 if (op->inv && op->randomitems)
917 {
918 /* value multiplier is same as for scrolls */
919 op->value = (op->value * op->inv->value);
920 op->level =
921 op->inv->level / 2 + RANDOM () % difficulty
922 + RANDOM () % difficulty;
923 }
924 else
925 {
926 FREE_AND_COPY (op->name, "potion");
927 FREE_AND_COPY (op->name_pl, "potions");
928 }
929 if (!(flags & GT_ONLY_GOOD) && RANDOM () % 2)
930 SET_FLAG (op, FLAG_CURSED);
931 break;
932 }
933
934 case AMULET:
935 if (op->arch == amulet_arch)
936 op->value *= 5; /* Since it's not just decoration */
937
938 case RING:
939 if (op->arch == NULL)
940 {
941 remove_ob (op);
942 free_object (op);
943 op = NULL;
944 break;
945 }
946
947 if (op->arch != ring_arch && op->arch != amulet_arch) /* It's a special artifact! */
948 break;
949
950 if (!(flags & GT_ONLY_GOOD) && !(RANDOM () % 3))
951 SET_FLAG (op, FLAG_CURSED);
952
953 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2);
954
955 if (op->type != RING) /* Amulets have only one ability */
956 break;
957
958 if (!(RANDOM () % 4))
959 {
960 int d = (RANDOM () % 2
961 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
962
963 if (d > 0)
964 op->value *= 3;
965
966 set_ring_bonus (op, d);
967 1023
968 if (!(RANDOM () % 4)) 1024 if (!(RANDOM () % 4))
969 { 1025 {
970 int d = (RANDOM () % 3
971 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2; 1026 int d = (RANDOM () % 2 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
1027
972 if (d > 0) 1028 if (d > 0)
973 op->value *= 5; 1029 op->value *= 3;
1030
974 set_ring_bonus (op, d); 1031 set_ring_bonus (op, d);
1032
1033 if (!(RANDOM () % 4))
1034 {
1035 int d = (RANDOM () % 3 || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
1036
1037 if (d > 0)
1038 op->value *= 5;
1039 set_ring_bonus (op, d);
1040 }
975 } 1041 }
976 }
977 1042
978 if (GET_ANIM_ID (op)) 1043 if (GET_ANIM_ID (op))
979 SET_ANIMATION (op, RANDOM () % ((int) NUM_ANIMATIONS (op))); 1044 SET_ANIMATION (op, RANDOM () % ((int) NUM_ANIMATIONS (op)));
980 1045
981 break; 1046 break;
982 1047
983 case BOOK: 1048 case BOOK:
984 /* Is it an empty book?, if yes lets make a special· 1049 /* Is it an empty book?, if yes lets make a special·
985 * msg for it, and tailor its properties based on the· 1050 * msg for it, and tailor its properties based on the·
986 * creator and/or map level we found it on. 1051 * creator and/or map level we found it on.
987 */ 1052 */
988 if (!op->msg && RANDOM () % 10) 1053 if (!op->msg && RANDOM () % 10)
989 {
990 /* set the book level properly */
991 if (creator->level == 0 || QUERY_FLAG (creator, FLAG_ALIVE))
992 { 1054 {
1055 /* set the book level properly */
1056 if (creator->level == 0 || QUERY_FLAG (creator, FLAG_ALIVE))
1057 {
993 if (op->map && op->map->difficulty) 1058 if (op->map && op->map->difficulty)
994 op->level =
995 RANDOM () % (op->map->difficulty) + RANDOM () % 10 + 1; 1059 op->level = RANDOM () % (op->map->difficulty) + RANDOM () % 10 + 1;
1060 else
1061 op->level = RANDOM () % 20 + 1;
1062 }
996 else 1063 else
997 op->level = RANDOM () % 20 + 1; 1064 op->level = RANDOM () % creator->level;
1065
1066 tailor_readable_ob (op, (creator && creator->stats.sp) ? creator->stats.sp : -1);
1067 /* books w/ info are worth more! */
1068 op->value *= ((op->level > 10 ? op->level : (op->level + 1) / 2) * ((strlen (op->msg) / 250) + 1));
1069 /* creator related stuff */
1070
1071 /* for library, chained books. Note that some monsters have no_pick
1072 * set - we don't want to set no pick in that case.
1073 */
1074 if (QUERY_FLAG (creator, FLAG_NO_PICK) && !QUERY_FLAG (creator, FLAG_MONSTER))
1075 SET_FLAG (op, FLAG_NO_PICK);
1076 if (creator->slaying && !op->slaying) /* for check_inv floors */
1077 op->slaying = creator->slaying;
1078
1079 /* add exp so reading it gives xp (once) */
1080 op->stats.exp = op->value > 10000 ? op->value / 5 : op->value / 10;
1081 }
1082 break;
1083
1084 case SPELLBOOK:
1085 op->value = op->value * op->inv->value;
1086 /* add exp so learning gives xp */
1087 op->level = op->inv->level;
1088 op->stats.exp = op->value;
1089 break;
1090
1091 case WAND:
1092 /* nrof in the treasure list is number of charges,
1093 * not number of wands. So copy that into food (charges),
1094 * and reset nrof.
1095 */
1096 op->stats.food = op->inv->nrof;
1097 op->nrof = 1;
1098 /* If the spell changes by level, choose a random level
1099 * for it, and adjust price. If the spell doesn't
1100 * change by level, just set the wand to the level of
1101 * the spell, and value calculation is simpler.
1102 */
1103 if (op->inv->duration_modifier || op->inv->dam_modifier || op->inv->range_modifier)
1104 {
1105 op->level = level_for_item (op, difficulty);
1106 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
998 } 1107 }
999 else 1108 else
1000 op->level = RANDOM () % creator->level; 1109 {
1001
1002 tailor_readable_ob (op,
1003 (creator
1004 && creator->stats.sp) ? creator->stats.
1005 sp : -1);
1006 /* books w/ info are worth more! */
1007 op->value *=
1008 ((op->level >
1009 10 ? op->level : (op->level + 1110 op->level = op->inv->level;
1010 1) / 2) * ((strlen (op->msg) / 250) + 1)); 1111 op->value = op->value * op->inv->value;
1011 /* creator related stuff */ 1112 }
1113 break;
1012 1114
1013 /* for library, chained books. Note that some monsters have no_pick 1115 case ROD:
1014 * set - we don't want to set no pick in that case. 1116 op->level = level_for_item (op, difficulty);
1117 /* Add 50 to both level an divisor to keep prices a little more
1118 * reasonable. Otherwise, a high level version of a low level
1119 * spell can be worth tons a money (eg, level 20 rod, level 2 spell =
1120 * 10 time multiplier). This way, the value are a bit more reasonable.
1015 */ 1121 */
1016 if (QUERY_FLAG (creator, FLAG_NO_PICK) && 1122 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1017 !QUERY_FLAG (creator, FLAG_MONSTER)) 1123 /* maxhp is used to denote how many 'charges' the rod holds before */
1018 SET_FLAG (op, FLAG_NO_PICK);
1019 if (creator->slaying && !op->slaying) /* for check_inv floors */
1020 op->slaying = add_string (creator->slaying);
1021
1022 /* add exp so reading it gives xp (once) */
1023 op->stats.exp = 1124 if (op->stats.maxhp)
1024 op->value > 10000 ? op->value / 5 : op->value / 10; 1125 op->stats.maxhp *= MAX (op->inv->stats.sp, op->inv->stats.grace);
1025 } 1126 else
1127 op->stats.maxhp = 2 * MAX (op->inv->stats.sp, op->inv->stats.grace);
1128
1129 op->stats.hp = op->stats.maxhp;
1026 break; 1130 break;
1027 1131
1028 case SPELLBOOK: 1132 case SCROLL:
1029 op->value = op->value * op->inv->value;
1030 /* add exp so learning gives xp */
1031 op->level = op->inv->level;
1032 op->stats.exp = op->value;
1033 break;
1034
1035 case WAND:
1036 /* nrof in the treasure list is number of charges,
1037 * not number of wands. So copy that into food (charges),
1038 * and reset nrof.
1039 */
1040 op->stats.food = op->inv->nrof;
1041 op->nrof = 1;
1042 /* If the spell changes by level, choose a random level
1043 * for it, and adjust price. If the spell doesn't
1044 * change by level, just set the wand to the level of
1045 * the spell, and value calculation is simpler.
1046 */
1047 if (op->inv->duration_modifier || op->inv->dam_modifier ||
1048 op->inv->range_modifier)
1049 {
1050 op->level = level_for_item (op, difficulty); 1133 op->level = level_for_item (op, difficulty);
1051 op->value = op->value * op->inv->value * (op->level + 50) /
1052 (op->inv->level + 50);
1053 }
1054 else
1055 {
1056 op->level = op->inv->level;
1057 op->value = op->value * op->inv->value;
1058 }
1059 break;
1060
1061 case ROD:
1062 op->level = level_for_item (op, difficulty);
1063 /* Add 50 to both level an divisor to keep prices a little more
1064 * reasonable. Otherwise, a high level version of a low level
1065 * spell can be worth tons a money (eg, level 20 rod, level 2 spell =
1066 * 10 time multiplier). This way, the value are a bit more reasonable.
1067 */
1068 op->value =
1069 op->value * op->inv->value * (op->level + 50) / (op->inv->level + 1134 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1070 50);
1071 /* maxhp is used to denote how many 'charges' the rod holds before */
1072 if (op->stats.maxhp)
1073 op->stats.maxhp *= MAX (op->inv->stats.sp, op->inv->stats.grace);
1074 else
1075 op->stats.maxhp = 2 * MAX (op->inv->stats.sp, op->inv->stats.grace);
1076 1135
1077 op->stats.hp = op->stats.maxhp;
1078 break;
1079
1080 case SCROLL:
1081 op->level = level_for_item (op, difficulty);
1082 op->value =
1083 op->value * op->inv->value
1084 * (op->level + 50) / (op->inv->level + 50);
1085
1086 /* add exp so reading them properly gives xp */ 1136 /* add exp so reading them properly gives xp */
1087 op->stats.exp = op->value / 5; 1137 op->stats.exp = op->value / 5;
1088 op->nrof = op->inv->nrof; 1138 op->nrof = op->inv->nrof;
1089 break; 1139 break;
1090 1140
1091 case RUNE: 1141 case RUNE:
1092 trap_adjust (op, difficulty); 1142 trap_adjust (op, difficulty);
1093 break; 1143 break;
1094 1144
1095 case TRAP: 1145 case TRAP:
1096 trap_adjust (op, difficulty); 1146 trap_adjust (op, difficulty);
1097 break; 1147 break;
1098 } /* switch type */ 1148 } /* switch type */
1099 1149
1100 if (flags & GT_STARTEQUIP) 1150 if (flags & GT_STARTEQUIP)
1101 { 1151 {
1102 if (op->nrof < 2 && op->type != CONTAINER 1152 if (op->nrof < 2 && op->type != CONTAINER && op->type != MONEY && !QUERY_FLAG (op, FLAG_IS_THROWN))
1103 && op->type != MONEY && !QUERY_FLAG (op, FLAG_IS_THROWN))
1104 SET_FLAG (op, FLAG_STARTEQUIP); 1153 SET_FLAG (op, FLAG_STARTEQUIP);
1105 else if (op->type != MONEY) 1154 else if (op->type != MONEY)
1106 op->value = 0; 1155 op->value = 0;
1107 } 1156 }
1108 1157
1120 1169
1121/* 1170/*
1122 * Allocate and return the pointer to an empty artifactlist structure. 1171 * Allocate and return the pointer to an empty artifactlist structure.
1123 */ 1172 */
1124 1173
1125static artifactlist *get_empty_artifactlist(void) { 1174static artifactlist *
1175get_empty_artifactlist (void)
1176{
1126 artifactlist *tl = (artifactlist *) malloc(sizeof(artifactlist)); 1177 artifactlist *al = (artifactlist *) malloc (sizeof (artifactlist));
1178
1127 if(tl==NULL) 1179 if (al == NULL)
1128 fatal(OUT_OF_MEMORY); 1180 fatal (OUT_OF_MEMORY);
1129 tl->next=NULL; 1181 al->next = NULL;
1130 tl->items=NULL; 1182 al->items = NULL;
1131 tl->total_chance=0; 1183 al->total_chance = 0;
1132 return tl; 1184 return al;
1133} 1185}
1134 1186
1135/* 1187/*
1136 * Allocate and return the pointer to an empty artifact structure. 1188 * Allocate and return the pointer to an empty artifact structure.
1137 */ 1189 */
1138 1190
1139static artifact *get_empty_artifact(void) { 1191static artifact *
1192get_empty_artifact (void)
1193{
1140 artifact *t = (artifact *) malloc(sizeof(artifact)); 1194 artifact *a = (artifact *) malloc (sizeof (artifact));
1195
1141 if(t==NULL) 1196 if (a == NULL)
1142 fatal(OUT_OF_MEMORY); 1197 fatal (OUT_OF_MEMORY);
1143 t->item=NULL; 1198 a->item = NULL;
1144 t->next=NULL; 1199 a->next = NULL;
1145 t->chance=0; 1200 a->chance = 0;
1146 t->difficulty=0; 1201 a->difficulty = 0;
1147 t->allowed = NULL; 1202 a->allowed = NULL;
1148 return t; 1203 return a;
1149} 1204}
1150 1205
1151/* 1206/*
1152 * Searches the artifact lists and returns one that has the same type 1207 * Searches the artifact lists and returns one that has the same type
1153 * of objects on it. 1208 * of objects on it.
1154 */ 1209 */
1155 1210
1211artifactlist *
1156artifactlist *find_artifactlist(int type) { 1212find_artifactlist (int type)
1213{
1157 artifactlist *al; 1214 artifactlist *al;
1158 1215
1159 for (al=first_artifactlist; al!=NULL; al=al->next) 1216 for (al = first_artifactlist; al != NULL; al = al->next)
1160 if (al->type == type) return al; 1217 if (al->type == type)
1218 return al;
1161 return NULL; 1219 return NULL;
1162} 1220}
1163 1221
1164/* 1222/*
1165 * For debugging purposes. Dumps all tables. 1223 * For debugging purposes. Dumps all tables.
1166 */ 1224 */
1167 1225
1226void
1168void dump_artifacts(void) { 1227dump_artifacts (void)
1228{
1169 artifactlist *al; 1229 artifactlist *al;
1170 artifact *art; 1230 artifact *art;
1171 linked_char *next; 1231 linked_char *next;
1172 1232
1173 fprintf(logfile,"\n"); 1233 fprintf (logfile, "\n");
1174 for (al=first_artifactlist; al!=NULL; al=al->next) { 1234 for (al = first_artifactlist; al != NULL; al = al->next)
1235 {
1175 fprintf(logfile, "Artifact has type %d, total_chance=%d\n", al->type, al->total_chance); 1236 fprintf (logfile, "Artifact has type %d, total_chance=%d\n", al->type, al->total_chance);
1176 for (art=al->items; art!=NULL; art=art->next) { 1237 for (art = al->items; art != NULL; art = art->next)
1177 fprintf(logfile,"Artifact %-30s Difficulty %3d Chance %5d\n", 1238 {
1178 art->item->name, art->difficulty, art->chance); 1239 fprintf (logfile, "Artifact %-30s Difficulty %3d Chance %5d\n", &art->item->name, art->difficulty, art->chance);
1179 if (art->allowed !=NULL) { 1240 if (art->allowed != NULL)
1241 {
1180 fprintf(logfile,"\tAllowed combinations:"); 1242 fprintf (logfile, "\tAllowed combinations:");
1181 for (next=art->allowed; next!=NULL; next=next->next) 1243 for (next = art->allowed; next != NULL; next = next->next)
1182 fprintf(logfile, "%s,", next->name); 1244 fprintf (logfile, "%s,", &next->name);
1183 fprintf(logfile,"\n"); 1245 fprintf (logfile, "\n");
1246 }
1184 } 1247 }
1185 }
1186 } 1248 }
1187 fprintf(logfile,"\n"); 1249 fprintf (logfile, "\n");
1188} 1250}
1189 1251
1190/* 1252/*
1191 * For debugging purposes. Dumps all treasures recursively (see below). 1253 * For debugging purposes. Dumps all treasures recursively (see below).
1192 */ 1254 */
1255void
1193void dump_monster_treasure_rec (const char *name, treasure *t, int depth) 1256dump_monster_treasure_rec (const char *name, treasure *t, int depth)
1194{ 1257{
1195 treasurelist *tl; 1258 treasurelist *tl;
1196 int i; 1259 int i;
1197 1260
1198 if (depth > 100) 1261 if (depth > 100)
1199 return; 1262 return;
1200 while (t != NULL) 1263 while (t)
1201 { 1264 {
1202 if (t->name != NULL) 1265 if (t->name)
1203 { 1266 {
1204 for (i = 0; i < depth; i++) 1267 for (i = 0; i < depth; i++)
1205 fprintf (logfile, " "); 1268 fprintf (logfile, " ");
1206 fprintf (logfile, "{ (list: %s)\n", t->name); 1269 fprintf (logfile, "{ (list: %s)\n", &t->name);
1207 tl = find_treasurelist (t->name); 1270 tl = find_treasurelist (t->name);
1271 if (tl)
1208 dump_monster_treasure_rec (name, tl->items, depth + 2); 1272 dump_monster_treasure_rec (name, tl->items, depth + 2);
1209 for (i = 0; i < depth; i++) 1273 for (i = 0; i < depth; i++)
1210 fprintf (logfile, " "); 1274 fprintf (logfile, " ");
1211 fprintf (logfile, "} (end of list: %s)\n", t->name); 1275 fprintf (logfile, "} (end of list: %s)\n", &t->name);
1212 } 1276 }
1213 else 1277 else
1214 { 1278 {
1215 for (i = 0; i < depth; i++) 1279 for (i = 0; i < depth; i++)
1216 fprintf (logfile, " "); 1280 fprintf (logfile, " ");
1217 if (t->item->clone.type == FLESH) 1281 if (t->item && t->item->clone.type == FLESH)
1218 fprintf (logfile, "%s's %s\n", name, t->item->clone.name); 1282 fprintf (logfile, "%s's %s\n", name, &t->item->clone.name);
1219 else 1283 else
1220 fprintf (logfile, "%s\n", t->item->clone.name); 1284 fprintf (logfile, "%s\n", &t->item->clone.name);
1221 } 1285 }
1286
1222 if (t->next_yes != NULL) 1287 if (t->next_yes)
1223 { 1288 {
1224 for (i = 0; i < depth; i++) 1289 for (i = 0; i < depth; i++)
1225 fprintf (logfile, " "); 1290 fprintf (logfile, " ");
1226 fprintf (logfile, " (if yes)\n"); 1291 fprintf (logfile, " (if yes)\n");
1227 dump_monster_treasure_rec (name, t->next_yes, depth + 1); 1292 dump_monster_treasure_rec (name, t->next_yes, depth + 1);
1228 } 1293 }
1294
1229 if (t->next_no != NULL) 1295 if (t->next_no)
1230 { 1296 {
1231 for (i = 0; i < depth; i++) 1297 for (i = 0; i < depth; i++)
1232 fprintf (logfile, " "); 1298 fprintf (logfile, " ");
1233 fprintf (logfile, " (if no)\n"); 1299 fprintf (logfile, " (if no)\n");
1234 dump_monster_treasure_rec (name, t->next_no, depth + 1); 1300 dump_monster_treasure_rec (name, t->next_no, depth + 1);
1235 } 1301 }
1302
1236 t = t->next; 1303 t = t->next;
1237 } 1304 }
1238} 1305}
1239 1306
1240/* 1307/*
1241 * For debugging purposes. Dumps all treasures for a given monster. 1308 * For debugging purposes. Dumps all treasures for a given monster.
1242 * Created originally by Raphael Quinet for debugging the alchemy code. 1309 * Created originally by Raphael Quinet for debugging the alchemy code.
1243 */ 1310 */
1244 1311
1312void
1245void dump_monster_treasure (const char *name) 1313dump_monster_treasure (const char *name)
1246{ 1314{
1247 archetype *at; 1315 archetype *at;
1248 int found; 1316 int found;
1249 1317
1250 found = 0; 1318 found = 0;
1251 fprintf (logfile, "\n"); 1319 fprintf (logfile, "\n");
1252 for (at = first_archetype; at != NULL; at = at->next) 1320 for (at = first_archetype; at != NULL; at = at->next)
1253 if (! strcasecmp (at->clone.name, name) && at->clone.title == NULL) 1321 if (!strcasecmp (at->clone.name, name) && at->clone.title == NULL)
1254 { 1322 {
1255 fprintf (logfile, "treasures for %s (arch: %s)\n", at->clone.name, 1323 fprintf (logfile, "treasures for %s (arch: %s)\n", &at->clone.name, &at->name);
1256 at->name);
1257 if (at->clone.randomitems != NULL) 1324 if (at->clone.randomitems != NULL)
1258 dump_monster_treasure_rec (at->clone.name, 1325 dump_monster_treasure_rec (at->clone.name, at->clone.randomitems->items, 1);
1259 at->clone.randomitems->items, 1); 1326 else
1260 else
1261 fprintf (logfile, "(nothing)\n"); 1327 fprintf (logfile, "(nothing)\n");
1262 fprintf (logfile, "\n"); 1328 fprintf (logfile, "\n");
1263 found++; 1329 found++;
1264 } 1330 }
1265 if (found == 0) 1331 if (found == 0)
1266 fprintf (logfile, "No objects have the name %s!\n\n", name); 1332 fprintf (logfile, "No objects have the name %s!\n\n", name);
1267} 1333}
1268 1334
1269/* 1335/*
1270 * Builds up the lists of artifacts from the file in the libdir. 1336 * Builds up the lists of artifacts from the file in the libdir.
1271 */ 1337 */
1272 1338
1339void
1273void init_artifacts(void) { 1340init_artifacts (void)
1341{
1274 static int has_been_inited=0; 1342 static int has_been_inited = 0;
1275 FILE *fp;
1276 char filename[MAX_BUF], buf[HUGE_BUF], *cp, *next; 1343 char filename[MAX_BUF], buf[HUGE_BUF], *cp, *next;
1277 artifact *art=NULL; 1344 artifact *art = NULL;
1278 linked_char *tmp; 1345 linked_char *tmp;
1279 int value, comp; 1346 int value;
1280 artifactlist *al; 1347 artifactlist *al;
1281 1348
1282 if (has_been_inited) return; 1349 if (has_been_inited)
1350 return;
1351 else
1283 else has_been_inited = 1; 1352 has_been_inited = 1;
1284 1353
1285 sprintf(filename, "%s/artifacts", settings.datadir); 1354 sprintf (filename, "%s/artifacts", settings.datadir);
1286 LOG(llevDebug, "Reading artifacts from %s...",filename); 1355 object_thawer thawer (filename);
1287 if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
1288 LOG(llevError, "Can't open %s.\n", filename);
1289 return;
1290 }
1291 1356
1357 if (!thawer)
1358 return;
1359
1292 while (fgets(buf, HUGE_BUF, fp)!=NULL) { 1360 while (fgets (buf, HUGE_BUF, thawer) != NULL)
1293 if (*buf=='#') continue;
1294 if((cp=strchr(buf,'\n'))!=NULL)
1295 *cp='\0';
1296 cp=buf;
1297 while(*cp==' ') /* Skip blanks */
1298 cp++;
1299 if (*cp=='\0') continue;
1300 1361 {
1362 if (*buf == '#')
1363 continue;
1364 if ((cp = strchr (buf, '\n')) != NULL)
1365 *cp = '\0';
1366 cp = buf;
1367 while (*cp == ' ') /* Skip blanks */
1368 cp++;
1369 if (*cp == '\0')
1370 continue;
1371
1301 if (!strncmp(cp, "Allowed", 7)) { 1372 if (!strncmp (cp, "Allowed", 7))
1302 if (art==NULL) {
1303 art=get_empty_artifact();
1304 nrofartifacts++;
1305 } 1373 {
1374 if (art == NULL)
1375 {
1376 art = get_empty_artifact ();
1377 nrofartifacts++;
1378 }
1306 cp = strchr(cp,' ') + 1; 1379 cp = strchr (cp, ' ') + 1;
1307 if (!strcmp(cp,"all")) continue; 1380 if (!strcmp (cp, "all"))
1381 continue;
1308 1382
1309 do { 1383 do
1310 nrofallowedstr++; 1384 {
1385 nrofallowedstr++;
1311 if ((next=strchr(cp, ','))!=NULL) 1386 if ((next = strchr (cp, ',')) != NULL)
1312 *(next++) = '\0'; 1387 *(next++) = '\0';
1313 tmp = (linked_char*) malloc(sizeof(linked_char)); 1388 tmp = new linked_char;
1314 tmp->name = add_string(cp); 1389
1390 tmp->name = cp;
1315 tmp->next = art->allowed; 1391 tmp->next = art->allowed;
1316 art->allowed = tmp; 1392 art->allowed = tmp;
1393 }
1317 } while ((cp=next)!=NULL); 1394 while ((cp = next) != NULL);
1318 } 1395 }
1319 else if (sscanf(cp, "chance %d", &value)) 1396 else if (sscanf (cp, "chance %d", &value))
1320 art->chance = (uint16) value; 1397 art->chance = (uint16) value;
1321 else if (sscanf(cp, "difficulty %d", &value)) 1398 else if (sscanf (cp, "difficulty %d", &value))
1322 art->difficulty = (uint8) value; 1399 art->difficulty = (uint8) value;
1323 else if (!strncmp(cp, "Object",6)) { 1400 else if (!strncmp (cp, "Object", 6))
1324 art->item = (object *) calloc(1, sizeof(object)); 1401 {
1325 reset_object(art->item); 1402 art->item = object::create ();
1326 if (!load_object(fp, art->item,LO_LINEMODE,0)) 1403
1404 if (!load_object (thawer, art->item, 0))
1327 LOG(llevError,"Init_Artifacts: Could not load object.\n"); 1405 LOG (llevError, "Init_Artifacts: Could not load object.\n");
1406
1328 art->item->name = add_string((strchr(cp, ' ')+1)); 1407 art->item->name = strchr (cp, ' ') + 1;
1329 al=find_artifactlist(art->item->type); 1408 al = find_artifactlist (art->item->type);
1330 if (al==NULL) { 1409 if (al == NULL)
1410 {
1331 al = get_empty_artifactlist(); 1411 al = get_empty_artifactlist ();
1332 al->type = art->item->type; 1412 al->type = art->item->type;
1333 al->next = first_artifactlist; 1413 al->next = first_artifactlist;
1334 first_artifactlist = al; 1414 first_artifactlist = al;
1335 } 1415 }
1336 art->next = al->items; 1416 art->next = al->items;
1337 al->items = art; 1417 al->items = art;
1338 art = NULL; 1418 art = NULL;
1339 } 1419 }
1340 else 1420 else
1341 LOG(llevError,"Unknown input in artifact file: %s\n", buf); 1421 LOG (llevError, "Unknown input in artifact file: %s\n", buf);
1342 } 1422 }
1343 1423
1344 close_and_delete(fp, comp);
1345
1346 for (al=first_artifactlist; al!=NULL; al=al->next) { 1424 for (al = first_artifactlist; al != NULL; al = al->next)
1425 {
1347 for (art=al->items; art!=NULL; art=art->next) { 1426 for (art = al->items; art != NULL; art = art->next)
1427 {
1348 if (!art->chance) 1428 if (!art->chance)
1349 LOG(llevError,"Warning: artifact with no chance: %s\n", art->item->name); 1429 LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name);
1350 else 1430 else
1351 al->total_chance += art->chance; 1431 al->total_chance += art->chance;
1352 } 1432 }
1353#if 0 1433#if 0
1354 LOG(llevDebug,"Artifact list type %d has %d total chance\n", 1434 LOG (llevDebug, "Artifact list type %d has %d total chance\n", al->type, al->total_chance);
1355 al->type, al->total_chance);
1356#endif 1435#endif
1357 } 1436 }
1358 1437
1359 LOG(llevDebug,"done.\n"); 1438 LOG (llevDebug, "done.\n");
1360} 1439}
1361 1440
1362 1441
1363/* 1442/*
1364 * Used in artifact generation. The bonuses of the first object 1443 * Used in artifact generation. The bonuses of the first object
1365 * is modified by the bonuses of the second object. 1444 * is modified by the bonuses of the second object.
1366 */ 1445 */
1367 1446
1447void
1368void add_abilities(object *op, object *change) { 1448add_abilities (object *op, object *change)
1449{
1369 int i,j, tmp; 1450 int i, tmp;
1370 1451
1371 if (change->face != blank_face) { 1452 if (change->face != blank_face)
1453 {
1372#ifdef TREASURE_VERBOSE 1454#ifdef TREASURE_VERBOSE
1373 LOG(llevDebug, "FACE: %d\n", change->face->number); 1455 LOG (llevDebug, "FACE: %d\n", change->face->number);
1374#endif 1456#endif
1375 op->face = change->face; 1457 op->face = change->face;
1376 } 1458 }
1459
1377 for (i = 0; i < NUM_STATS; i++) 1460 for (i = 0; i < NUM_STATS; i++)
1378 change_attr_value(&(op->stats), i, get_attr_value(&(change->stats), i)); 1461 change_attr_value (&(op->stats), i, get_attr_value (&(change->stats), i));
1379 1462
1380 op->attacktype |= change->attacktype; 1463 op->attacktype |= change->attacktype;
1381 op->path_attuned |= change->path_attuned; 1464 op->path_attuned |= change->path_attuned;
1382 op->path_repelled |= change->path_repelled; 1465 op->path_repelled |= change->path_repelled;
1383 op->path_denied |= change->path_denied; 1466 op->path_denied |= change->path_denied;
1384 op->move_type |= change->move_type; 1467 op->move_type |= change->move_type;
1385 op->stats.luck += change->stats.luck; 1468 op->stats.luck += change->stats.luck;
1386 1469
1387 if (QUERY_FLAG(change,FLAG_CURSED)) SET_FLAG(op, FLAG_CURSED); 1470 if (QUERY_FLAG (change, FLAG_CURSED))
1388 if (QUERY_FLAG(change,FLAG_DAMNED)) SET_FLAG(op, FLAG_DAMNED); 1471 SET_FLAG (op, FLAG_CURSED);
1472 if (QUERY_FLAG (change, FLAG_DAMNED))
1473 SET_FLAG (op, FLAG_DAMNED);
1389 if ((QUERY_FLAG(change,FLAG_CURSED) || QUERY_FLAG(change,FLAG_DAMNED)) 1474 if ((QUERY_FLAG (change, FLAG_CURSED) || QUERY_FLAG (change, FLAG_DAMNED)) && op->magic > 0)
1390 && op->magic > 0)
1391 set_abs_magic(op, -op->magic); 1475 set_abs_magic (op, -op->magic);
1392 1476
1393 if (QUERY_FLAG(change,FLAG_LIFESAVE)) SET_FLAG(op,FLAG_LIFESAVE); 1477 if (QUERY_FLAG (change, FLAG_LIFESAVE))
1394 if (QUERY_FLAG(change,FLAG_REFL_SPELL)) SET_FLAG(op,FLAG_REFL_SPELL); 1478 SET_FLAG (op, FLAG_LIFESAVE);
1395 if (QUERY_FLAG(change,FLAG_STEALTH)) SET_FLAG(op,FLAG_STEALTH); 1479 if (QUERY_FLAG (change, FLAG_REFL_SPELL))
1396 if (QUERY_FLAG(change,FLAG_XRAYS)) SET_FLAG(op,FLAG_XRAYS); 1480 SET_FLAG (op, FLAG_REFL_SPELL);
1397 if (QUERY_FLAG(change,FLAG_BLIND)) SET_FLAG(op,FLAG_BLIND); 1481 if (QUERY_FLAG (change, FLAG_STEALTH))
1398 if (QUERY_FLAG(change,FLAG_SEE_IN_DARK)) SET_FLAG(op,FLAG_SEE_IN_DARK); 1482 SET_FLAG (op, FLAG_STEALTH);
1399 if (QUERY_FLAG(change,FLAG_REFL_MISSILE)) SET_FLAG(op,FLAG_REFL_MISSILE); 1483 if (QUERY_FLAG (change, FLAG_XRAYS))
1400 if (QUERY_FLAG(change,FLAG_MAKE_INVIS)) SET_FLAG(op,FLAG_MAKE_INVIS); 1484 SET_FLAG (op, FLAG_XRAYS);
1485 if (QUERY_FLAG (change, FLAG_BLIND))
1486 SET_FLAG (op, FLAG_BLIND);
1487 if (QUERY_FLAG (change, FLAG_SEE_IN_DARK))
1488 SET_FLAG (op, FLAG_SEE_IN_DARK);
1489 if (QUERY_FLAG (change, FLAG_REFL_MISSILE))
1490 SET_FLAG (op, FLAG_REFL_MISSILE);
1491 if (QUERY_FLAG (change, FLAG_MAKE_INVIS))
1492 SET_FLAG (op, FLAG_MAKE_INVIS);
1401 1493
1402 if (QUERY_FLAG(change,FLAG_STAND_STILL)) { 1494 if (QUERY_FLAG (change, FLAG_STAND_STILL))
1495 {
1403 CLEAR_FLAG(op,FLAG_ANIMATE); 1496 CLEAR_FLAG (op, FLAG_ANIMATE);
1404 /* so artifacts will join */ 1497 /* so artifacts will join */
1405 if(!QUERY_FLAG(op,FLAG_ALIVE)) op->speed = 0.0; 1498 if (!QUERY_FLAG (op, FLAG_ALIVE))
1406 update_ob_speed(op); 1499 op->speed = 0.0;
1500
1501 op->set_speed (op->speed);
1407 } 1502 }
1408 if(change->nrof) op->nrof=RANDOM()%((int) change->nrof) + 1; 1503
1504 if (change->nrof)
1505 op->nrof = RANDOM () % ((int) change->nrof) + 1;
1506
1409 op->stats.exp += change->stats.exp; /* Speed modifier */ 1507 op->stats.exp += change->stats.exp; /* Speed modifier */
1410 op->stats.wc += change->stats.wc; 1508 op->stats.wc += change->stats.wc;
1411 op->stats.ac += change->stats.ac; 1509 op->stats.ac += change->stats.ac;
1412 1510
1413 if (change->other_arch) { 1511 if (change->other_arch)
1512 {
1414 /* Basically, for horns & potions, the other_arch field is the spell 1513 /* Basically, for horns & potions, the other_arch field is the spell
1415 * to cast. So convert that to into a spell and put it into 1514 * to cast. So convert that to into a spell and put it into
1416 * this object. 1515 * this object.
1417 */ 1516 */
1418 if (op->type == HORN || op->type == POTION) { 1517 if (op->type == HORN || op->type == POTION)
1518 {
1419 object *tmp_obj; 1519 object *tmp_obj;
1520
1420 /* Remove any spells this object currently has in it */ 1521 /* Remove any spells this object currently has in it */
1421 while (op->inv) { 1522 while (op->inv)
1422 tmp_obj = op->inv; 1523 op->inv->destroy ();
1423 remove_ob(tmp_obj); 1524
1424 free_object(tmp_obj);
1425 }
1426 tmp_obj = arch_to_object(change->other_arch); 1525 tmp_obj = arch_to_object (change->other_arch);
1427 insert_ob_in_ob(tmp_obj, op); 1526 insert_ob_in_ob (tmp_obj, op);
1428 } 1527 }
1429 /* No harm setting this for potions/horns */ 1528 /* No harm setting this for potions/horns */
1430 op->other_arch = change->other_arch; 1529 op->other_arch = change->other_arch;
1431 } 1530 }
1432 1531
1433 if (change->stats.hp < 0) 1532 if (change->stats.hp < 0)
1434 op->stats.hp = -change->stats.hp; 1533 op->stats.hp = -change->stats.hp;
1435 else 1534 else
1436 op->stats.hp += change->stats.hp; 1535 op->stats.hp += change->stats.hp;
1536
1437 if (change->stats.maxhp < 0) 1537 if (change->stats.maxhp < 0)
1438 op->stats.maxhp = -change->stats.maxhp; 1538 op->stats.maxhp = -change->stats.maxhp;
1439 else 1539 else
1440 op->stats.maxhp += change->stats.maxhp; 1540 op->stats.maxhp += change->stats.maxhp;
1541
1441 if (change->stats.sp < 0) 1542 if (change->stats.sp < 0)
1442 op->stats.sp = -change->stats.sp; 1543 op->stats.sp = -change->stats.sp;
1443 else 1544 else
1444 op->stats.sp += change->stats.sp; 1545 op->stats.sp += change->stats.sp;
1546
1445 if (change->stats.maxsp < 0) 1547 if (change->stats.maxsp < 0)
1446 op->stats.maxsp = -change->stats.maxsp; 1548 op->stats.maxsp = -change->stats.maxsp;
1447 else 1549 else
1448 op->stats.maxsp += change->stats.maxsp; 1550 op->stats.maxsp += change->stats.maxsp;
1551
1449 if (change->stats.food < 0) 1552 if (change->stats.food < 0)
1450 op->stats.food = -(change->stats.food); 1553 op->stats.food = -(change->stats.food);
1451 else 1554 else
1452 op->stats.food += change->stats.food; 1555 op->stats.food += change->stats.food;
1556
1453 if (change->level < 0) 1557 if (change->level < 0)
1454 op->level = -(change->level); 1558 op->level = -(change->level);
1455 else 1559 else
1456 op->level += change->level; 1560 op->level += change->level;
1457 1561
1458 if (change->gen_sp_armour < 0) 1562 if (change->gen_sp_armour < 0)
1459 op->gen_sp_armour = -(change->gen_sp_armour); 1563 op->gen_sp_armour = -(change->gen_sp_armour);
1460 else 1564 else
1461 op->gen_sp_armour = (op->gen_sp_armour * (change->gen_sp_armour)) / 100; 1565 op->gen_sp_armour = (op->gen_sp_armour * (change->gen_sp_armour)) / 100;
1462 1566
1463 op->item_power = change->item_power; 1567 op->item_power = change->item_power;
1464 1568
1465 for (i=0; i<NROFATTACKS; i++) { 1569 for (i = 0; i < NROFATTACKS; i++)
1466 if (change->resist[i]) { 1570 if (change->resist[i])
1467 op->resist[i] += change->resist[i]; 1571 op->resist[i] += change->resist[i];
1468 } 1572
1469 }
1470 if (change->stats.dam) { 1573 if (change->stats.dam)
1574 {
1471 if (change->stats.dam < 0) 1575 if (change->stats.dam < 0)
1472 op->stats.dam = (-change->stats.dam); 1576 op->stats.dam = (-change->stats.dam);
1473 else if (op->stats.dam) { 1577 else if (op->stats.dam)
1578 {
1474 tmp = (signed char) (((int)op->stats.dam * (int)change->stats.dam)/10); 1579 tmp = (signed char) (((int) op->stats.dam * (int) change->stats.dam) / 10);
1475 if (tmp == op->stats.dam) { 1580 if (tmp == op->stats.dam)
1581 {
1476 if (change->stats.dam < 10) 1582 if (change->stats.dam < 10)
1477 op->stats.dam--; 1583 op->stats.dam--;
1478 else 1584 else
1479 op->stats.dam++; 1585 op->stats.dam++;
1586 }
1587 else
1588 op->stats.dam = tmp;
1589 }
1480 } 1590 }
1481 else 1591
1482 op->stats.dam = tmp;
1483 }
1484 }
1485 if (change->weight) { 1592 if (change->weight)
1593 {
1486 if (change->weight < 0) 1594 if (change->weight < 0)
1487 op->weight = (-change->weight); 1595 op->weight = (-change->weight);
1488 else 1596 else
1489 op->weight = (op->weight * (change->weight)) / 100; 1597 op->weight = (op->weight * (change->weight)) / 100;
1490 } 1598 }
1599
1491 if (change->last_sp) { 1600 if (change->last_sp)
1601 {
1492 if (change->last_sp < 0) 1602 if (change->last_sp < 0)
1493 op->last_sp = (-change->last_sp); 1603 op->last_sp = (-change->last_sp);
1494 else 1604 else
1495 op->last_sp = (signed char) (((int)op->last_sp * (int)change->last_sp) / (int) 100); 1605 op->last_sp = (signed char) (((int) op->last_sp * (int) change->last_sp) / (int) 100);
1496 } 1606 }
1607
1497 if (change->gen_sp_armour) { 1608 if (change->gen_sp_armour)
1609 {
1498 if (change->gen_sp_armour < 0) 1610 if (change->gen_sp_armour < 0)
1499 op->gen_sp_armour = (-change->gen_sp_armour); 1611 op->gen_sp_armour = (-change->gen_sp_armour);
1500 else 1612 else
1501 op->gen_sp_armour = (signed char) (((int)op->gen_sp_armour * ((int)change->gen_sp_armour)) 1613 op->gen_sp_armour = (signed char) (((int) op->gen_sp_armour * ((int) change->gen_sp_armour)) / (int) 100);
1502 / (int)100);
1503 } 1614 }
1615
1504 op->value *= change->value; 1616 op->value *= change->value;
1505 1617
1618 if (change->material)
1506 if(change->material) op->material = change->material; 1619 op->material = change->material;
1507 1620
1508 if (change->materialname) { 1621 if (change->materialname)
1509 if (op->materialname)
1510 free_string(op->materialname);
1511 op->materialname = add_refcount(change->materialname); 1622 op->materialname = change->materialname;
1512 }
1513 1623
1514 if (change->slaying) { 1624 if (change->slaying)
1515 if (op->slaying)
1516 free_string(op->slaying);
1517 op->slaying = add_refcount(change->slaying); 1625 op->slaying = change->slaying;
1518 } 1626
1519 if (change->race) { 1627 if (change->race)
1520 if (op->race) 1628 op->race = change->race;
1521 free_string(op->race); 1629
1522 op->race = add_refcount(change->race);
1523 }
1524 if (change->msg) { 1630 if (change->msg)
1525 if (op->msg) 1631 op->msg = change->msg;
1526 free_string(op->msg);
1527 op->msg = add_refcount(change->msg);
1528 }
1529 /* GROS: Added support for event_... in artifact file */
1530 for(j=0;j<NR_EVENTS;j++) {
1531 event *evt;
1532 event *evt2;
1533 event *evtn;
1534 event *evtp;
1535
1536 evt = find_event(change,j);
1537 evt2= find_event(op,j);
1538
1539 if ((evt) && (evt->hook)) {
1540 if ((evt2)&&(evt2->hook)) {
1541 free_string(evt2->hook);
1542 free_string(evt2->plugin);
1543 free_string(evt2->options);
1544 evtp = NULL;
1545 evtn = evt2->next;
1546 if (evt2 == op->events) {
1547 free(evt2);
1548 op->events = evtn;
1549 }
1550 else {
1551 evtp = op->events;
1552 while (evtp->next != evt2)
1553 evtp = evtp->next;
1554 free(evt2);
1555 evtp->next = evtn;
1556 }
1557 }
1558 else if (evt2 == NULL) {
1559 if (op->events == NULL) {
1560 evt2 = (event *)malloc(sizeof(event));
1561 op->events = evt2;
1562 }
1563 else {
1564 evtp = op->events;
1565 while (evtp->next != NULL)
1566 evtp = evtp->next;
1567 evtp->next = (event *)malloc(sizeof(event));
1568 evt2 = evtp->next;
1569 }
1570 }
1571 evt2->next = NULL;
1572 evt2->hook = add_refcount(evt->hook);
1573 evt2->plugin = add_refcount(evt->plugin);
1574 evt2->type = j;
1575
1576 if (evt->options)
1577 evt2->options = add_refcount(evt->options);
1578 else
1579 evt2->options = NULL;
1580 }
1581 }
1582} 1632}
1583 1633
1634static int
1584static int legal_artifact_combination(object *op, artifact *art) { 1635legal_artifact_combination (object *op, artifact * art)
1636{
1585 int neg, success = 0; 1637 int neg, success = 0;
1586 linked_char *tmp; 1638 linked_char *tmp;
1587 const char *name; 1639 const char *name;
1588 1640
1589 if (art->allowed == (linked_char *) NULL) 1641 if (art->allowed == (linked_char *) NULL)
1590 return 1; /* Ie, "all" */ 1642 return 1; /* Ie, "all" */
1591 for (tmp = art->allowed; tmp; tmp = tmp->next) { 1643 for (tmp = art->allowed; tmp; tmp = tmp->next)
1644 {
1592#ifdef TREASURE_VERBOSE 1645#ifdef TREASURE_VERBOSE
1593 LOG(llevDebug, "legal_art: %s\n", tmp->name); 1646 LOG (llevDebug, "legal_art: %s\n", tmp->name);
1594#endif 1647#endif
1595 if (*tmp->name == '!') 1648 if (*tmp->name == '!')
1596 name = tmp->name + 1, neg = 1; 1649 name = tmp->name + 1, neg = 1;
1597 else 1650 else
1598 name = tmp->name, neg = 0; 1651 name = tmp->name, neg = 0;
1599 1652
1600 /* If we match name, then return the opposite of 'neg' */ 1653 /* If we match name, then return the opposite of 'neg' */
1601 if (!strcmp(name,op->name) || (op->arch && !strcmp(name,op->arch->name))) 1654 if (!strcmp (name, op->name) || (op->arch && !strcmp (name, op->arch->name)))
1602 return !neg; 1655 return !neg;
1603 1656
1604 /* Set success as true, since if the match was an inverse, it means 1657 /* Set success as true, since if the match was an inverse, it means
1605 * everything is allowed except what we match 1658 * everything is allowed except what we match
1606 */ 1659 */
1607 else if (neg) 1660 else if (neg)
1608 success = 1; 1661 success = 1;
1609 } 1662 }
1610 return success; 1663 return success;
1611} 1664}
1612 1665
1613/* 1666/*
1614 * Fixes the given object, giving it the abilities and titles 1667 * Fixes the given object, giving it the abilities and titles
1615 * it should have due to the second artifact-template. 1668 * it should have due to the second artifact-template.
1616 */ 1669 */
1617 1670
1671void
1618void give_artifact_abilities(object *op, object *artifct) { 1672give_artifact_abilities (object *op, object *artifct)
1673{
1619 char new_name[MAX_BUF]; 1674 char new_name[MAX_BUF];
1620 1675
1621 sprintf(new_name, "of %s", artifct->name); 1676 sprintf (new_name, "of %s", &artifct->name);
1622 if (op->title)
1623 free_string(op->title);
1624 op->title = add_string(new_name); 1677 op->title = new_name;
1625 add_abilities(op, artifct); /* Give out the bonuses */ 1678 add_abilities (op, artifct); /* Give out the bonuses */
1626 1679
1627#if 0 /* Bit verbose, but keep it here until next time I need it... */ 1680#if 0 /* Bit verbose, but keep it here until next time I need it... */
1628 { 1681 {
1629 char identified = QUERY_FLAG(op, FLAG_IDENTIFIED); 1682 char identified = QUERY_FLAG (op, FLAG_IDENTIFIED);
1683
1630 SET_FLAG(op, FLAG_IDENTIFIED); 1684 SET_FLAG (op, FLAG_IDENTIFIED);
1631 LOG(llevDebug, "Generated artifact %s %s [%s]\n", 1685 LOG (llevDebug, "Generated artifact %s %s [%s]\n", op->name, op->title, describe_item (op, NULL));
1632 op->name, op->title, describe_item(op, NULL));
1633 if (!identified) 1686 if (!identified)
1634 CLEAR_FLAG(op, FLAG_IDENTIFIED); 1687 CLEAR_FLAG (op, FLAG_IDENTIFIED);
1635 } 1688 }
1636#endif 1689#endif
1637 return; 1690 return;
1638} 1691}
1639 1692
1646 */ 1699 */
1647 1700
1648/* Give 1 re-roll attempt per artifact */ 1701/* Give 1 re-roll attempt per artifact */
1649#define ARTIFACT_TRIES 2 1702#define ARTIFACT_TRIES 2
1650 1703
1704void
1651void generate_artifact(object *op, int difficulty) { 1705generate_artifact (object *op, int difficulty)
1706{
1652 artifactlist *al; 1707 artifactlist *al;
1653 artifact *art; 1708 artifact *art;
1654 int i; 1709 int i;
1655 1710
1656 al = find_artifactlist(op->type); 1711 al = find_artifactlist (op->type);
1657 1712
1658 if (al==NULL) { 1713 if (al == NULL)
1714 {
1659#if 0 /* This is too verbose, usually */ 1715#if 0 /* This is too verbose, usually */
1660 LOG(llevDebug, "Couldn't change %s into artifact - no table.\n", op->name); 1716 LOG (llevDebug, "Couldn't change %s into artifact - no table.\n", op->name);
1661#endif
1662 return;
1663 }
1664
1665 for (i = 0; i < ARTIFACT_TRIES; i++) {
1666 int roll = RANDOM()% al->total_chance;
1667
1668 for (art=al->items; art!=NULL; art=art->next) {
1669 roll -= art->chance;
1670 if (roll<0) break;
1671 }
1672
1673 if (art == NULL || roll>=0) {
1674#if 1
1675 LOG(llevError, "Got null entry and non zero roll in generate_artifact, type %d\n",
1676 op->type);
1677#endif 1717#endif
1678 return; 1718 return;
1679 } 1719 }
1720
1721 for (i = 0; i < ARTIFACT_TRIES; i++)
1722 {
1723 int roll = RANDOM () % al->total_chance;
1724
1725 for (art = al->items; art != NULL; art = art->next)
1726 {
1727 roll -= art->chance;
1728 if (roll < 0)
1729 break;
1730 }
1731
1732 if (art == NULL || roll >= 0)
1733 {
1734#if 1
1735 LOG (llevError, "Got null entry and non zero roll in generate_artifact, type %d\n", op->type);
1736#endif
1737 return;
1738 }
1680 if (!strcmp(art->item->name,"NONE")) 1739 if (!strcmp (art->item->name, "NONE"))
1681 return; 1740 return;
1682 if (FABS(op->magic) < art->item->magic) 1741 if (FABS (op->magic) < art->item->magic)
1683 continue; /* Not magic enough to be this item */ 1742 continue; /* Not magic enough to be this item */
1684 1743
1685 /* Map difficulty not high enough */ 1744 /* Map difficulty not high enough */
1686 if (difficulty<art->difficulty) 1745 if (difficulty < art->difficulty)
1687 continue; 1746 continue;
1688 1747
1689 if (!legal_artifact_combination(op, art)) { 1748 if (!legal_artifact_combination (op, art))
1749 {
1690#ifdef TREASURE_VERBOSE 1750#ifdef TREASURE_VERBOSE
1691 LOG(llevDebug, "%s of %s was not a legal combination.\n", 1751 LOG (llevDebug, "%s of %s was not a legal combination.\n", op->name, art->item->name);
1692 op->name, art->item->name);
1693#endif 1752#endif
1694 continue; 1753 continue;
1695 } 1754 }
1696 give_artifact_abilities(op, art->item); 1755 give_artifact_abilities (op, art->item);
1697 return; 1756 return;
1698 } 1757 }
1699} 1758}
1700 1759
1701/* fix_flesh_item() - objects of type FLESH are similar to type 1760/* fix_flesh_item() - objects of type FLESH are similar to type
1702 * FOOD, except they inherit properties (name, food value, etc). 1761 * FOOD, except they inherit properties (name, food value, etc).
1703 * based on the original owner (or 'donor' if you like). -b.t. 1762 * based on the original owner (or 'donor' if you like). -b.t.
1704 */ 1763 */
1705 1764
1765void
1706void fix_flesh_item(object *item, object *donor) { 1766fix_flesh_item (object *item, object *donor)
1767{
1707 char tmpbuf[MAX_BUF]; 1768 char tmpbuf[MAX_BUF];
1708 int i; 1769 int i;
1709 1770
1710 if(item->type==FLESH && donor) { 1771 if (item->type == FLESH && donor)
1772 {
1711 /* change the name */ 1773 /* change the name */
1712 sprintf(tmpbuf,"%s's %s",donor->name,item->name); 1774 sprintf (tmpbuf, "%s's %s", &donor->name, &item->name);
1713 FREE_AND_COPY(item->name, tmpbuf); 1775 item->name = tmpbuf;
1714 sprintf(tmpbuf,"%s's %s",donor->name,item->name_pl); 1776 sprintf (tmpbuf, "%s's %s", &donor->name, &item->name_pl);
1715 FREE_AND_COPY(item->name_pl, tmpbuf); 1777 item->name_pl = tmpbuf;
1716 1778
1717 /* weight is FLESH weight/100 * donor */ 1779 /* weight is FLESH weight/100 * donor */
1718 if((item->weight = (signed long) (((double)item->weight/(double)100.0) * (double)donor->weight))==0) 1780 if ((item->weight = (signed long) (((double) item->weight / (double) 100.0) * (double) donor->weight)) == 0)
1719 item->weight=1; 1781 item->weight = 1;
1720 1782
1721 /* value is multiplied by level of donor */ 1783 /* value is multiplied by level of donor */
1722 item->value *= isqrt(donor->level*2); 1784 item->value *= isqrt (donor->level * 2);
1723 1785
1724 /* food value */ 1786 /* food value */
1725 item->stats.food += (donor->stats.hp/100) + donor->stats.Con; 1787 item->stats.food += (donor->stats.hp / 100) + donor->stats.Con;
1726 1788
1727 /* flesh items inherit some abilities of donor, but not 1789 /* flesh items inherit some abilities of donor, but not
1728 * full effect. 1790 * full effect.
1729 */ 1791 */
1730 for (i=0; i<NROFATTACKS; i++) 1792 for (i = 0; i < NROFATTACKS; i++)
1731 item->resist[i] = donor->resist[i]/2; 1793 item->resist[i] = donor->resist[i] / 2;
1732 1794
1733 /* item inherits donor's level (important for quezals) */ 1795 /* item inherits donor's level (important for quezals) */
1734 item->level = donor->level; 1796 item->level = donor->level;
1735 1797
1736 /* if donor has some attacktypes, the flesh is poisonous */ 1798 /* if donor has some attacktypes, the flesh is poisonous */
1737 if(donor->attacktype&AT_POISON) 1799 if (donor->attacktype & AT_POISON)
1738 item->type=POISON; 1800 item->type = POISON;
1739 if(donor->attacktype&AT_ACID) item->stats.hp = -1*item->stats.food; 1801 if (donor->attacktype & AT_ACID)
1802 item->stats.hp = -1 * item->stats.food;
1740 SET_FLAG(item,FLAG_NO_STEAL); 1803 SET_FLAG (item, FLAG_NO_STEAL);
1741 } 1804 }
1742} 1805}
1743 1806
1744/* special_potion() - so that old potion code is still done right. */ 1807/* special_potion() - so that old potion code is still done right. */
1745 1808
1809int
1746int special_potion (object *op) { 1810special_potion (object *op)
1747 1811{
1748 int i;
1749
1750 if(op->attacktype) return 1; 1812 if (op->attacktype)
1751
1752 if(op->stats.Str || op->stats.Dex || op->stats.Con || op->stats.Pow
1753 || op->stats.Wis || op->stats.Int || op->stats.Cha ) return 1;
1754
1755 for (i=0; i<NROFATTACKS; i++)
1756 if (op->resist[i]) return 1;
1757
1758 return 0; 1813 return 1;
1759}
1760 1814
1815 if (op->stats.Str || op->stats.Dex || op->stats.Con || op->stats.Pow || op->stats.Wis || op->stats.Int || op->stats.Cha)
1816 return 1;
1817
1818 for (int i = 0; i < NROFATTACKS; i++)
1819 if (op->resist[i])
1820 return 1;
1821
1822 return 0;
1823}
1824
1825void
1761void free_treasurestruct(treasure *t) 1826free_treasurestruct (treasure *t)
1762{ 1827{
1828 if (t->next)
1763 if (t->next) free_treasurestruct(t->next); 1829 free_treasurestruct (t->next);
1830 if (t->next_yes)
1764 if (t->next_yes) free_treasurestruct(t->next_yes); 1831 free_treasurestruct (t->next_yes);
1832 if (t->next_no)
1765 if (t->next_no) free_treasurestruct(t->next_no); 1833 free_treasurestruct (t->next_no);
1766 free(t);
1767}
1768 1834
1835 delete t;
1836}
1837
1838void
1769void free_charlinks(linked_char *lc) 1839free_charlinks (linked_char *lc)
1770{ 1840{
1771 if (lc->next) free_charlinks(lc->next); 1841 if (lc->next)
1772 free(lc); 1842 free_charlinks (lc->next);
1773}
1774 1843
1844 delete lc;
1845}
1846
1847void
1775void free_artifact(artifact *at) 1848free_artifact (artifact * at)
1776{ 1849{
1777 1850 if (at->next)
1778 if (at->next) free_artifact(at->next); 1851 free_artifact (at->next);
1852
1853 if (at->allowed)
1779 if (at->allowed) free_charlinks(at->allowed); 1854 free_charlinks (at->allowed);
1780 if (at->item) {
1781 if (at->item->name) free_string(at->item->name);
1782 if (at->item->name_pl) free_string(at->item->name_pl);
1783 if (at->item->msg) free_string(at->item->msg);
1784 if (at->item->title) free_string(at->item->title);
1785 free(at->item);
1786 }
1787 free(at);
1788}
1789 1855
1856 at->item->destroy (1);
1857
1858 delete at;
1859}
1860
1861void
1790void free_artifactlist(artifactlist *al) 1862free_artifactlist (artifactlist * al)
1791{ 1863{
1792 artifactlist *nextal; 1864 artifactlist *nextal;
1865
1793 for (al=first_artifactlist; al!=NULL; al=nextal) { 1866 for (al = first_artifactlist; al; al = nextal)
1867 {
1794 nextal=al->next; 1868 nextal = al->next;
1869
1795 if (al->items) { 1870 if (al->items)
1796 free_artifact(al->items); 1871 free_artifact (al->items);
1797 }
1798 free(al);
1799 }
1800}
1801 1872
1873 free (al);
1874 }
1875}
1876
1877void
1802void free_all_treasures(void) { 1878free_all_treasures (void)
1879{
1803treasurelist *tl, *next; 1880 treasurelist *tl, *next;
1804 1881
1805 1882
1806 for (tl=first_treasurelist; tl!=NULL; tl=next) { 1883 for (tl = first_treasurelist; tl != NULL; tl = next)
1807 next=tl->next;
1808 if (tl->name) free_string(tl->name);
1809 if (tl->items) free_treasurestruct(tl->items);
1810 free(tl);
1811 } 1884 {
1885 next = tl->next;
1886 if (tl->items)
1887 free_treasurestruct (tl->items);
1888 delete tl;
1889 }
1812 free_artifactlist(first_artifactlist); 1890 free_artifactlist (first_artifactlist);
1813} 1891}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines