ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/arch.C
(Generate patch)

Comparing deliantra/server/common/arch.C (file contents):
Revision 1.40 by root, Fri Feb 2 22:08:23 2007 UTC vs.
Revision 1.45 by root, Fri Apr 13 07:26:29 2007 UTC

300 * An alternative way to init the hashtable which is slower, but _works_... 300 * An alternative way to init the hashtable which is slower, but _works_...
301 */ 301 */
302void 302void
303init_archetable (void) 303init_archetable (void)
304{ 304{
305 archetype *at;
306
307 LOG (llevDebug, " Setting up archetable...\n"); 305 LOG (llevDebug, " Setting up archetable...\n");
308 306
309 for (at = first_archetype; at; at = at->more ? at->more : at->next) 307 for (archetype *at = first_archetype; at; at = at->next)
308 for (archetype *bt = at; bt; bt = bt->more)
310 at->hash_add (); 309 bt->hash_add ();
311 310
312 LOG (llevDebug, "done\n"); 311 LOG (llevDebug, "done\n");
313} 312}
314 313
315void 314void
334 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f); 333 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f);
335} 334}
336 335
337archetype::archetype () 336archetype::archetype ()
338{ 337{
338 clone.arch = this;
339
339 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_to */ 340 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_to */
340 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */ 341 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */
341} 342}
342 343
343archetype::~archetype () 344archetype::~archetype ()
344{ 345{
346 //TODO: nuke ->more's
347}
348
349archetype *
350archetype::read (object_thawer &f)
351{
352 assert (f.kw == KW_object);
353
354 archetype *head = new archetype;
355 f.get (head->name);
356
357 if (!head->clone.parse_kv (f))
358 {
359 delete head;
360 return 0;
361 }
362
363 for (archetype *prev = head; f.kw == KW_more; )
364 {
365 f.next ();
366
367 assert (f.kw == KW_object);
368
369 archetype *more = new archetype;
370 f.get (more->name);
371
372 if (!more->clone.parse_kv (f))
373 {
374 delete head;
375 return 0;
376 }
377
378 if (more->clone.x > head->tail_x) head->tail_x = more->clone.x;
379 if (more->clone.y > head->tail_y) head->tail_y = more->clone.y;
380
381 more->head = head;
382 more->clone.head = &head->clone;
383 prev->more = more;
384 prev->clone.more = &more->clone;
385
386 prev = more;
387 }
388
389 head->next = first_archetype;
390 first_archetype = head;
391
392 return head;
345} 393}
346 394
347/* 395/*
348 * Reads/parses the archetype-file, and copies into a linked list 396 * Reads/parses the archetype-file, and copies into a linked list
349 * of archetype-structures. 397 * of archetype-structures.
350 */ 398 */
351void 399static bool
352first_arch_pass (object_thawer & fp) 400first_arch_pass (object_thawer &f)
353{ 401{
354 archetype *head = 0, *last_more = 0; 402 for (;;)
355
356 archetype *at = new archetype;
357 at->clone.arch = first_archetype = at;
358
359 while (int i = load_object (fp, &at->clone, 0))
360 { 403 {
361 at->clone.speed_left = (float) (-0.1);
362 /* copy the body_info to the body_used - this is only really
363 * need for monsters, but doesn't hurt to do it for everything.
364 * by doing so, when a monster is created, it has good starting
365 * values for the body_used info, so when items are created
366 * for it, they can be properly equipped.
367 */
368 memcpy (&at->clone.body_used, &at->clone.body_info, sizeof (at->clone.body_info));
369
370 switch (i) 404 switch (f.kw)
371 {
372 case LL_NORMAL: /* A new archetype, just link it with the previous */
373 if (last_more != NULL)
374 last_more->next = at;
375 if (head != NULL)
376 head->next = at;
377 head = last_more = at;
378#if 0
379 if (!op->type)
380 LOG (llevDebug, " WARNING: Archetype %s has no type info!\n", op->arch->name);
381#endif
382 at->tail_x = 0;
383 at->tail_y = 0;
384 break;
385
386 case LL_MORE: /* Another part of the previous archetype, link it correctly */
387
388 at->head = head;
389 at->clone.head = &head->clone;
390 if (last_more != NULL)
391 {
392 last_more->more = at;
393 last_more->clone.more = &at->clone;
394 }
395 last_more = at;
396
397 /* If this multipart image is still composed of individual small
398 * images, don't set the tail_.. values. We can't use them anyways,
399 * and setting these to zero makes the map sending to the client much
400 * easier as just looking at the head, we know what to do.
401 */
402 if (at->clone.face != head->clone.face)
403 {
404 head->tail_x = 0;
405 head->tail_y = 0;
406 }
407 else
408 {
409 if (at->clone.x > head->tail_x)
410 head->tail_x = at->clone.x;
411 if (at->clone.y > head->tail_y)
412 head->tail_y = at->clone.y;
413 }
414 break;
415
416 } 405 {
406 case KW_object:
407 if (!archetype::read (f))
408 return false;
409 continue;
417 410
418 at = new archetype; 411 case KW_EOF:
412 return true;
419 413
420 at->clone.arch = at; 414 default:
421 } 415 if (!f.parse_error ("archetypes file"))
416 return false;
417 }
422 418
423 delete at; 419 f.next ();
420 }
424} 421}
425 422
426/* 423/*
427 * Reads the archetype file once more, and links all pointers between 424 * Reads the archetype file once more, and links all pointers between
428 * archetypes. 425 * archetypes.
429 */ 426 */
430
431void 427void
432second_arch_pass (object_thawer & thawer) 428second_arch_pass (object_thawer & thawer)
433{ 429{
434 char buf[MAX_BUF], *variable = buf, *argument, *cp; 430 char buf[MAX_BUF], *variable = buf, *argument, *cp;
435 archetype *at = NULL, *other; 431 archetype *at = NULL, *other;
436 432
437 while (fgets (buf, MAX_BUF, thawer) != NULL) 433 while (fgets (buf, MAX_BUF, thawer) != NULL)
438 { 434 {
439 if (*buf == '#') 435 if (*buf == '#')
440 continue; 436 continue;
437
441 if ((argument = strchr (buf, ' ')) != NULL) 438 if ((argument = strchr (buf, ' ')) != NULL)
442 { 439 {
443 *argument = '\0', argument++; 440 *argument = '\0', argument++;
444 cp = argument + strlen (argument) - 1; 441 cp = argument + strlen (argument) - 1;
445 while (isspace (*cp)) 442 while (isspace (*cp))
446 { 443 {
447 *cp = '\0'; 444 *cp = '\0';
448 cp--; 445 cp--;
449 } 446 }
450 } 447 }
448
451 if (!strcmp ("Object", variable)) 449 if (!strcmp ("object", variable))
452 { 450 {
453 if ((at = archetype::find (argument)) == NULL) 451 if ((at = archetype::find (argument)) == NULL)
454 LOG (llevError, "Warning: failed to find arch %s\n", argument); 452 LOG (llevError, "Warning: failed to find arch %s\n", argument);
455 } 453 }
456 else if (!strcmp ("other_arch", variable)) 454 else if (!strcmp ("other_arch", variable))
463 at->clone.other_arch = other; 461 at->clone.other_arch = other;
464 } 462 }
465 } 463 }
466 else if (!strcmp ("randomitems", variable)) 464 else if (!strcmp ("randomitems", variable))
467 { 465 {
468 if (at != NULL) 466 if (at)
469 { 467 {
470 treasurelist *tl = find_treasurelist (argument); 468 treasurelist *tl = find_treasurelist (argument);
471 469
472 if (tl == NULL) 470 if (tl == NULL)
473 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument); 471 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument);
476 } 474 }
477 } 475 }
478 } 476 }
479} 477}
480 478
481#ifdef DEBUG
482void
483check_generators (void)
484{
485 archetype *at;
486
487 for (at = first_archetype; at != NULL; at = at->next)
488 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL)
489 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name);
490}
491#endif
492
493/* 479/*
494 * First initialises the archtype hash-table (init_archetable()). 480 * First initialises the archtype hash-table (init_archetable()).
495 * Reads and parses the archetype file (with the first and second-pass 481 * Reads and parses the archetype file (with the first and second-pass
496 * functions). 482 * functions).
497 * Then initialises treasures by calling load_treasures(). 483 * Then initialises treasures by calling load_treasures().
498 */ 484 */
499
500void 485void
501load_archetypes (void) 486load_archetypes (void)
502{ 487{
503 char filename[MAX_BUF]; 488 char filename[MAX_BUF];
504 489
505 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes); 490 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes);
506 LOG (llevDebug, "Reading archetypes from %s:\n", filename); 491 LOG (llevDebug, "Reading archetypes from %s:\n", filename);
507 492
508 { 493 {
509 object_thawer
510 thawer (filename); 494 object_thawer f (filename);
495
496 f.next ();
511 497
512 LOG (llevDebug, " arch-pass 1...\n"); 498 LOG (llevDebug, " arch-pass 1...\n");
513 first_arch_pass (thawer); 499 if (!first_arch_pass (f))
500 cleanup ("errors during first arch pass are fatal");
514 LOG (llevDebug, " done\n"); 501 LOG (llevDebug, " done\n");
515 } 502 }
516 503
517 init_archetable (); 504 init_archetable ();
518 warn_archetypes = 1; 505 warn_archetypes = 1;
519 506
520 { 507 {
521 object_thawer
522 thawer (filename); 508 object_thawer f (filename);
523 509
524 LOG (llevDebug, " loading treasure...\n"); 510 LOG (llevDebug, " loading treasure...\n");
525 load_treasures (); 511 load_treasures ();
526 LOG (llevDebug, " done\n"); 512 LOG (llevDebug, " done\n");
527 LOG (llevDebug, " arch-pass 2...\n"); 513 LOG (llevDebug, " arch-pass 2...\n");
528 second_arch_pass (thawer); 514 second_arch_pass (f);
529 LOG (llevDebug, " done\n"); 515 LOG (llevDebug, " done\n");
530#ifdef DEBUG
531 check_generators ();
532#endif
533 } 516 }
534 LOG (llevDebug, " done\n"); 517 LOG (llevDebug, " done\n");
535} 518}
536 519
537/* 520/*
539 * This function returns NULL on failure. 522 * This function returns NULL on failure.
540 */ 523 */
541object * 524object *
542arch_to_object (archetype *at) 525arch_to_object (archetype *at)
543{ 526{
544 object *op; 527 if (!at)
545
546 if (at == NULL)
547 { 528 {
548 if (warn_archetypes) 529 if (warn_archetypes)
549 LOG (llevError, "Couldn't find archetype.\n"); 530 LOG (llevError, "Couldn't find archetype.\n");
550 531
551 return NULL; 532 return NULL;
552 } 533 }
553 534
554 op = at->clone.clone (); 535 object *op = at->clone.clone ();
555 op->arch = at; 536 op->arch = at;
556 op->instantiate (); 537 op->instantiate ();
557 return op; 538 return op;
558} 539}
559 540

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines