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.30 by elmex, Wed Jan 3 02:30:51 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines