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.4 by root, Tue Aug 29 08:01:36 2006 UTC vs.
Revision 1.27 by root, Wed Dec 20 09:14:21 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines