1 | |
1 | |
2 | /* |
2 | /* |
3 | * static char *rcs_treasure_c = |
3 | * static char *rcs_treasure_c = |
4 | * "$Id: treasure.C,v 1.3 2006/08/28 14:05:24 root Exp $"; |
4 | * "$Id: treasure.C,v 1.4 2006/08/29 08:01:36 root Exp $"; |
5 | */ |
5 | */ |
6 | |
6 | |
7 | /* |
7 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
8 | CrossFire, A Multiplayer game for X-windows |
9 | |
9 | |
… | |
… | |
107 | treasure *t=get_empty_treasure(); |
107 | treasure *t=get_empty_treasure(); |
108 | int value; |
108 | int value; |
109 | |
109 | |
110 | nroftreasures++; |
110 | nroftreasures++; |
111 | while(fgets(buf,MAX_BUF,fp)!=NULL) { |
111 | while(fgets(buf,MAX_BUF,fp)!=NULL) { |
112 | (*line)++; |
112 | (*line)++; |
113 | |
113 | |
114 | if(*buf=='#') |
114 | if(*buf=='#') |
115 | continue; |
115 | continue; |
116 | if((cp=strchr(buf,'\n'))!=NULL) |
116 | if((cp=strchr(buf,'\n'))!=NULL) |
117 | *cp='\0'; |
117 | *cp='\0'; |
118 | cp=buf; |
118 | cp=buf; |
119 | while(isspace(*cp)) /* Skip blanks */ |
119 | while(isspace(*cp)) /* Skip blanks */ |
120 | cp++; |
120 | cp++; |
121 | |
121 | |
122 | if(sscanf(cp,"arch %s",variable)) { |
122 | if(sscanf(cp,"arch %s",variable)) { |
123 | if((t->item=find_archetype(variable))==NULL) |
123 | if((t->item=find_archetype(variable))==NULL) |
124 | LOG(llevError,"Treasure lacks archetype: %s\n",variable); |
124 | LOG(llevError,"Treasure lacks archetype: %s\n",variable); |
125 | } else if (sscanf(cp, "list %s", variable)) |
125 | } else if (sscanf(cp, "list %s", variable)) |
126 | t->name = add_string(variable); |
126 | t->name = add_string(variable); |
127 | else if (sscanf(cp, "change_name %s", variable)) |
127 | else if (sscanf(cp, "change_name %s", variable)) |
128 | t->change_arch.name = add_string(variable); |
128 | t->change_arch.name = add_string(variable); |
129 | else if (sscanf(cp, "change_title %s", variable)) |
129 | else if (sscanf(cp, "change_title %s", variable)) |
130 | t->change_arch.title = add_string(variable); |
130 | t->change_arch.title = add_string(variable); |
131 | else if (sscanf(cp, "change_slaying %s", variable)) |
131 | else if (sscanf(cp, "change_slaying %s", variable)) |
132 | t->change_arch.slaying = add_string(variable); |
132 | t->change_arch.slaying = add_string(variable); |
133 | else if(sscanf(cp,"chance %d",&value)) |
133 | else if(sscanf(cp,"chance %d",&value)) |
134 | t->chance=(uint8) value; |
134 | t->chance=(uint8) value; |
135 | else if(sscanf(cp,"nrof %d",&value)) |
135 | else if(sscanf(cp,"nrof %d",&value)) |
136 | t->nrof=(uint16) value; |
136 | t->nrof=(uint16) value; |
137 | else if(sscanf(cp,"magic %d",&value)) |
137 | else if(sscanf(cp,"magic %d",&value)) |
138 | t->magic=(uint8) value; |
138 | t->magic=(uint8) value; |
139 | else if(!strcmp(cp,"yes")) |
139 | else if(!strcmp(cp,"yes")) |
140 | t->next_yes=load_treasure(fp, line); |
140 | t->next_yes=load_treasure(fp, line); |
141 | else if(!strcmp(cp,"no")) |
141 | else if(!strcmp(cp,"no")) |
142 | t->next_no=load_treasure(fp, line); |
142 | t->next_no=load_treasure(fp, line); |
143 | else if(!strcmp(cp,"end")) |
143 | else if(!strcmp(cp,"end")) |
144 | return t; |
144 | return t; |
145 | else if(!strcmp(cp,"more")) { |
145 | else if(!strcmp(cp,"more")) { |
146 | t->next=load_treasure(fp, line); |
146 | t->next=load_treasure(fp, line); |
147 | return t; |
147 | return t; |
148 | } else |
148 | } else |
149 | LOG(llevError,"Unknown treasure-command: '%s', last entry %s, line %d\n", |
149 | LOG(llevError,"Unknown treasure-command: '%s', last entry %s, line %d\n", |
150 | cp,t->name?t->name:"null", *line); |
150 | cp,t->name?t->name:"null", *line); |
151 | } |
151 | } |
152 | LOG(llevError,"treasure lacks 'end'.\n"); |
152 | LOG(llevError,"treasure lacks 'end'.\n"); |
153 | return t; |
153 | return t; |
154 | } |
154 | } |
155 | |
155 | |
… | |
… | |
158 | * so that the treasure name can be printed out |
158 | * so that the treasure name can be printed out |
159 | */ |
159 | */ |
160 | static void check_treasurelist(const treasure *t, const treasurelist *tl) |
160 | static void check_treasurelist(const treasure *t, const treasurelist *tl) |
161 | { |
161 | { |
162 | if (t->item==NULL && t->name==NULL) |
162 | if (t->item==NULL && t->name==NULL) |
163 | LOG(llevError,"Treasurelist %s has element with no name or archetype\n", tl->name); |
163 | LOG(llevError,"Treasurelist %s has element with no name or archetype\n", tl->name); |
164 | if (t->chance>=100 && t->next_yes && (t->next || t->next_no)) |
164 | 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", |
165 | LOG(llevError,"Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", |
166 | tl->name); |
166 | tl->name); |
167 | /* find_treasurelist will print out its own error message */ |
167 | /* find_treasurelist will print out its own error message */ |
168 | if (t->name && strcmp(t->name,"NONE")) |
168 | if (t->name && strcmp(t->name,"NONE")) |
169 | (void) find_treasurelist(t->name); |
169 | (void) find_treasurelist(t->name); |
170 | if (t->next) check_treasurelist(t->next, tl); |
170 | if (t->next) check_treasurelist(t->next, tl); |
171 | if (t->next_yes) check_treasurelist(t->next_yes,tl); |
171 | if (t->next_yes) check_treasurelist(t->next_yes,tl); |
172 | if (t->next_no) check_treasurelist(t->next_no, tl); |
172 | if (t->next_no) check_treasurelist(t->next_no, tl); |
173 | } |
173 | } |
174 | #endif |
174 | #endif |
… | |
… | |
185 | treasure *t; |
185 | treasure *t; |
186 | int comp, line=0; |
186 | int comp, line=0; |
187 | |
187 | |
188 | sprintf(filename,"%s/%s",settings.datadir,settings.treasures); |
188 | sprintf(filename,"%s/%s",settings.datadir,settings.treasures); |
189 | if((fp=open_and_uncompress(filename,0,&comp))==NULL) { |
189 | if((fp=open_and_uncompress(filename,0,&comp))==NULL) { |
190 | LOG(llevError,"Can't open treasure file.\n"); |
190 | LOG(llevError,"Can't open treasure file.\n"); |
191 | return; |
191 | return; |
192 | } |
192 | } |
193 | while(fgets(buf,MAX_BUF,fp)!=NULL) { |
193 | while(fgets(buf,MAX_BUF,fp)!=NULL) { |
194 | line++; |
194 | line++; |
195 | if(*buf=='#') |
195 | if(*buf=='#') |
196 | continue; |
196 | continue; |
197 | |
197 | |
198 | if(sscanf(buf,"treasureone %s\n",name) || sscanf(buf,"treasure %s\n",name)) { |
198 | if(sscanf(buf,"treasureone %s\n",name) || sscanf(buf,"treasure %s\n",name)) { |
199 | treasurelist *tl=get_empty_treasurelist(); |
199 | treasurelist *tl=get_empty_treasurelist(); |
200 | tl->name=add_string(name); |
200 | tl->name=add_string(name); |
201 | if(previous==NULL) |
201 | if(previous==NULL) |
202 | first_treasurelist=tl; |
202 | first_treasurelist=tl; |
203 | else |
203 | else |
204 | previous->next=tl; |
204 | previous->next=tl; |
205 | previous=tl; |
205 | previous=tl; |
206 | tl->items=load_treasure(fp, &line); |
206 | tl->items=load_treasure(fp, &line); |
207 | |
207 | |
208 | /* This is a one of the many items on the list should be generated. |
208 | /* 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 |
209 | * Add up the chance total, and check to make sure the yes & no |
210 | * fields of the treasures are not being used. |
210 | * fields of the treasures are not being used. |
211 | */ |
211 | */ |
212 | if (!strncmp(buf,"treasureone",11)) { |
212 | if (!strncmp(buf,"treasureone",11)) { |
213 | for (t=tl->items; t!=NULL; t=t->next) { |
213 | for (t=tl->items; t!=NULL; t=t->next) { |
214 | #ifdef TREASURE_DEBUG |
214 | #ifdef TREASURE_DEBUG |
215 | if (t->next_yes || t->next_no) { |
215 | if (t->next_yes || t->next_no) { |
216 | LOG(llevError,"Treasure %s is one item, but on treasure %s\n", |
216 | LOG(llevError,"Treasure %s is one item, but on treasure %s\n", |
217 | 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"); |
218 | LOG(llevError," the next_yes or next_no field is set\n"); |
219 | } |
219 | } |
220 | #endif |
220 | #endif |
221 | tl->total_chance += t->chance; |
221 | tl->total_chance += t->chance; |
222 | } |
222 | } |
223 | } |
223 | } |
224 | } else |
224 | } else |
225 | LOG(llevError,"Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line); |
225 | LOG(llevError,"Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line); |
226 | } |
226 | } |
227 | close_and_delete(fp, comp); |
227 | close_and_delete(fp, comp); |
228 | |
228 | |
229 | #ifdef TREASURE_DEBUG |
229 | #ifdef TREASURE_DEBUG |
230 | /* Perform some checks on how valid the treasure data actually is. |
230 | /* Perform some checks on how valid the treasure data actually is. |
231 | * verify that list transitions work (ie, the list that it is supposed |
231 | * verify that list transitions work (ie, the list that it is supposed |
232 | * to transition to exists). Also, verify that at least the name |
232 | * to transition to exists). Also, verify that at least the name |
233 | * or archetype is set for each treasure element. |
233 | * or archetype is set for each treasure element. |
234 | */ |
234 | */ |
235 | for (previous=first_treasurelist; previous!=NULL; previous=previous->next) |
235 | for (previous=first_treasurelist; previous!=NULL; previous=previous->next) |
236 | check_treasurelist(previous->items, previous); |
236 | check_treasurelist(previous->items, previous); |
237 | #endif |
237 | #endif |
238 | } |
238 | } |
239 | |
239 | |
240 | /* |
240 | /* |
241 | * Searches for the given treasurelist in the globally linked list |
241 | * Searches for the given treasurelist in the globally linked list |
… | |
… | |
284 | * by another object. |
284 | * by another object. |
285 | */ |
285 | */ |
286 | if (flags & GT_ENVIRONMENT && op->type != SPELL) { |
286 | if (flags & GT_ENVIRONMENT && op->type != SPELL) { |
287 | op->x = creator->x; |
287 | op->x = creator->x; |
288 | op->y = creator->y; |
288 | op->y = creator->y; |
289 | SET_FLAG(op, FLAG_OBJ_ORIGINAL); |
289 | SET_FLAG(op, FLAG_OBJ_ORIGINAL); |
290 | insert_ob_in_map (op, creator->map,op,INS_NO_MERGE | INS_NO_WALK_ON); |
290 | insert_ob_in_map (op, creator->map,op,INS_NO_MERGE | INS_NO_WALK_ON); |
291 | } else { |
291 | } else { |
292 | op = insert_ob_in_ob (op, creator); |
292 | op = insert_ob_in_ob (op, creator); |
293 | if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER)) |
293 | if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER)) |
294 | monster_check_apply(creator, op); |
294 | monster_check_apply(creator, op); |
… | |
… | |
303 | static void change_treasure(treasure *t, object *op) |
303 | static void change_treasure(treasure *t, object *op) |
304 | { |
304 | { |
305 | /* CMD: change_name xxxx */ |
305 | /* CMD: change_name xxxx */ |
306 | if(t->change_arch.name) |
306 | if(t->change_arch.name) |
307 | { |
307 | { |
308 | FREE_AND_COPY(op->name, t->change_arch.name); |
308 | FREE_AND_COPY(op->name, t->change_arch.name); |
309 | /* not great, but better than something that is completely wrong */ |
309 | /* not great, but better than something that is completely wrong */ |
310 | FREE_AND_COPY(op->name_pl, t->change_arch.name); |
310 | FREE_AND_COPY(op->name_pl, t->change_arch.name); |
311 | } |
311 | } |
312 | |
312 | |
313 | if(t->change_arch.title) |
313 | if(t->change_arch.title) |
314 | { |
314 | { |
315 | if(op->title) |
315 | if(op->title) |
… | |
… | |
330 | object *tmp; |
330 | object *tmp; |
331 | |
331 | |
332 | |
332 | |
333 | if((int)t->chance >= 100 || (RANDOM()%100 + 1) < (int) t->chance) { |
333 | if((int)t->chance >= 100 || (RANDOM()%100 + 1) < (int) t->chance) { |
334 | if (t->name) { |
334 | if (t->name) { |
335 | if (strcmp(t->name,"NONE") && difficulty>=t->magic) |
335 | if (strcmp(t->name,"NONE") && difficulty>=t->magic) |
336 | create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries); |
336 | create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries); |
337 | } |
337 | } |
338 | else { |
338 | else { |
339 | if(t->item->clone.invisible != 0 || ! (flag & GT_INVISIBLE)) { |
339 | if(t->item->clone.invisible != 0 || ! (flag & GT_INVISIBLE)) { |
340 | tmp=arch_to_object(t->item); |
340 | tmp=arch_to_object(t->item); |
341 | if(t->nrof&&tmp->nrof<=1) |
341 | if(t->nrof&&tmp->nrof<=1) |
… | |
… | |
353 | if(t->next!=NULL) |
353 | if(t->next!=NULL) |
354 | create_all_treasures(t->next,op,flag,difficulty, tries); |
354 | create_all_treasures(t->next,op,flag,difficulty, tries); |
355 | } |
355 | } |
356 | |
356 | |
357 | void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, |
357 | void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, |
358 | int tries) |
358 | int tries) |
359 | { |
359 | { |
360 | int value = RANDOM() % tl->total_chance; |
360 | int value = RANDOM() % tl->total_chance; |
361 | treasure *t; |
361 | treasure *t; |
362 | |
362 | |
363 | if (tries++>100) { |
363 | if (tries++>100) { |
364 | LOG(llevDebug,"create_one_treasure: tries exceeded 100, returning without making treasure\n"); |
364 | LOG(llevDebug,"create_one_treasure: tries exceeded 100, returning without making treasure\n"); |
365 | return; |
365 | return; |
366 | } |
366 | } |
367 | for (t=tl->items; t!=NULL; t=t->next) { |
367 | for (t=tl->items; t!=NULL; t=t->next) { |
368 | value -= t->chance; |
368 | value -= t->chance; |
369 | if (value<0) break; |
369 | if (value<0) break; |
370 | } |
370 | } |
371 | |
371 | |
372 | if (!t || value>=0) { |
372 | if (!t || value>=0) { |
373 | LOG(llevError, "create_one_treasure: got null object or not able to find treasure\n"); |
373 | LOG(llevError, "create_one_treasure: got null object or not able to find treasure\n"); |
374 | abort(); |
374 | abort(); |
375 | return; |
375 | return; |
376 | } |
376 | } |
377 | if (t->name) { |
377 | if (t->name) { |
378 | if (!strcmp(t->name,"NONE")) return; |
378 | if (!strcmp(t->name,"NONE")) return; |
379 | if (difficulty>=t->magic) |
379 | if (difficulty>=t->magic) |
380 | create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries); |
380 | create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries); |
381 | else if (t->nrof) |
381 | else if (t->nrof) |
382 | create_one_treasure(tl, op, flag, difficulty, tries); |
382 | create_one_treasure(tl, op, flag, difficulty, tries); |
383 | return; |
383 | return; |
384 | } |
384 | } |
385 | if((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) { |
385 | if((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) { |
386 | object *tmp=arch_to_object(t->item); |
386 | object *tmp=arch_to_object(t->item); |
387 | if (!tmp) return; |
387 | if (!tmp) return; |
388 | if(t->nrof && tmp->nrof<=1) |
388 | if(t->nrof && tmp->nrof<=1) |
389 | tmp->nrof = RANDOM()%((int) t->nrof) + 1; |
389 | tmp->nrof = RANDOM()%((int) t->nrof) + 1; |
390 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
390 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
391 | change_treasure(t, tmp); |
391 | change_treasure(t, tmp); |
392 | put_treasure (tmp, op, flag); |
392 | put_treasure (tmp, op, flag); |
… | |
… | |
399 | * list transitions, or so that excessively good treasure will not be |
399 | * 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 |
400 | * created on weak maps, because it will exceed the number of allowed tries |
401 | * to do that. |
401 | * to do that. |
402 | */ |
402 | */ |
403 | void create_treasure(treasurelist *t, object *op, int flag, int difficulty, |
403 | void create_treasure(treasurelist *t, object *op, int flag, int difficulty, |
404 | int tries) |
404 | int tries) |
405 | { |
405 | { |
406 | |
406 | |
407 | if (tries++>100) { |
407 | if (tries++>100) { |
408 | LOG(llevDebug,"createtreasure: tries exceeded 100, returning without making treasure\n"); |
408 | LOG(llevDebug,"createtreasure: tries exceeded 100, returning without making treasure\n"); |
409 | return; |
409 | return; |
410 | } |
410 | } |
411 | if (t->total_chance) |
411 | if (t->total_chance) |
412 | create_one_treasure(t, op, flag,difficulty, tries); |
412 | create_one_treasure(t, op, flag,difficulty, tries); |
413 | else |
413 | else |
414 | create_all_treasures(t->items, op, flag, difficulty, tries); |
414 | create_all_treasures(t->items, op, flag, difficulty, tries); |
415 | } |
415 | } |
416 | |
416 | |
417 | /* This is similar to the old generate treasure function. However, |
417 | /* This is similar to the old generate treasure function. However, |
… | |
… | |
419 | * create_treasure. We create a dummy object that the treasure gets |
419 | * create_treasure. We create a dummy object that the treasure gets |
420 | * inserted into, and then return that treausre |
420 | * inserted into, and then return that treausre |
421 | */ |
421 | */ |
422 | object *generate_treasure(treasurelist *t, int difficulty) |
422 | object *generate_treasure(treasurelist *t, int difficulty) |
423 | { |
423 | { |
424 | object *ob = get_object(), *tmp; |
424 | object *ob = get_object(), *tmp; |
425 | |
425 | |
426 | create_treasure(t, ob, 0, difficulty, 0); |
426 | create_treasure(t, ob, 0, difficulty, 0); |
427 | |
427 | |
428 | /* Don't want to free the object we are about to return */ |
428 | /* Don't want to free the object we are about to return */ |
429 | tmp = ob->inv; |
429 | tmp = ob->inv; |
430 | if (tmp!=NULL) remove_ob(tmp); |
430 | if (tmp!=NULL) remove_ob(tmp); |
431 | if (ob->inv) { |
431 | if (ob->inv) { |
432 | LOG(llevError,"In generate treasure, created multiple objects.\n"); |
432 | LOG(llevError,"In generate treasure, created multiple objects.\n"); |
433 | } |
433 | } |
434 | free_object(ob); |
434 | free_object(ob); |
435 | return tmp; |
435 | return tmp; |
436 | } |
436 | } |
437 | |
437 | |
438 | /* |
438 | /* |
439 | * This is a new way of calculating the chance for an item to have |
439 | * This is a new way of calculating the chance for an item to have |
440 | * a specific magical bonus. |
440 | * a specific magical bonus. |
… | |
… | |
612 | void set_ring_bonus(object *op,int bonus) { |
612 | void set_ring_bonus(object *op,int bonus) { |
613 | |
613 | |
614 | int r=RANDOM()%(bonus>0?25:11); |
614 | int r=RANDOM()%(bonus>0?25:11); |
615 | |
615 | |
616 | if(op->type==AMULET) { |
616 | if(op->type==AMULET) { |
617 | if(!(RANDOM()%21)) |
617 | if(!(RANDOM()%21)) |
618 | r=20+RANDOM()%2; |
618 | r=20+RANDOM()%2; |
619 | else { |
619 | else { |
620 | if(RANDOM()&2) |
620 | if(RANDOM()&2) |
621 | r=10; |
621 | r=10; |
622 | else |
622 | else |
623 | r=11+RANDOM()%9; |
623 | r=11+RANDOM()%9; |
624 | } |
624 | } |
625 | } |
625 | } |
626 | |
626 | |
627 | switch(r) { |
627 | switch(r) { |
628 | /* Redone by MSW 2000-11-26 to have much less code. Also, |
628 | /* Redone by MSW 2000-11-26 to have much less code. Also, |
629 | * bonuses and penalties will stack and add to existing values. |
629 | * bonuses and penalties will stack and add to existing values. |
630 | * of the item. |
630 | * of the item. |
631 | */ |
631 | */ |
632 | case 0: |
632 | case 0: |
633 | case 1: |
633 | case 1: |
634 | case 2: |
634 | case 2: |
635 | case 3: |
635 | case 3: |
636 | case 4: |
636 | case 4: |
637 | case 5: |
637 | case 5: |
638 | case 6: |
638 | case 6: |
639 | set_attr_value(&op->stats, r, (signed char)(bonus + get_attr_value(&op->stats,r))); |
639 | set_attr_value(&op->stats, r, (signed char)(bonus + get_attr_value(&op->stats,r))); |
640 | break; |
640 | break; |
641 | |
641 | |
642 | case 7: |
642 | case 7: |
643 | op->stats.dam+=bonus; |
643 | op->stats.dam+=bonus; |
644 | break; |
644 | break; |
645 | |
645 | |
646 | case 8: |
646 | case 8: |
647 | op->stats.wc+=bonus; |
647 | op->stats.wc+=bonus; |
648 | break; |
648 | break; |
649 | |
649 | |
650 | case 9: |
650 | case 9: |
651 | op->stats.food+=bonus; /* hunger/sustenance */ |
651 | op->stats.food+=bonus; /* hunger/sustenance */ |
652 | break; |
652 | break; |
653 | |
653 | |
654 | case 10: |
654 | case 10: |
655 | op->stats.ac+=bonus; |
655 | op->stats.ac+=bonus; |
656 | break; |
656 | break; |
657 | |
657 | |
658 | /* Item that gives protections/vulnerabilities */ |
658 | /* Item that gives protections/vulnerabilities */ |
659 | case 11: |
659 | case 11: |
660 | case 12: |
660 | case 12: |
661 | case 13: |
661 | case 13: |
662 | case 14: |
662 | case 14: |
663 | case 15: |
663 | case 15: |
664 | case 16: |
664 | case 16: |
665 | case 17: |
665 | case 17: |
666 | case 18: |
666 | case 18: |
667 | case 19: |
667 | case 19: |
668 | { |
668 | { |
669 | int b=5+FABS(bonus),val,resist=RANDOM() % num_resist_table; |
669 | int b=5+FABS(bonus),val,resist=RANDOM() % num_resist_table; |
670 | |
670 | |
671 | /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */ |
671 | /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */ |
672 | val = 10 + RANDOM() % b + RANDOM() % b + RANDOM() % b + RANDOM() % b; |
672 | val = 10 + RANDOM() % b + RANDOM() % b + RANDOM() % b + RANDOM() % b; |
673 | |
673 | |
674 | /* Cursed items need to have higher negative values to equal out with |
674 | /* Cursed items need to have higher negative values to equal out with |
675 | * positive values for how protections work out. Put another |
675 | * positive values for how protections work out. Put another |
676 | * little random element in since that they don't always end up with |
676 | * little random element in since that they don't always end up with |
677 | * even values. |
677 | * even values. |
678 | */ |
678 | */ |
679 | if (bonus<0) val = 2*-val - RANDOM() % b; |
679 | if (bonus<0) val = 2*-val - RANDOM() % b; |
680 | if (val>35) val=35; /* Upper limit */ |
680 | if (val>35) val=35; /* Upper limit */ |
681 | b=0; |
681 | b=0; |
682 | while (op->resist[resist_table[resist]]!=0 && b<4) { |
682 | while (op->resist[resist_table[resist]]!=0 && b<4) { |
683 | resist=RANDOM() % num_resist_table; |
683 | resist=RANDOM() % num_resist_table; |
684 | } |
684 | } |
685 | if (b==4) return; /* Not able to find a free resistance */ |
685 | if (b==4) return; /* Not able to find a free resistance */ |
686 | op->resist[resist_table[resist]] = val; |
686 | op->resist[resist_table[resist]] = val; |
687 | /* We should probably do something more clever here to adjust value |
687 | /* We should probably do something more clever here to adjust value |
688 | * based on how good a resistance we gave. |
688 | * based on how good a resistance we gave. |
689 | */ |
689 | */ |
690 | break; |
690 | break; |
691 | } |
691 | } |
692 | case 20: |
692 | case 20: |
693 | if(op->type==AMULET) { |
693 | if(op->type==AMULET) { |
694 | SET_FLAG(op,FLAG_REFL_SPELL); |
694 | SET_FLAG(op,FLAG_REFL_SPELL); |
695 | op->value*=11; |
695 | op->value*=11; |
696 | } else { |
696 | } else { |
697 | op->stats.hp=1; /* regenerate hit points */ |
697 | op->stats.hp=1; /* regenerate hit points */ |
698 | op->value*=4; |
698 | op->value*=4; |
699 | } |
699 | } |
700 | break; |
700 | break; |
701 | |
701 | |
702 | case 21: |
702 | case 21: |
703 | if(op->type==AMULET) { |
703 | if(op->type==AMULET) { |
704 | SET_FLAG(op,FLAG_REFL_MISSILE); |
704 | SET_FLAG(op,FLAG_REFL_MISSILE); |
705 | op->value*=9; |
705 | op->value*=9; |
706 | } else { |
706 | } else { |
707 | op->stats.sp=1; /* regenerate spell points */ |
707 | op->stats.sp=1; /* regenerate spell points */ |
708 | op->value*=3; |
708 | op->value*=3; |
709 | } |
709 | } |
710 | break; |
710 | break; |
711 | |
711 | |
712 | case 22: |
712 | case 22: |
713 | op->stats.exp+=bonus; /* Speed! */ |
713 | op->stats.exp+=bonus; /* Speed! */ |
714 | op->value=(op->value*2)/3; |
714 | op->value=(op->value*2)/3; |
715 | break; |
715 | break; |
716 | } |
716 | } |
717 | if(bonus>0) |
717 | if(bonus>0) |
718 | op->value*=2*bonus; |
718 | op->value*=2*bonus; |
719 | else |
719 | else |
720 | op->value= -(op->value*2*bonus)/3; |
720 | op->value= -(op->value*2*bonus)/3; |
721 | } |
721 | } |
722 | |
722 | |
723 | /* |
723 | /* |
724 | * get_magic(diff) will return a random number between 0 and 4. |
724 | * 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 |
725 | * diff can be any value above 2. The higher the diff-variable, the |
… | |
… | |
1155 | |
1155 | |
1156 | artifactlist *find_artifactlist(int type) { |
1156 | artifactlist *find_artifactlist(int type) { |
1157 | artifactlist *al; |
1157 | artifactlist *al; |
1158 | |
1158 | |
1159 | for (al=first_artifactlist; al!=NULL; al=al->next) |
1159 | for (al=first_artifactlist; al!=NULL; al=al->next) |
1160 | if (al->type == type) return al; |
1160 | if (al->type == type) return al; |
1161 | return NULL; |
1161 | return NULL; |
1162 | } |
1162 | } |
1163 | |
1163 | |
1164 | /* |
1164 | /* |
1165 | * For debugging purposes. Dumps all tables. |
1165 | * For debugging purposes. Dumps all tables. |
… | |
… | |
1173 | fprintf(logfile,"\n"); |
1173 | fprintf(logfile,"\n"); |
1174 | for (al=first_artifactlist; al!=NULL; al=al->next) { |
1174 | for (al=first_artifactlist; al!=NULL; al=al->next) { |
1175 | fprintf(logfile, "Artifact has type %d, total_chance=%d\n", al->type, al->total_chance); |
1175 | 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) { |
1176 | for (art=al->items; art!=NULL; art=art->next) { |
1177 | fprintf(logfile,"Artifact %-30s Difficulty %3d Chance %5d\n", |
1177 | fprintf(logfile,"Artifact %-30s Difficulty %3d Chance %5d\n", |
1178 | art->item->name, art->difficulty, art->chance); |
1178 | art->item->name, art->difficulty, art->chance); |
1179 | if (art->allowed !=NULL) { |
1179 | if (art->allowed !=NULL) { |
1180 | fprintf(logfile,"\tAllowed combinations:"); |
1180 | fprintf(logfile,"\tAllowed combinations:"); |
1181 | for (next=art->allowed; next!=NULL; next=next->next) |
1181 | for (next=art->allowed; next!=NULL; next=next->next) |
1182 | fprintf(logfile, "%s,", next->name); |
1182 | fprintf(logfile, "%s,", next->name); |
1183 | fprintf(logfile,"\n"); |
1183 | fprintf(logfile,"\n"); |
1184 | } |
1184 | } |
1185 | } |
1185 | } |
1186 | } |
1186 | } |
1187 | fprintf(logfile,"\n"); |
1187 | fprintf(logfile,"\n"); |
1188 | } |
1188 | } |
… | |
… | |
1198 | if (depth > 100) |
1198 | if (depth > 100) |
1199 | return; |
1199 | return; |
1200 | while (t != NULL) |
1200 | while (t != NULL) |
1201 | { |
1201 | { |
1202 | if (t->name != NULL) |
1202 | if (t->name != NULL) |
1203 | { |
1203 | { |
1204 | for (i = 0; i < depth; i++) |
1204 | for (i = 0; i < depth; i++) |
1205 | fprintf (logfile, " "); |
1205 | fprintf (logfile, " "); |
1206 | fprintf (logfile, "{ (list: %s)\n", t->name); |
1206 | fprintf (logfile, "{ (list: %s)\n", t->name); |
1207 | tl = find_treasurelist (t->name); |
1207 | tl = find_treasurelist (t->name); |
1208 | dump_monster_treasure_rec (name, tl->items, depth + 2); |
1208 | dump_monster_treasure_rec (name, tl->items, depth + 2); |
1209 | for (i = 0; i < depth; i++) |
1209 | for (i = 0; i < depth; i++) |
1210 | fprintf (logfile, " "); |
1210 | fprintf (logfile, " "); |
1211 | fprintf (logfile, "} (end of list: %s)\n", t->name); |
1211 | fprintf (logfile, "} (end of list: %s)\n", t->name); |
1212 | } |
1212 | } |
1213 | else |
1213 | else |
1214 | { |
1214 | { |
1215 | for (i = 0; i < depth; i++) |
1215 | for (i = 0; i < depth; i++) |
1216 | fprintf (logfile, " "); |
1216 | fprintf (logfile, " "); |
1217 | if (t->item->clone.type == FLESH) |
1217 | if (t->item->clone.type == FLESH) |
1218 | fprintf (logfile, "%s's %s\n", name, t->item->clone.name); |
1218 | fprintf (logfile, "%s's %s\n", name, t->item->clone.name); |
1219 | else |
1219 | else |
1220 | fprintf (logfile, "%s\n", t->item->clone.name); |
1220 | fprintf (logfile, "%s\n", t->item->clone.name); |
1221 | } |
1221 | } |
1222 | if (t->next_yes != NULL) |
1222 | if (t->next_yes != NULL) |
1223 | { |
1223 | { |
1224 | for (i = 0; i < depth; i++) |
1224 | for (i = 0; i < depth; i++) |
1225 | fprintf (logfile, " "); |
1225 | fprintf (logfile, " "); |
1226 | fprintf (logfile, " (if yes)\n"); |
1226 | fprintf (logfile, " (if yes)\n"); |
1227 | dump_monster_treasure_rec (name, t->next_yes, depth + 1); |
1227 | dump_monster_treasure_rec (name, t->next_yes, depth + 1); |
1228 | } |
1228 | } |
1229 | if (t->next_no != NULL) |
1229 | if (t->next_no != NULL) |
1230 | { |
1230 | { |
1231 | for (i = 0; i < depth; i++) |
1231 | for (i = 0; i < depth; i++) |
1232 | fprintf (logfile, " "); |
1232 | fprintf (logfile, " "); |
1233 | fprintf (logfile, " (if no)\n"); |
1233 | fprintf (logfile, " (if no)\n"); |
1234 | dump_monster_treasure_rec (name, t->next_no, depth + 1); |
1234 | dump_monster_treasure_rec (name, t->next_no, depth + 1); |
1235 | } |
1235 | } |
1236 | t = t->next; |
1236 | t = t->next; |
1237 | } |
1237 | } |
1238 | } |
1238 | } |
1239 | |
1239 | |
1240 | /* |
1240 | /* |
… | |
… | |
1250 | found = 0; |
1250 | found = 0; |
1251 | fprintf (logfile, "\n"); |
1251 | fprintf (logfile, "\n"); |
1252 | for (at = first_archetype; at != NULL; at = at->next) |
1252 | for (at = first_archetype; at != NULL; at = at->next) |
1253 | if (! strcasecmp (at->clone.name, name) && at->clone.title == NULL) |
1253 | if (! strcasecmp (at->clone.name, name) && at->clone.title == NULL) |
1254 | { |
1254 | { |
1255 | fprintf (logfile, "treasures for %s (arch: %s)\n", at->clone.name, |
1255 | fprintf (logfile, "treasures for %s (arch: %s)\n", at->clone.name, |
1256 | at->name); |
1256 | at->name); |
1257 | if (at->clone.randomitems != NULL) |
1257 | if (at->clone.randomitems != NULL) |
1258 | dump_monster_treasure_rec (at->clone.name, |
1258 | dump_monster_treasure_rec (at->clone.name, |
1259 | at->clone.randomitems->items, 1); |
1259 | at->clone.randomitems->items, 1); |
1260 | else |
1260 | else |
1261 | fprintf (logfile, "(nothing)\n"); |
1261 | fprintf (logfile, "(nothing)\n"); |
1262 | fprintf (logfile, "\n"); |
1262 | fprintf (logfile, "\n"); |
1263 | found++; |
1263 | found++; |
1264 | } |
1264 | } |
1265 | if (found == 0) |
1265 | if (found == 0) |
1266 | fprintf (logfile, "No objects have the name %s!\n\n", name); |
1266 | fprintf (logfile, "No objects have the name %s!\n\n", name); |
1267 | } |
1267 | } |
1268 | |
1268 | |
… | |
… | |
1283 | else has_been_inited = 1; |
1283 | else has_been_inited = 1; |
1284 | |
1284 | |
1285 | sprintf(filename, "%s/artifacts", settings.datadir); |
1285 | sprintf(filename, "%s/artifacts", settings.datadir); |
1286 | LOG(llevDebug, "Reading artifacts from %s...",filename); |
1286 | LOG(llevDebug, "Reading artifacts from %s...",filename); |
1287 | if ((fp_ = open_and_uncompress(filename, 0, &comp)) == NULL) { |
1287 | if ((fp_ = open_and_uncompress(filename, 0, &comp)) == NULL) { |
1288 | LOG(llevError, "Can't open %s.\n", filename); |
1288 | LOG(llevError, "Can't open %s.\n", filename); |
1289 | return; |
1289 | return; |
1290 | } |
1290 | } |
1291 | |
1291 | |
1292 | object_thawer fp (fp_); |
1292 | object_thawer fp (fp_); |
1293 | |
1293 | |
1294 | while (fgets(buf, HUGE_BUF, fp)!=NULL) { |
1294 | while (fgets(buf, HUGE_BUF, fp)!=NULL) { |
1295 | if (*buf=='#') continue; |
1295 | if (*buf=='#') continue; |
1296 | if((cp=strchr(buf,'\n'))!=NULL) |
1296 | if((cp=strchr(buf,'\n'))!=NULL) |
1297 | *cp='\0'; |
1297 | *cp='\0'; |
1298 | cp=buf; |
1298 | cp=buf; |
1299 | while(*cp==' ') /* Skip blanks */ |
1299 | while(*cp==' ') /* Skip blanks */ |
1300 | cp++; |
1300 | cp++; |
1301 | if (*cp=='\0') continue; |
1301 | if (*cp=='\0') continue; |
1302 | |
1302 | |
1303 | if (!strncmp(cp, "Allowed", 7)) { |
1303 | if (!strncmp(cp, "Allowed", 7)) { |
1304 | if (art==NULL) { |
1304 | if (art==NULL) { |
1305 | art=get_empty_artifact(); |
1305 | art=get_empty_artifact(); |
1306 | nrofartifacts++; |
1306 | nrofartifacts++; |
1307 | } |
1307 | } |
1308 | cp = strchr(cp,' ') + 1; |
1308 | cp = strchr(cp,' ') + 1; |
1309 | if (!strcmp(cp,"all")) continue; |
1309 | if (!strcmp(cp,"all")) continue; |
1310 | |
1310 | |
1311 | do { |
1311 | do { |
1312 | nrofallowedstr++; |
1312 | nrofallowedstr++; |
1313 | if ((next=strchr(cp, ','))!=NULL) |
1313 | if ((next=strchr(cp, ','))!=NULL) |
1314 | *(next++) = '\0'; |
1314 | *(next++) = '\0'; |
1315 | tmp = (linked_char*) malloc(sizeof(linked_char)); |
1315 | tmp = (linked_char*) malloc(sizeof(linked_char)); |
1316 | tmp->name = add_string(cp); |
1316 | tmp->name = add_string(cp); |
1317 | tmp->next = art->allowed; |
1317 | tmp->next = art->allowed; |
1318 | art->allowed = tmp; |
1318 | art->allowed = tmp; |
1319 | } while ((cp=next)!=NULL); |
1319 | } while ((cp=next)!=NULL); |
1320 | } |
1320 | } |
1321 | else if (sscanf(cp, "chance %d", &value)) |
1321 | else if (sscanf(cp, "chance %d", &value)) |
1322 | art->chance = (uint16) value; |
1322 | art->chance = (uint16) value; |
1323 | else if (sscanf(cp, "difficulty %d", &value)) |
1323 | else if (sscanf(cp, "difficulty %d", &value)) |
1324 | art->difficulty = (uint8) value; |
1324 | art->difficulty = (uint8) value; |
1325 | else if (!strncmp(cp, "Object",6)) { |
1325 | else if (!strncmp(cp, "Object",6)) { |
1326 | art->item = (object *) calloc(1, sizeof(object)); |
1326 | art->item = (object *) calloc(1, sizeof(object)); |
1327 | reset_object(art->item); |
1327 | reset_object(art->item); |
1328 | if (!load_object(fp, art->item,LO_LINEMODE,0)) |
1328 | if (!load_object(fp, art->item,LO_LINEMODE,0)) |
1329 | LOG(llevError,"Init_Artifacts: Could not load object.\n"); |
1329 | LOG(llevError,"Init_Artifacts: Could not load object.\n"); |
1330 | art->item->name = add_string((strchr(cp, ' ')+1)); |
1330 | art->item->name = add_string((strchr(cp, ' ')+1)); |
1331 | al=find_artifactlist(art->item->type); |
1331 | al=find_artifactlist(art->item->type); |
1332 | if (al==NULL) { |
1332 | if (al==NULL) { |
1333 | al = get_empty_artifactlist(); |
1333 | al = get_empty_artifactlist(); |
1334 | al->type = art->item->type; |
1334 | al->type = art->item->type; |
1335 | al->next = first_artifactlist; |
1335 | al->next = first_artifactlist; |
1336 | first_artifactlist = al; |
1336 | first_artifactlist = al; |
1337 | } |
1337 | } |
1338 | art->next = al->items; |
1338 | art->next = al->items; |
1339 | al->items = art; |
1339 | al->items = art; |
1340 | art = NULL; |
1340 | art = NULL; |
1341 | } |
1341 | } |
1342 | else |
1342 | else |
1343 | LOG(llevError,"Unknown input in artifact file: %s\n", buf); |
1343 | LOG(llevError,"Unknown input in artifact file: %s\n", buf); |
1344 | } |
1344 | } |
1345 | |
1345 | |
1346 | close_and_delete(fp, comp); |
1346 | close_and_delete(fp, comp); |
1347 | |
1347 | |
1348 | for (al=first_artifactlist; al!=NULL; al=al->next) { |
1348 | for (al=first_artifactlist; al!=NULL; al=al->next) { |
1349 | for (art=al->items; art!=NULL; art=art->next) { |
1349 | for (art=al->items; art!=NULL; art=art->next) { |
1350 | if (!art->chance) |
1350 | if (!art->chance) |
1351 | LOG(llevError,"Warning: artifact with no chance: %s\n", art->item->name); |
1351 | LOG(llevError,"Warning: artifact with no chance: %s\n", art->item->name); |
1352 | else |
1352 | else |
1353 | al->total_chance += art->chance; |
1353 | al->total_chance += art->chance; |
1354 | } |
1354 | } |
1355 | #if 0 |
1355 | #if 0 |
1356 | LOG(llevDebug,"Artifact list type %d has %d total chance\n", |
1356 | LOG(llevDebug,"Artifact list type %d has %d total chance\n", |
1357 | al->type, al->total_chance); |
1357 | al->type, al->total_chance); |
1358 | #endif |
1358 | #endif |
1359 | } |
1359 | } |
1360 | |
1360 | |
1361 | LOG(llevDebug,"done.\n"); |
1361 | LOG(llevDebug,"done.\n"); |
1362 | } |
1362 | } |
… | |
… | |
1370 | void add_abilities(object *op, object *change) { |
1370 | void add_abilities(object *op, object *change) { |
1371 | int i,j, tmp; |
1371 | int i,j, tmp; |
1372 | |
1372 | |
1373 | if (change->face != blank_face) { |
1373 | if (change->face != blank_face) { |
1374 | #ifdef TREASURE_VERBOSE |
1374 | #ifdef TREASURE_VERBOSE |
1375 | LOG(llevDebug, "FACE: %d\n", change->face->number); |
1375 | LOG(llevDebug, "FACE: %d\n", change->face->number); |
1376 | #endif |
1376 | #endif |
1377 | op->face = change->face; |
1377 | op->face = change->face; |
1378 | } |
1378 | } |
1379 | for (i = 0; i < NUM_STATS; i++) |
1379 | for (i = 0; i < NUM_STATS; i++) |
1380 | change_attr_value(&(op->stats), i, get_attr_value(&(change->stats), i)); |
1380 | change_attr_value(&(op->stats), i, get_attr_value(&(change->stats), i)); |
1381 | |
1381 | |
1382 | op->attacktype |= change->attacktype; |
1382 | op->attacktype |= change->attacktype; |
1383 | op->path_attuned |= change->path_attuned; |
1383 | op->path_attuned |= change->path_attuned; |
1384 | op->path_repelled |= change->path_repelled; |
1384 | op->path_repelled |= change->path_repelled; |
1385 | op->path_denied |= change->path_denied; |
1385 | op->path_denied |= change->path_denied; |
… | |
… | |
1387 | op->stats.luck += change->stats.luck; |
1387 | op->stats.luck += change->stats.luck; |
1388 | |
1388 | |
1389 | if (QUERY_FLAG(change,FLAG_CURSED)) SET_FLAG(op, FLAG_CURSED); |
1389 | if (QUERY_FLAG(change,FLAG_CURSED)) SET_FLAG(op, FLAG_CURSED); |
1390 | if (QUERY_FLAG(change,FLAG_DAMNED)) SET_FLAG(op, FLAG_DAMNED); |
1390 | if (QUERY_FLAG(change,FLAG_DAMNED)) SET_FLAG(op, FLAG_DAMNED); |
1391 | if ((QUERY_FLAG(change,FLAG_CURSED) || QUERY_FLAG(change,FLAG_DAMNED)) |
1391 | if ((QUERY_FLAG(change,FLAG_CURSED) || QUERY_FLAG(change,FLAG_DAMNED)) |
1392 | && op->magic > 0) |
1392 | && op->magic > 0) |
1393 | set_abs_magic(op, -op->magic); |
1393 | set_abs_magic(op, -op->magic); |
1394 | |
1394 | |
1395 | if (QUERY_FLAG(change,FLAG_LIFESAVE)) SET_FLAG(op,FLAG_LIFESAVE); |
1395 | if (QUERY_FLAG(change,FLAG_LIFESAVE)) SET_FLAG(op,FLAG_LIFESAVE); |
1396 | if (QUERY_FLAG(change,FLAG_REFL_SPELL)) SET_FLAG(op,FLAG_REFL_SPELL); |
1396 | if (QUERY_FLAG(change,FLAG_REFL_SPELL)) SET_FLAG(op,FLAG_REFL_SPELL); |
1397 | if (QUERY_FLAG(change,FLAG_STEALTH)) SET_FLAG(op,FLAG_STEALTH); |
1397 | if (QUERY_FLAG(change,FLAG_STEALTH)) SET_FLAG(op,FLAG_STEALTH); |
1398 | if (QUERY_FLAG(change,FLAG_XRAYS)) SET_FLAG(op,FLAG_XRAYS); |
1398 | if (QUERY_FLAG(change,FLAG_XRAYS)) SET_FLAG(op,FLAG_XRAYS); |
… | |
… | |
1400 | if (QUERY_FLAG(change,FLAG_SEE_IN_DARK)) SET_FLAG(op,FLAG_SEE_IN_DARK); |
1400 | if (QUERY_FLAG(change,FLAG_SEE_IN_DARK)) SET_FLAG(op,FLAG_SEE_IN_DARK); |
1401 | if (QUERY_FLAG(change,FLAG_REFL_MISSILE)) SET_FLAG(op,FLAG_REFL_MISSILE); |
1401 | if (QUERY_FLAG(change,FLAG_REFL_MISSILE)) SET_FLAG(op,FLAG_REFL_MISSILE); |
1402 | if (QUERY_FLAG(change,FLAG_MAKE_INVIS)) SET_FLAG(op,FLAG_MAKE_INVIS); |
1402 | if (QUERY_FLAG(change,FLAG_MAKE_INVIS)) SET_FLAG(op,FLAG_MAKE_INVIS); |
1403 | |
1403 | |
1404 | if (QUERY_FLAG(change,FLAG_STAND_STILL)) { |
1404 | if (QUERY_FLAG(change,FLAG_STAND_STILL)) { |
1405 | CLEAR_FLAG(op,FLAG_ANIMATE); |
1405 | CLEAR_FLAG(op,FLAG_ANIMATE); |
1406 | /* so artifacts will join */ |
1406 | /* so artifacts will join */ |
1407 | if(!QUERY_FLAG(op,FLAG_ALIVE)) op->speed = 0.0; |
1407 | if(!QUERY_FLAG(op,FLAG_ALIVE)) op->speed = 0.0; |
1408 | update_ob_speed(op); |
1408 | update_ob_speed(op); |
1409 | } |
1409 | } |
1410 | if(change->nrof) op->nrof=RANDOM()%((int) change->nrof) + 1; |
1410 | if(change->nrof) op->nrof=RANDOM()%((int) change->nrof) + 1; |
1411 | op->stats.exp += change->stats.exp; /* Speed modifier */ |
1411 | op->stats.exp += change->stats.exp; /* Speed modifier */ |
1412 | op->stats.wc += change->stats.wc; |
1412 | op->stats.wc += change->stats.wc; |
1413 | op->stats.ac += change->stats.ac; |
1413 | op->stats.ac += change->stats.ac; |
1414 | |
1414 | |
1415 | if (change->other_arch) { |
1415 | if (change->other_arch) { |
1416 | /* Basically, for horns & potions, the other_arch field is the spell |
1416 | /* 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 |
1417 | * to cast. So convert that to into a spell and put it into |
1418 | * this object. |
1418 | * this object. |
1419 | */ |
1419 | */ |
1420 | if (op->type == HORN || op->type == POTION) { |
1420 | if (op->type == HORN || op->type == POTION) { |
1421 | object *tmp_obj; |
1421 | object *tmp_obj; |
1422 | /* Remove any spells this object currently has in it */ |
1422 | /* Remove any spells this object currently has in it */ |
1423 | while (op->inv) { |
1423 | while (op->inv) { |
1424 | tmp_obj = op->inv; |
1424 | tmp_obj = op->inv; |
1425 | remove_ob(tmp_obj); |
1425 | remove_ob(tmp_obj); |
1426 | free_object(tmp_obj); |
1426 | free_object(tmp_obj); |
1427 | } |
1427 | } |
1428 | tmp_obj = arch_to_object(change->other_arch); |
1428 | tmp_obj = arch_to_object(change->other_arch); |
1429 | insert_ob_in_ob(tmp_obj, op); |
1429 | insert_ob_in_ob(tmp_obj, op); |
1430 | } |
1430 | } |
1431 | /* No harm setting this for potions/horns */ |
1431 | /* No harm setting this for potions/horns */ |
1432 | op->other_arch = change->other_arch; |
1432 | op->other_arch = change->other_arch; |
1433 | } |
1433 | } |
1434 | |
1434 | |
1435 | if (change->stats.hp < 0) |
1435 | if (change->stats.hp < 0) |
1436 | op->stats.hp = -change->stats.hp; |
1436 | op->stats.hp = -change->stats.hp; |
1437 | else |
1437 | else |
1438 | op->stats.hp += change->stats.hp; |
1438 | op->stats.hp += change->stats.hp; |
1439 | if (change->stats.maxhp < 0) |
1439 | if (change->stats.maxhp < 0) |
1440 | op->stats.maxhp = -change->stats.maxhp; |
1440 | op->stats.maxhp = -change->stats.maxhp; |
1441 | else |
1441 | else |
1442 | op->stats.maxhp += change->stats.maxhp; |
1442 | op->stats.maxhp += change->stats.maxhp; |
1443 | if (change->stats.sp < 0) |
1443 | if (change->stats.sp < 0) |
1444 | op->stats.sp = -change->stats.sp; |
1444 | op->stats.sp = -change->stats.sp; |
1445 | else |
1445 | else |
1446 | op->stats.sp += change->stats.sp; |
1446 | op->stats.sp += change->stats.sp; |
1447 | if (change->stats.maxsp < 0) |
1447 | if (change->stats.maxsp < 0) |
1448 | op->stats.maxsp = -change->stats.maxsp; |
1448 | op->stats.maxsp = -change->stats.maxsp; |
1449 | else |
1449 | else |
1450 | op->stats.maxsp += change->stats.maxsp; |
1450 | op->stats.maxsp += change->stats.maxsp; |
1451 | if (change->stats.food < 0) |
1451 | if (change->stats.food < 0) |
1452 | op->stats.food = -(change->stats.food); |
1452 | op->stats.food = -(change->stats.food); |
1453 | else |
1453 | else |
1454 | op->stats.food += change->stats.food; |
1454 | op->stats.food += change->stats.food; |
1455 | if (change->level < 0) |
1455 | if (change->level < 0) |
1456 | op->level = -(change->level); |
1456 | op->level = -(change->level); |
1457 | else |
1457 | else |
1458 | op->level += change->level; |
1458 | op->level += change->level; |
1459 | |
1459 | |
1460 | if (change->gen_sp_armour < 0) |
1460 | if (change->gen_sp_armour < 0) |
1461 | op->gen_sp_armour = -(change->gen_sp_armour); |
1461 | op->gen_sp_armour = -(change->gen_sp_armour); |
1462 | else |
1462 | else |
1463 | op->gen_sp_armour = (op->gen_sp_armour * (change->gen_sp_armour)) / 100; |
1463 | op->gen_sp_armour = (op->gen_sp_armour * (change->gen_sp_armour)) / 100; |
1464 | |
1464 | |
1465 | op->item_power = change->item_power; |
1465 | op->item_power = change->item_power; |
1466 | |
1466 | |
1467 | for (i=0; i<NROFATTACKS; i++) { |
1467 | for (i=0; i<NROFATTACKS; i++) { |
1468 | if (change->resist[i]) { |
1468 | if (change->resist[i]) { |
1469 | op->resist[i] += change->resist[i]; |
1469 | op->resist[i] += change->resist[i]; |
1470 | } |
1470 | } |
1471 | } |
1471 | } |
1472 | if (change->stats.dam) { |
1472 | if (change->stats.dam) { |
1473 | if (change->stats.dam < 0) |
1473 | if (change->stats.dam < 0) |
1474 | op->stats.dam = (-change->stats.dam); |
1474 | op->stats.dam = (-change->stats.dam); |
1475 | else if (op->stats.dam) { |
1475 | else if (op->stats.dam) { |
1476 | tmp = (signed char) (((int)op->stats.dam * (int)change->stats.dam)/10); |
1476 | tmp = (signed char) (((int)op->stats.dam * (int)change->stats.dam)/10); |
1477 | if (tmp == op->stats.dam) { |
1477 | if (tmp == op->stats.dam) { |
1478 | if (change->stats.dam < 10) |
1478 | if (change->stats.dam < 10) |
1479 | op->stats.dam--; |
1479 | op->stats.dam--; |
1480 | else |
1480 | else |
1481 | op->stats.dam++; |
1481 | op->stats.dam++; |
1482 | } |
1482 | } |
1483 | else |
1483 | else |
1484 | op->stats.dam = tmp; |
1484 | op->stats.dam = tmp; |
1485 | } |
1485 | } |
1486 | } |
1486 | } |
1487 | if (change->weight) { |
1487 | if (change->weight) { |
1488 | if (change->weight < 0) |
1488 | if (change->weight < 0) |
1489 | op->weight = (-change->weight); |
1489 | op->weight = (-change->weight); |
1490 | else |
1490 | else |
1491 | op->weight = (op->weight * (change->weight)) / 100; |
1491 | op->weight = (op->weight * (change->weight)) / 100; |
1492 | } |
1492 | } |
1493 | if (change->last_sp) { |
1493 | if (change->last_sp) { |
1494 | if (change->last_sp < 0) |
1494 | if (change->last_sp < 0) |
1495 | op->last_sp = (-change->last_sp); |
1495 | op->last_sp = (-change->last_sp); |
1496 | else |
1496 | else |
1497 | op->last_sp = (signed char) (((int)op->last_sp * (int)change->last_sp) / (int) 100); |
1497 | op->last_sp = (signed char) (((int)op->last_sp * (int)change->last_sp) / (int) 100); |
1498 | } |
1498 | } |
1499 | if (change->gen_sp_armour) { |
1499 | if (change->gen_sp_armour) { |
1500 | if (change->gen_sp_armour < 0) |
1500 | if (change->gen_sp_armour < 0) |
1501 | op->gen_sp_armour = (-change->gen_sp_armour); |
1501 | op->gen_sp_armour = (-change->gen_sp_armour); |
1502 | else |
1502 | else |
1503 | op->gen_sp_armour = (signed char) (((int)op->gen_sp_armour * ((int)change->gen_sp_armour)) |
1503 | op->gen_sp_armour = (signed char) (((int)op->gen_sp_armour * ((int)change->gen_sp_armour)) |
1504 | / (int)100); |
1504 | / (int)100); |
1505 | } |
1505 | } |
1506 | op->value *= change->value; |
1506 | op->value *= change->value; |
1507 | |
1507 | |
1508 | if(change->material) op->material = change->material; |
1508 | if(change->material) op->material = change->material; |
1509 | |
1509 | |
1510 | if (change->materialname) { |
1510 | if (change->materialname) { |
1511 | if (op->materialname) |
1511 | if (op->materialname) |
1512 | free_string(op->materialname); |
1512 | free_string(op->materialname); |
1513 | op->materialname = add_refcount(change->materialname); |
1513 | op->materialname = add_refcount(change->materialname); |
1514 | } |
1514 | } |
1515 | |
1515 | |
1516 | if (change->slaying) { |
1516 | if (change->slaying) { |
1517 | if (op->slaying) |
1517 | if (op->slaying) |
1518 | free_string(op->slaying); |
1518 | free_string(op->slaying); |
1519 | op->slaying = add_refcount(change->slaying); |
1519 | op->slaying = add_refcount(change->slaying); |
1520 | } |
1520 | } |
1521 | if (change->race) { |
1521 | if (change->race) { |
1522 | if (op->race) |
1522 | if (op->race) |
1523 | free_string(op->race); |
1523 | free_string(op->race); |
1524 | op->race = add_refcount(change->race); |
1524 | op->race = add_refcount(change->race); |
1525 | } |
1525 | } |
1526 | if (change->msg) { |
1526 | if (change->msg) { |
1527 | if (op->msg) |
1527 | if (op->msg) |
1528 | free_string(op->msg); |
1528 | free_string(op->msg); |
1529 | op->msg = add_refcount(change->msg); |
1529 | op->msg = add_refcount(change->msg); |
1530 | } |
1530 | } |
1531 | /* GROS: Added support for event_... in artifact file */ |
1531 | /* GROS: Added support for event_... in artifact file */ |
1532 | for(j=0;j<NR_EVENTS;j++) { |
1532 | for(j=0;j<NR_EVENTS;j++) { |
1533 | event *evt; |
1533 | event *evt; |
1534 | event *evt2; |
1534 | event *evt2; |
1535 | event *evtn; |
1535 | event *evtn; |
1536 | event *evtp; |
1536 | event *evtp; |
1537 | |
1537 | |
1538 | evt = find_event(change,j); |
1538 | evt = find_event(change,j); |
1539 | evt2= find_event(op,j); |
1539 | evt2= find_event(op,j); |
1540 | |
1540 | |
1541 | if ((evt) && (evt->hook)) { |
1541 | if ((evt) && (evt->hook)) { |
1542 | if ((evt2)&&(evt2->hook)) { |
1542 | if ((evt2)&&(evt2->hook)) { |
1543 | free_string(evt2->hook); |
1543 | free_string(evt2->hook); |
1544 | free_string(evt2->plugin); |
1544 | free_string(evt2->plugin); |
1545 | free_string(evt2->options); |
1545 | free_string(evt2->options); |
1546 | evtp = NULL; |
1546 | evtp = NULL; |
1547 | evtn = evt2->next; |
1547 | evtn = evt2->next; |
1548 | if (evt2 == op->events) { |
1548 | if (evt2 == op->events) { |
1549 | free(evt2); |
1549 | free(evt2); |
1550 | op->events = evtn; |
1550 | op->events = evtn; |
1551 | } |
1551 | } |
1552 | else { |
1552 | else { |
1553 | evtp = op->events; |
1553 | evtp = op->events; |
1554 | while (evtp->next != evt2) |
1554 | while (evtp->next != evt2) |
1555 | evtp = evtp->next; |
1555 | evtp = evtp->next; |
1556 | free(evt2); |
1556 | free(evt2); |
1557 | evtp->next = evtn; |
1557 | evtp->next = evtn; |
1558 | } |
1558 | } |
1559 | } |
1559 | } |
1560 | else if (evt2 == NULL) { |
1560 | else if (evt2 == NULL) { |
1561 | if (op->events == NULL) { |
1561 | if (op->events == NULL) { |
1562 | evt2 = (event *)malloc(sizeof(event)); |
1562 | evt2 = (event *)malloc(sizeof(event)); |
1563 | op->events = evt2; |
1563 | op->events = evt2; |
1564 | } |
1564 | } |
1565 | else { |
1565 | else { |
1566 | evtp = op->events; |
1566 | evtp = op->events; |
1567 | while (evtp->next != NULL) |
1567 | while (evtp->next != NULL) |
1568 | evtp = evtp->next; |
1568 | evtp = evtp->next; |
1569 | evtp->next = (event *)malloc(sizeof(event)); |
1569 | evtp->next = (event *)malloc(sizeof(event)); |
1570 | evt2 = evtp->next; |
1570 | evt2 = evtp->next; |
1571 | } |
1571 | } |
1572 | } |
1572 | } |
1573 | evt2->next = NULL; |
1573 | evt2->next = NULL; |
1574 | evt2->hook = add_refcount(evt->hook); |
1574 | evt2->hook = add_refcount(evt->hook); |
1575 | evt2->plugin = add_refcount(evt->plugin); |
1575 | evt2->plugin = add_refcount(evt->plugin); |
1576 | evt2->type = j; |
1576 | evt2->type = j; |
1577 | |
1577 | |
1578 | if (evt->options) |
1578 | if (evt->options) |
1579 | evt2->options = add_refcount(evt->options); |
1579 | evt2->options = add_refcount(evt->options); |
1580 | else |
1580 | else |
1581 | evt2->options = NULL; |
1581 | evt2->options = NULL; |
1582 | } |
1582 | } |
1583 | } |
1583 | } |
1584 | } |
1584 | } |
1585 | |
1585 | |
1586 | static int legal_artifact_combination(object *op, artifact *art) { |
1586 | static int legal_artifact_combination(object *op, artifact *art) { |
1587 | int neg, success = 0; |
1587 | int neg, success = 0; |
… | |
… | |
1631 | char identified = QUERY_FLAG(op, FLAG_IDENTIFIED); |
1631 | char identified = QUERY_FLAG(op, FLAG_IDENTIFIED); |
1632 | SET_FLAG(op, FLAG_IDENTIFIED); |
1632 | SET_FLAG(op, FLAG_IDENTIFIED); |
1633 | LOG(llevDebug, "Generated artifact %s %s [%s]\n", |
1633 | LOG(llevDebug, "Generated artifact %s %s [%s]\n", |
1634 | op->name, op->title, describe_item(op, NULL)); |
1634 | op->name, op->title, describe_item(op, NULL)); |
1635 | if (!identified) |
1635 | if (!identified) |
1636 | CLEAR_FLAG(op, FLAG_IDENTIFIED); |
1636 | CLEAR_FLAG(op, FLAG_IDENTIFIED); |
1637 | } |
1637 | } |
1638 | #endif |
1638 | #endif |
1639 | return; |
1639 | return; |
1640 | } |
1640 | } |
1641 | |
1641 | |
… | |
… | |
1669 | |
1669 | |
1670 | for (art=al->items; art!=NULL; art=art->next) { |
1670 | for (art=al->items; art!=NULL; art=art->next) { |
1671 | roll -= art->chance; |
1671 | roll -= art->chance; |
1672 | if (roll<0) break; |
1672 | if (roll<0) break; |
1673 | } |
1673 | } |
1674 | |
1674 | |
1675 | if (art == NULL || roll>=0) { |
1675 | if (art == NULL || roll>=0) { |
1676 | #if 1 |
1676 | #if 1 |
1677 | LOG(llevError, "Got null entry and non zero roll in generate_artifact, type %d\n", |
1677 | LOG(llevError, "Got null entry and non zero roll in generate_artifact, type %d\n", |
1678 | op->type); |
1678 | op->type); |
1679 | #endif |
1679 | #endif |
1680 | return; |
1680 | return; |
1681 | } |
1681 | } |
1682 | if (!strcmp(art->item->name,"NONE")) |
1682 | if (!strcmp(art->item->name,"NONE")) |
1683 | return; |
1683 | return; |
1684 | if (FABS(op->magic) < art->item->magic) |
1684 | if (FABS(op->magic) < art->item->magic) |
1685 | continue; /* Not magic enough to be this item */ |
1685 | continue; /* Not magic enough to be this item */ |
1686 | |
1686 | |
1687 | /* Map difficulty not high enough */ |
1687 | /* Map difficulty not high enough */ |
1688 | if (difficulty<art->difficulty) |
1688 | if (difficulty<art->difficulty) |
1689 | continue; |
1689 | continue; |
1690 | |
1690 | |
1691 | if (!legal_artifact_combination(op, art)) { |
1691 | if (!legal_artifact_combination(op, art)) { |
1692 | #ifdef TREASURE_VERBOSE |
1692 | #ifdef TREASURE_VERBOSE |
1693 | LOG(llevDebug, "%s of %s was not a legal combination.\n", |
1693 | LOG(llevDebug, "%s of %s was not a legal combination.\n", |
1694 | op->name, art->item->name); |
1694 | op->name, art->item->name); |
… | |
… | |
1708 | void fix_flesh_item(object *item, object *donor) { |
1708 | void fix_flesh_item(object *item, object *donor) { |
1709 | char tmpbuf[MAX_BUF]; |
1709 | char tmpbuf[MAX_BUF]; |
1710 | int i; |
1710 | int i; |
1711 | |
1711 | |
1712 | if(item->type==FLESH && donor) { |
1712 | if(item->type==FLESH && donor) { |
1713 | /* change the name */ |
1713 | /* change the name */ |
1714 | sprintf(tmpbuf,"%s's %s",donor->name,item->name); |
1714 | sprintf(tmpbuf,"%s's %s",donor->name,item->name); |
1715 | FREE_AND_COPY(item->name, tmpbuf); |
1715 | FREE_AND_COPY(item->name, tmpbuf); |
1716 | sprintf(tmpbuf,"%s's %s",donor->name,item->name_pl); |
1716 | sprintf(tmpbuf,"%s's %s",donor->name,item->name_pl); |
1717 | FREE_AND_COPY(item->name_pl, tmpbuf); |
1717 | FREE_AND_COPY(item->name_pl, tmpbuf); |
1718 | |
1718 | |
1719 | /* weight is FLESH weight/100 * donor */ |
1719 | /* weight is FLESH weight/100 * donor */ |
1720 | if((item->weight = (signed long) (((double)item->weight/(double)100.0) * (double)donor->weight))==0) |
1720 | if((item->weight = (signed long) (((double)item->weight/(double)100.0) * (double)donor->weight))==0) |
1721 | item->weight=1; |
1721 | item->weight=1; |
1722 | |
1722 | |
1723 | /* value is multiplied by level of donor */ |
1723 | /* value is multiplied by level of donor */ |
1724 | item->value *= isqrt(donor->level*2); |
1724 | item->value *= isqrt(donor->level*2); |
1725 | |
1725 | |
1726 | /* food value */ |
1726 | /* food value */ |
1727 | item->stats.food += (donor->stats.hp/100) + donor->stats.Con; |
1727 | item->stats.food += (donor->stats.hp/100) + donor->stats.Con; |
1728 | |
1728 | |
1729 | /* flesh items inherit some abilities of donor, but not |
1729 | /* flesh items inherit some abilities of donor, but not |
1730 | * full effect. |
1730 | * full effect. |
1731 | */ |
1731 | */ |
1732 | for (i=0; i<NROFATTACKS; i++) |
1732 | for (i=0; i<NROFATTACKS; i++) |
1733 | item->resist[i] = donor->resist[i]/2; |
1733 | item->resist[i] = donor->resist[i]/2; |
1734 | |
1734 | |
1735 | /* item inherits donor's level (important for quezals) */ |
1735 | /* item inherits donor's level (important for quezals) */ |
1736 | item->level = donor->level; |
1736 | item->level = donor->level; |
1737 | |
1737 | |
1738 | /* if donor has some attacktypes, the flesh is poisonous */ |
1738 | /* if donor has some attacktypes, the flesh is poisonous */ |
1739 | if(donor->attacktype&AT_POISON) |
1739 | if(donor->attacktype&AT_POISON) |
1740 | item->type=POISON; |
1740 | item->type=POISON; |
1741 | if(donor->attacktype&AT_ACID) item->stats.hp = -1*item->stats.food; |
1741 | if(donor->attacktype&AT_ACID) item->stats.hp = -1*item->stats.food; |
1742 | SET_FLAG(item,FLAG_NO_STEAL); |
1742 | SET_FLAG(item,FLAG_NO_STEAL); |
1743 | } |
1743 | } |
1744 | } |
1744 | } |
1745 | |
1745 | |
1746 | /* special_potion() - so that old potion code is still done right. */ |
1746 | /* special_potion() - so that old potion code is still done right. */ |
1747 | |
1747 | |
… | |
… | |
1753 | |
1753 | |
1754 | if(op->stats.Str || op->stats.Dex || op->stats.Con || op->stats.Pow |
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; |
1755 | || op->stats.Wis || op->stats.Int || op->stats.Cha ) return 1; |
1756 | |
1756 | |
1757 | for (i=0; i<NROFATTACKS; i++) |
1757 | for (i=0; i<NROFATTACKS; i++) |
1758 | if (op->resist[i]) return 1; |
1758 | if (op->resist[i]) return 1; |
1759 | |
1759 | |
1760 | return 0; |
1760 | return 0; |
1761 | } |
1761 | } |
1762 | |
1762 | |
1763 | void free_treasurestruct(treasure *t) |
1763 | void free_treasurestruct(treasure *t) |
1764 | { |
1764 | { |
1765 | if (t->next) free_treasurestruct(t->next); |
1765 | if (t->next) free_treasurestruct(t->next); |
1766 | if (t->next_yes) free_treasurestruct(t->next_yes); |
1766 | if (t->next_yes) free_treasurestruct(t->next_yes); |
1767 | if (t->next_no) free_treasurestruct(t->next_no); |
1767 | if (t->next_no) free_treasurestruct(t->next_no); |
1768 | free(t); |
1768 | free(t); |
1769 | } |
1769 | } |
1770 | |
1770 | |
1771 | void free_charlinks(linked_char *lc) |
1771 | void free_charlinks(linked_char *lc) |
1772 | { |
1772 | { |
1773 | if (lc->next) free_charlinks(lc->next); |
1773 | if (lc->next) free_charlinks(lc->next); |
1774 | free(lc); |
1774 | free(lc); |
1775 | } |
1775 | } |
1776 | |
1776 | |
1777 | void free_artifact(artifact *at) |
1777 | void free_artifact(artifact *at) |
1778 | { |
1778 | { |
1779 | |
1779 | |
1780 | if (at->next) free_artifact(at->next); |
1780 | if (at->next) free_artifact(at->next); |
1781 | if (at->allowed) free_charlinks(at->allowed); |
1781 | if (at->allowed) free_charlinks(at->allowed); |
1782 | if (at->item) { |
1782 | if (at->item) { |
1783 | if (at->item->name) free_string(at->item->name); |
1783 | if (at->item->name) free_string(at->item->name); |
1784 | if (at->item->name_pl) free_string(at->item->name_pl); |
1784 | if (at->item->name_pl) free_string(at->item->name_pl); |
1785 | if (at->item->msg) free_string(at->item->msg); |
1785 | if (at->item->msg) free_string(at->item->msg); |
1786 | if (at->item->title) free_string(at->item->title); |
1786 | if (at->item->title) free_string(at->item->title); |
1787 | free(at->item); |
1787 | free(at->item); |
1788 | } |
1788 | } |
1789 | free(at); |
1789 | free(at); |
1790 | } |
1790 | } |
1791 | |
1791 | |
1792 | void free_artifactlist(artifactlist *al) |
1792 | void free_artifactlist(artifactlist *al) |
1793 | { |
1793 | { |
1794 | artifactlist *nextal; |
1794 | artifactlist *nextal; |
1795 | for (al=first_artifactlist; al!=NULL; al=nextal) { |
1795 | for (al=first_artifactlist; al!=NULL; al=nextal) { |
1796 | nextal=al->next; |
1796 | nextal=al->next; |
1797 | if (al->items) { |
1797 | if (al->items) { |
1798 | free_artifact(al->items); |
1798 | free_artifact(al->items); |
1799 | } |
1799 | } |
1800 | free(al); |
1800 | free(al); |
1801 | } |
1801 | } |
1802 | } |
1802 | } |
1803 | |
1803 | |
1804 | void free_all_treasures(void) { |
1804 | void free_all_treasures(void) { |
1805 | treasurelist *tl, *next; |
1805 | treasurelist *tl, *next; |
1806 | |
1806 | |
1807 | |
1807 | |
1808 | for (tl=first_treasurelist; tl!=NULL; tl=next) { |
1808 | for (tl=first_treasurelist; tl!=NULL; tl=next) { |
1809 | next=tl->next; |
1809 | next=tl->next; |
1810 | if (tl->name) free_string(tl->name); |
1810 | if (tl->name) free_string(tl->name); |
1811 | if (tl->items) free_treasurestruct(tl->items); |
1811 | if (tl->items) free_treasurestruct(tl->items); |
1812 | free(tl); |
1812 | free(tl); |
1813 | } |
1813 | } |
1814 | free_artifactlist(first_artifactlist); |
1814 | free_artifactlist(first_artifactlist); |
1815 | } |
1815 | } |