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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines