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.6 by root, Thu Aug 31 18:59:23 2006 UTC vs.
Revision 1.23 by root, Tue Dec 12 20:53:02 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines