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.41 by root, Mon Apr 16 06:23:40 2007 UTC vs.
Revision 1.42 by root, Mon Apr 16 10:14:25 2007 UTC

20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 21 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de> 22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
23 */ 23 */
24 24
25#define ALLOWED_COMBINATION
26
27/* TREASURE_DEBUG does some checking on the treasurelists after loading. 25/* TREASURE_DEBUG does some checking on the treasurelists after loading.
28 * It is useful for finding bugs in the treasures file. Since it only 26 * It is useful for finding bugs in the treasures file. Since it only
29 * slows the startup some (and not actual game play), it is by default 27 * slows the startup some (and not actual game play), it is by default
30 * left on 28 * left on
31 */ 29 */
32#define TREASURE_DEBUG 30#define TREASURE_DEBUG
33 31
34/* TREASURE_VERBOSE enables copious output concerning artifact generation */ 32/* TREASURE_VERBOSE enables copious output concerning artifact generation */
35 33
36/* #define TREASURE_VERBOSE */ 34//#define TREASURE_VERBOSE
37 35
38#include <global.h> 36#include <global.h>
39#include <treasure.h> 37#include <treasure.h>
40#include <funcpoint.h> 38#include <funcpoint.h>
41#include <loader.h> 39#include <loader.h>
133 131
134/* 132/*
135 * Reads the lib/treasure file from disk, and parses the contents 133 * Reads the lib/treasure file from disk, and parses the contents
136 * into an internal treasure structure (very linked lists) 134 * into an internal treasure structure (very linked lists)
137 */ 135 */
138
139static treasure * 136static treasure *
140load_treasure (FILE * fp, int *line) 137load_treasure (object_thawer &f)
141{ 138{
142 char buf[MAX_BUF], *cp, variable[MAX_BUF];
143 treasure *t = new treasure; 139 treasure *t = new treasure;
144 int value; 140 int value;
145 141
146 nroftreasures++; 142 nroftreasures++;
147 while (fgets (buf, MAX_BUF, fp) != NULL)
148 {
149 (*line)++;
150 143
151 if (*buf == '#') 144 for (;;)
152 continue; 145 {
153 if ((cp = strchr (buf, '\n')) != NULL) 146 coroapi::cede_every (10);
154 *cp = '\0';
155 cp = buf;
156 while (isspace (*cp)) /* Skip blanks */
157 cp++;
158 147
159 if (sscanf (cp, "arch %s", variable)) 148 f.next ();
160 { 149
161 if ((t->item = archetype::find (variable)) == NULL) 150 switch (f.kw)
162 LOG (llevError, "Treasure lacks archetype: %s\n", variable);
163 } 151 {
164 else if (sscanf (cp, "list %s", variable)) 152 case KW_arch:
165 t->name = variable; 153 if (!(t->item = archetype::find (f.get_str ())))
166 else if (sscanf (cp, "change_name %s", variable)) 154 LOG (llevError, "%s:%d treasure references unknown archetype '%s', skipping.\n", f.name, f.linenum, f.get_str ());
167 t->change_arch.name = variable; 155 break;
168 else if (sscanf (cp, "change_title %s", variable)) 156
169 t->change_arch.title = variable; 157 case KW_list: f.get (t->name); break;
170 else if (sscanf (cp, "change_slaying %s", variable)) 158 case KW_change_name: f.get (t->change_arch.name); break;
171 t->change_arch.slaying = variable; 159 case KW_change_title: f.get (t->change_arch.title); break;
172 else if (sscanf (cp, "chance %d", &value)) 160 case KW_change_slaying: f.get (t->change_arch.slaying); break;
173 t->chance = (uint8) value; 161 case KW_chance: f.get (t->chance); break;
174 else if (sscanf (cp, "nrof %d", &value)) 162 case KW_nrof: f.get (t->nrof); break;
175 t->nrof = (uint16) value; 163 case KW_magic: f.get (t->magic); break;
176 else if (sscanf (cp, "magic %d", &value)) 164
177 t->magic = (uint8) value; 165 case KW_yes: t->next_yes = load_treasure (f); break;
178 else if (!strcmp (cp, "yes")) 166 case KW_no: t->next_no = load_treasure (f); break;
179 t->next_yes = load_treasure (fp, line); 167
180 else if (!strcmp (cp, "no")) 168 case KW_end:
181 t->next_no = load_treasure (fp, line);
182 else if (!strcmp (cp, "end"))
183 return t;
184 else if (!strcmp (cp, "more"))
185 {
186 t->next = load_treasure (fp, line);
187 return t; 169 return t;
170
171 case KW_more:
172 t->next = load_treasure (f);
173 return t;
174
175 default:
176 if (!f.parse_error ("treasure list"))
177 return t; // error
178
179 return t;
188 } 180 }
189 else
190 LOG (llevError, "Unknown treasure-command: '%s', last entry %s, line %d\n", cp, &t->name, *line);
191 } 181 }
192 LOG (llevError, "treasure lacks 'end'.\n");
193 return t;
194} 182}
195 183
196#ifdef TREASURE_DEBUG 184#ifdef TREASURE_DEBUG
197
198/* recursived checks the linked list. Treasurelist is passed only 185/* recursived checks the linked list. Treasurelist is passed only
199 * so that the treasure name can be printed out 186 * so that the treasure name can be printed out
200 */ 187 */
201static void 188static void
202check_treasurelist (const treasure *t, const treasurelist * tl) 189check_treasurelist (const treasure *t, const treasurelist * tl)
217 204
218/* 205/*
219 * Opens LIBDIR/treasure and reads all treasure-declarations from it. 206 * Opens LIBDIR/treasure and reads all treasure-declarations from it.
220 * Each treasure is parsed with the help of load_treasure(). 207 * Each treasure is parsed with the help of load_treasure().
221 */ 208 */
222 209bool
223void
224load_treasures (void) 210load_treasures ()
225{ 211{
226 FILE *fp;
227 char filename[MAX_BUF], buf[MAX_BUF], name[MAX_BUF];
228 treasure *t; 212 treasure *t;
229 int comp, line = 0; 213 int comp, line = 0;
230 214
215 char filename[MAX_BUF];
231 sprintf (filename, "%s/%s", settings.datadir, settings.treasures); 216 sprintf (filename, "%s/%s", settings.datadir, settings.treasures);
232 if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL) 217
218 object_thawer f (filename);
219
220 if (!f)
233 { 221 {
234 LOG (llevError, "Can't open treasure file.\n"); 222 LOG (llevError, "Can't open treasure file.\n");
235 return; 223 return false;
236 }
237 while (fgets (buf, MAX_BUF, fp) != NULL)
238 { 224 }
239 line++;
240 if (*buf == '#' || *buf == '\n')
241 ; // ignore
242 else if (sscanf (buf, "treasureone %s\n", name) || sscanf (buf, "treasure %s\n", name))
243 {
244 treasurelist *tl = treasurelist::get (name);
245 225
246 clear (tl); 226 f.next ();
247 tl->items = load_treasure (fp, &line);
248 227
249 /* This is a one of the many items on the list should be generated. 228 for (;;)
250 * Add up the chance total, and check to make sure the yes & no 229 {
251 * fields of the treasures are not being used. 230 switch (f.kw)
252 */ 231 {
253 if (!strncmp (buf, "treasureone", 11)) 232 case KW_treasure:
233 case KW_treasureone:
254 { 234 {
255 for (t = tl->items; t; t = t->next) 235 bool one = f.kw == KW_treasureone;
236 treasurelist *tl = treasurelist::get (f.get_str ());
237
238 clear (tl);
239 tl->items = load_treasure (f);
240
241 if (!tl->items)
242 return false;
243
244 /* This is a one of the many items on the list should be generated.
245 * Add up the chance total, and check to make sure the yes & no
246 * fields of the treasures are not being used.
247 */
248 if (one)
256 { 249 {
250 for (t = tl->items; t; t = t->next)
251 {
257#ifdef TREASURE_DEBUG 252#ifdef TREASURE_DEBUG
258 if (t->next_yes || t->next_no) 253 if (t->next_yes || t->next_no)
259 { 254 {
260 LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name); 255 LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name);
261 LOG (llevError, " the next_yes or next_no field is set\n"); 256 LOG (llevError, " the next_yes or next_no field is set\n");
257 }
258#endif
259 tl->total_chance += t->chance;
262 } 260 }
263#endif
264 tl->total_chance += t->chance;
265 } 261 }
266 } 262 }
267 } 263 break;
268 else
269 LOG (llevError, "Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line);
270 }
271 264
272 close_and_delete (fp, comp); 265 case KW_EOF:
273
274#ifdef TREASURE_DEBUG 266#ifdef TREASURE_DEBUG
275 /* Perform some checks on how valid the treasure data actually is. 267 /* Perform some checks on how valid the treasure data actually is.
276 * verify that list transitions work (ie, the list that it is supposed 268 * verify that list transitions work (ie, the list that it is supposed
277 * to transition to exists). Also, verify that at least the name 269 * to transition to exists). Also, verify that at least the name
278 * or archetype is set for each treasure element. 270 * or archetype is set for each treasure element.
279 */ 271 */
280 for (treasurelist *tl = first_treasurelist; tl; tl = tl->next) 272 for (treasurelist *tl = first_treasurelist; tl; tl = tl->next)
281 check_treasurelist (tl->items, tl); 273 check_treasurelist (tl->items, tl);
282#endif 274#endif
275 return true;
276
277 default:
278 if (!f.parse_error ("treasure lists"))
279 return false;
280
281 break;
282 }
283
284 f.next ();
285 }
283} 286}
284 287
285/* 288/*
286 * Generates the objects specified by the given treasure. 289 * Generates the objects specified by the given treasure.
287 * It goes recursively through the rest of the linked list. 290 * It goes recursively through the rest of the linked list.
482 * magical bonus "wanted". 485 * magical bonus "wanted".
483 */ 486 */
484 487
485static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = { 488static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = {
486 489
487/*chance of magic difficulty*/ 490// chance of magic difficulty
488
489/* +0 +1 +2 +3 +4 */ 491// +0 +1 +2 +3 +4
490 {95, 2, 2, 1, 0}, /*1 */ 492 {95, 2, 2, 1, 0}, // 1
491 {92, 5, 2, 1, 0}, /*2 */ 493 {92, 5, 2, 1, 0}, // 2
492 {85, 10, 4, 1, 0}, /*3 */ 494 {85, 10, 4, 1, 0}, // 3
493 {80, 14, 4, 2, 0}, /*4 */ 495 {80, 14, 4, 2, 0}, // 4
494 {75, 17, 5, 2, 1}, /*5 */ 496 {75, 17, 5, 2, 1}, // 5
495 {70, 18, 8, 3, 1}, /*6 */ 497 {70, 18, 8, 3, 1}, // 6
496 {65, 21, 10, 3, 1}, /*7 */ 498 {65, 21, 10, 3, 1}, // 7
497 {60, 22, 12, 4, 2}, /*8 */ 499 {60, 22, 12, 4, 2}, // 8
498 {55, 25, 14, 4, 2}, /*9 */ 500 {55, 25, 14, 4, 2}, // 9
499 {50, 27, 16, 5, 2}, /*10 */ 501 {50, 27, 16, 5, 2}, // 10
500 {45, 28, 18, 6, 3}, /*11 */ 502 {45, 28, 18, 6, 3}, // 11
501 {42, 28, 20, 7, 3}, /*12 */ 503 {42, 28, 20, 7, 3}, // 12
502 {40, 27, 21, 8, 4}, /*13 */ 504 {40, 27, 21, 8, 4}, // 13
503 {38, 25, 22, 10, 5}, /*14 */ 505 {38, 25, 22, 10, 5}, // 14
504 {36, 23, 23, 12, 6}, /*15 */ 506 {36, 23, 23, 12, 6}, // 15
505 {33, 21, 24, 14, 8}, /*16 */ 507 {33, 21, 24, 14, 8}, // 16
506 {31, 19, 25, 16, 9}, /*17 */ 508 {31, 19, 25, 16, 9}, // 17
507 {27, 15, 30, 18, 10}, /*18 */ 509 {27, 15, 30, 18, 10}, // 18
508 {20, 12, 30, 25, 13}, /*19 */ 510 {20, 12, 30, 25, 13}, // 19
509 {15, 10, 28, 30, 17}, /*20 */ 511 {15, 10, 28, 30, 17}, // 20
510 {13, 9, 27, 28, 23}, /*21 */ 512 {13, 9, 27, 28, 23}, // 21
511 {10, 8, 25, 28, 29}, /*22 */ 513 {10, 8, 25, 28, 29}, // 22
512 {8, 7, 23, 26, 36}, /*23 */ 514 { 8, 7, 23, 26, 36}, // 23
513 {6, 6, 20, 22, 46}, /*24 */ 515 { 6, 6, 20, 22, 46}, // 24
514 {4, 5, 17, 18, 56}, /*25 */ 516 { 4, 5, 17, 18, 56}, // 25
515 {2, 4, 12, 14, 68}, /*26 */ 517 { 2, 4, 12, 14, 68}, // 26
516 {0, 3, 7, 10, 80}, /*27 */ 518 { 0, 3, 7, 10, 80}, // 27
517 {0, 0, 3, 7, 90}, /*28 */ 519 { 0, 0, 3, 7, 90}, // 28
518 {0, 0, 0, 3, 97}, /*29 */ 520 { 0, 0, 0, 3, 97}, // 29
519 {0, 0, 0, 0, 100}, /*30 */ 521 { 0, 0, 0, 0, 100}, // 30
520 {0, 0, 0, 0, 100}, /*31 */ 522 { 0, 0, 0, 0, 100}, // 31
521}; 523};
522 524
523 525
524/* calculate the appropriate level for wands staves and scrolls. 526/* calculate the appropriate level for wands staves and scrolls.
525 * This code presumes that op has had its spell object created (in op->inv) 527 * This code presumes that op has had its spell object created (in op->inv)
847 849
848 if (op->randomitems && op->type != SPELL) 850 if (op->randomitems && op->type != SPELL)
849 { 851 {
850 create_treasure (op->randomitems, op, flags, difficulty, 0); 852 create_treasure (op->randomitems, op, flags, difficulty, 0);
851 if (!op->inv) 853 if (!op->inv)
852 LOG (llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", &op->name); 854 LOG (llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", op->debug_desc ());
853 855
854 /* So the treasure doesn't get created again */ 856 /* So the treasure doesn't get created again */
855 op->randomitems = NULL; 857 op->randomitems = 0;
856 } 858 }
857 859
858 if (difficulty < 1) 860 if (difficulty < 1)
859 difficulty = 1; 861 difficulty = 1;
860 862
1457 int i, tmp; 1459 int i, tmp;
1458 1460
1459 if (change->face != blank_face) 1461 if (change->face != blank_face)
1460 { 1462 {
1461#ifdef TREASURE_VERBOSE 1463#ifdef TREASURE_VERBOSE
1462 LOG (llevDebug, "FACE: %d\n", change->face->number); 1464 LOG (llevDebug, "add_abilities change face: %d\n", change->face);
1463#endif 1465#endif
1464 op->face = change->face; 1466 op->face = change->face;
1465 } 1467 }
1466 1468
1467 for (i = 0; i < NUM_STATS; i++) 1469 for (i = 0; i < NUM_STATS; i++)
1648 if (art->allowed == (linked_char *) NULL) 1650 if (art->allowed == (linked_char *) NULL)
1649 return 1; /* Ie, "all" */ 1651 return 1; /* Ie, "all" */
1650 for (tmp = art->allowed; tmp; tmp = tmp->next) 1652 for (tmp = art->allowed; tmp; tmp = tmp->next)
1651 { 1653 {
1652#ifdef TREASURE_VERBOSE 1654#ifdef TREASURE_VERBOSE
1653 LOG (llevDebug, "legal_art: %s\n", tmp->name); 1655 LOG (llevDebug, "legal_art: %s\n", &tmp->name);
1654#endif 1656#endif
1655 if (*tmp->name == '!') 1657 if (*tmp->name == '!')
1656 name = tmp->name + 1, neg = 1; 1658 name = tmp->name + 1, neg = 1;
1657 else 1659 else
1658 name = tmp->name, neg = 0; 1660 name = tmp->name, neg = 0;
1753 continue; 1755 continue;
1754 1756
1755 if (!legal_artifact_combination (op, art)) 1757 if (!legal_artifact_combination (op, art))
1756 { 1758 {
1757#ifdef TREASURE_VERBOSE 1759#ifdef TREASURE_VERBOSE
1758 LOG (llevDebug, "%s of %s was not a legal combination.\n", op->name, art->item->name); 1760 LOG (llevDebug, "%s of %s was not a legal combination.\n", &op->name, &art->item->name);
1759#endif 1761#endif
1760 continue; 1762 continue;
1761 } 1763 }
1764
1762 give_artifact_abilities (op, art->item); 1765 give_artifact_abilities (op, art->item);
1763 return; 1766 return;
1764 } 1767 }
1765} 1768}
1766 1769

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines