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

Comparing deliantra/server/common/loader.l (file contents):
Revision 1.2 by root, Thu May 11 18:37:20 2006 UTC vs.
Revision 1.10 by root, Sun Aug 27 16:15:11 2006 UTC

1%{ 1%{
2/* 2/*
3 * static char *rcsid_object_c = 3 * static char *rcsid_object_c =
4 * "$Id: loader.l,v 1.2 2006/05/11 18:37:20 root Exp $"; 4 * "$Id: loader.l,v 1.10 2006/08/27 16:15:11 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
35#include <global.h> 35#include <global.h>
36#include <loader.h> 36#include <loader.h>
37#include <newserver.h> 37#include <newserver.h>
38#include <sproto.h> 38#include <sproto.h>
39 39
40#define YY_DECL int lex_load(object *op, int map_flags) 40#define YY_DECL int lex_load(object *op, object_thawer &thawer, int map_flags)
41 41
42static char *yval(); 42static char *yval();
43 43
44static int lex_error; 44static int lex_error;
45static char msgbuf[HUGE_BUF]; 45static char msgbuf[65536];
46static char lorebuf[HUGE_BUF]; 46static char lorebuf[65536];
47 47
48/* Maps the MOVE_* values to names */ 48/* Maps the MOVE_* values to names */
49static const char *const move_name[] = {"walk", "fly_low", "fly_high", "swim", "boat", 49static const char *const move_name[] = {"walk", "fly_low", "fly_high", "swim", "boat",
50 NULL}; 50 NULL};
51 51
57 * If you are adding a new spell, you should not modify this - you 57 * If you are adding a new spell, you should not modify this - you
58 * new spell won't have been used, and thus won't have any legacy object. 58 * new spell won't have been used, and thus won't have any legacy object.
59 * NULL entries in this table are valid - to denote objects that should 59 * NULL entries in this table are valid - to denote objects that should
60 * not be updated for whatever reason. 60 * not be updated for whatever reason.
61 */ 61 */
62const char *const spell_mapping[] = { 62const char *spell_mapping[] = {
63"spell_magic_bullet", /* 0 */ 63"spell_magic_bullet", /* 0 */
64"spell_small_fireball", /* 1 */ 64"spell_small_fireball", /* 1 */
65"spell_medium_fireball", /* 2 */ 65"spell_medium_fireball", /* 2 */
66"spell_large_fireball", /* 3 */ 66"spell_large_fireball", /* 3 */
67"spell_burning_hands", /* 4 */ 67"spell_burning_hands", /* 4 */
325 } 325 }
326 } 326 }
327 LOG(llevError,"set_body_info called with bogus params: %s\n", params); 327 LOG(llevError,"set_body_info called with bogus params: %s\n", params);
328} 328}
329 329
330// return a suitable strign describign an objetc in enough detail to find it
331// used only in check_loaded_object: TODO remove static, move it elsewhere and
332// use it in more log messages.
333static char *op_debug_info_ (object *op, char *info)
334{
335 char info2[256 * 3];
336 char *p = info;
337
338 p += snprintf (p, 256, "%d=\"%s%s%s\"",
339 op->count,
340 op->name ? op->name : "(anon)",
341 op->title ? " " : "",
342 op->title ? op->title : "");
343
344 if (op->env)
345 p += snprintf (p, 256, "(in %s)", op_debug_info_ (op->env, info2));
346
347 if (op->map)
348 p += snprintf (p, 256, "(on %s@%d+%d)", op->map->path, op->x, op->y);
349
350 return info;
351}
352
353static char *op_debug_info (object *op)
354{
355 static char info[256 * 3];
356
357 return op_debug_info_ (op, info);
358}
330 359
331/* This function checks the object after it has been loaded (when we 360/* This function checks the object after it has been loaded (when we
332 * get the 'end' in the input stream). This function can be used to 361 * get the 'end' in the input stream). This function can be used to
333 * deal with legacy objects where fields may have changed. It can also be used 362 * deal with legacy objects where fields may have changed. It can also be used
334 * to check for objects to make sure there are no common errors. 363 * to check for objects to make sure there are no common errors.
363 * really just to catch any errors - program will still run, but 392 * really just to catch any errors - program will still run, but
364 * not in the ideal fashion. 393 * not in the ideal fashion.
365 */ 394 */
366 if ((op->type == WEAPON || op->type==BOW) && arch_init) { 395 if ((op->type == WEAPON || op->type==BOW) && arch_init) {
367 if (!op->skill) { 396 if (!op->skill) {
368 LOG(llevError,"Weapon %s lacks a skill.\n", op->name); 397 LOG(llevError,"Weapon %s lacks a skill.\n", op_debug_info (op));
369 } else if ((!strcmp(op->skill,"one handed weapons") && op->body_info[1] != -1) || 398 } else if ((!strcmp(op->skill,"one handed weapons") && op->body_info[1] != -1) ||
370 (!strcmp(op->skill,"two handed weapons") && op->body_info[1] != -2)) { 399 (!strcmp(op->skill,"two handed weapons") && op->body_info[1] != -2)) {
371 LOG(llevError,"weapon %s arm usage does not match skill: %d, %s\n", 400 LOG(llevError,"weapon %s arm usage does not match skill: %d, %s\n",
372 op->name, op->body_info[1], op->skill); 401 op_debug_info (op), op->body_info[1], op->skill);
373 } 402 }
374 } 403 }
375 404
376 /* We changed last_heal to gen_sp_armour, which is what it 405 /* We changed last_heal to gen_sp_armour, which is what it
377 * really does for many objects. Need to catch any in maps 406 * really does for many objects. Need to catch any in maps
382 (op->type == SHIELD) || (op->type == RING) || 411 (op->type == SHIELD) || (op->type == RING) ||
383 (op->type == BOOTS) || (op->type == GLOVES) || 412 (op->type == BOOTS) || (op->type == GLOVES) ||
384 (op->type == AMULET ) || (op->type == GIRDLE) || 413 (op->type == AMULET ) || (op->type == GIRDLE) ||
385 (op->type == BRACERS ) || (op->type == CLOAK)) { 414 (op->type == BRACERS ) || (op->type == CLOAK)) {
386 if (op->last_heal) { 415 if (op->last_heal) {
387 LOG(llevDebug,"Object %s still has last_heal set, not gen_sp_armour\n", 416 LOG(llevDebug,"Object %s still has last_heal set, not gen_sp_armour\n", op_debug_info (op));
388 op->name?op->name:"NULL");
389 op->gen_sp_armour = op->last_heal; 417 op->gen_sp_armour = op->last_heal;
390 op->last_heal = 0; 418 op->last_heal = 0;
391 } 419 }
392 if (editor) ip =0; 420 if (editor) ip =0;
393 else ip = calc_item_power(op, 0); 421 else ip = calc_item_power(op, 0);
394 /* Legacy objects from before item power was in the game */ 422 /* Legacy objects from before item power was in the game */
395 if (!op->item_power && ip) { 423 if (!op->item_power && ip) {
396 if (ip > 3) { 424 if (ip > 3) {
397 LOG(llevDebug,"Object %s had no item power, using %d\n", 425 LOG(llevDebug,"Object %s had no item power, using %d\n", op_debug_info (op), ip);
398 op->name?op->name:"NULL", ip);
399 } 426 }
400 op->item_power = ip; 427 op->item_power = ip;
401 } 428 }
402 /* Check for possibly bogus values. Has to meet both these criteria - 429 /* Check for possibly bogus values. Has to meet both these criteria -
403 * something that has item_power 1 is probably just fine if our calculated 430 * something that has item_power 1 is probably just fine if our calculated
405 * similarly, it item_power is 0, the first check will always pass, 432 * similarly, it item_power is 0, the first check will always pass,
406 * but not the second one. 433 * but not the second one.
407 */ 434 */
408 if (ip > 2 *op->item_power && ip > (op->item_power + 3)) { 435 if (ip > 2 *op->item_power && ip > (op->item_power + 3)) {
409 LOG(llevDebug,"Object %s seems to have too low item power? %d > %d\n", 436 LOG(llevDebug,"Object %s seems to have too low item power? %d > %d\n",
410 op->name?op->name:"NULL", ip, op->item_power); 437 op_debug_info (op), ip, op->item_power);
411 } 438 }
412 439
413 } 440 }
414 /* Old spellcasting object - need to load in the appropiate object */ 441 /* Old spellcasting object - need to load in the appropiate object */
415 if ((op->type == ROD || op->type == WAND || op->type == SCROLL || op->type == HORN 442 if ((op->type == ROD || op->type == WAND || op->type == SCROLL || op->type == HORN
438 } 465 }
439 466
440 if (QUERY_FLAG(op, FLAG_MONSTER)) { 467 if (QUERY_FLAG(op, FLAG_MONSTER)) {
441 if (op->stats.hp > op->stats.maxhp) 468 if (op->stats.hp > op->stats.maxhp)
442 LOG(llevDebug,"Monster %s has hp set higher than maxhp (%d>%d)\n", 469 LOG(llevDebug,"Monster %s has hp set higher than maxhp (%d>%d)\n",
443 op->name, 470 op_debug_info (op),
444 op->stats.hp, op->stats.maxhp); 471 op->stats.hp, op->stats.maxhp);
445 472
446 /* The archs just need to be updated for this */ 473 /* The archs just need to be updated for this */
447 if (op->move_type ==0) op->move_type = MOVE_WALK; 474 if (op->move_type ==0) op->move_type = MOVE_WALK;
448 } 475 }
616 643
617%} 644%}
618 645
619^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; } 646^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; }
620<MESSAGE>^endmsg{WS}$ { BEGIN( INITIAL ); 647<MESSAGE>^endmsg{WS}$ { BEGIN( INITIAL );
621 op->msg=add_string(msgbuf);
622 /* Just print a warning so we can be reasonably safe 648 /* Just print a warning so we can be reasonably safe
623 * about not overflowing the buffer. 649 * about not overflowing the buffer.
624 */ 650 */
625 if (strlen(op->msg) > (HUGE_BUF/2)) 651 if (strlen(msgbuf) >= HUGE_BUF)
652 {
626 LOG(llevDebug, "\n\tWarning message length > %d (max allowed=%d): %d\n>%.80s<\n", 653 LOG(llevDebug, "\n\tError message length >= %d: %d\n>%.80s<\n",
627 HUGE_BUF/2, HUGE_BUF, strlen(op->msg),op->msg); 654 HUGE_BUF, strlen(op->msg),op->msg);
655 op->msg = add_string ("ERROR, please report: string too long, winged.\n");
656 }
657 else
658 op->msg = add_string (msgbuf);
628 } 659 }
629<MESSAGE>.* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); } 660<MESSAGE>.* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); }
630 661
631^lore{WS}$ { BEGIN( LORE ); lorebuf[0]='\0'; } 662^lore{WS}$ { BEGIN( LORE ); lorebuf[0]='\0'; }
632<LORE>^endlore{WS}$ { BEGIN( INITIAL ); 663<LORE>^endlore{WS}$ { BEGIN( INITIAL );
662^name_pl{S} { char *yv=yval(); 693^name_pl{S} { char *yv=yval();
663 694
664 if (*yv=='\0') LOG(llevError,"Name without val\n"); 695 if (*yv=='\0') LOG(llevError,"Name without val\n");
665 else FREE_AND_COPY(op->name_pl, yv); 696 else FREE_AND_COPY(op->name_pl, yv);
666 } 697 }
698^attach{S} { char *yv=yval();
699 if (*yv)
700 op->attach = add_string (yv);
701 }
667^skill{S} FREE_AND_COPY(op->skill,yval()); 702^skill{S} FREE_AND_COPY(op->skill,yval());
668^custom_name{S} { char *yv=yval(); 703^custom_name{S} { char *yv=yval();
669 704
670 if (*yv=='\0') LOG(llevError,"Custom name without val\n"); 705 if (*yv=='\0') LOG(llevError,"Custom name without val\n");
671 else FREE_AND_COPY(op->custom_name, yv); 706 else FREE_AND_COPY(op->custom_name, yv);
681 */ 716 */
682 if (op->arch) { 717 if (op->arch) {
683 object *tmp; 718 object *tmp;
684 char *yv=yval(); 719 char *yv=yval();
685 720
686 tmp=get_object();
687 tmp->arch = find_archetype(yv); 721 archetype *arch = find_archetype(yv);
688 if (tmp->arch!=NULL) 722 if (arch!=NULL)
689 copy_object(&tmp->arch->clone,tmp); 723 tmp = arch_to_object (arch);
690 else { 724 else {
725 tmp = get_object ();
691 if (tmp->name) free_string(tmp->name); 726 if (tmp->name) free_string(tmp->name);
692 /* record the name of the broken object */ 727 /* record the name of the broken object */
693 tmp->name = add_string(yv); 728 tmp->name = add_string(yv);
694 } 729 }
695 strcpy(msgbuf, ""); 730 strcpy(msgbuf, "");
696 strcpy(lorebuf, ""); 731 strcpy(lorebuf, "");
697 lex_load(tmp, map_flags); 732 lex_load(tmp, thawer, map_flags);
698 if (tmp->arch) { 733 if (tmp->arch) {
699 insert_ob_in_ob(tmp,op); 734 insert_ob_in_ob(tmp,op);
700 } 735 }
701 else { 736 else {
702 LOG(llevDebug,"Discarding object without arch: %s\n", tmp->name?tmp->name:"(null)"); 737 LOG(llevDebug,"Discarding object without arch: %s\n", tmp->name?tmp->name:"(null)");
706 /* This is the actual archetype definition then */ 741 /* This is the actual archetype definition then */
707 else { 742 else {
708 char *yv=yval(); 743 char *yv=yval();
709 744
710 op->arch=find_archetype(yv); 745 op->arch=find_archetype(yv);
711 if (op->arch!=NULL) copy_object(&op->arch->clone,op); 746 if (op->arch!=NULL) {
712 else if (!arch_init) { 747 copy_object(&op->arch->clone,op);
748 op->instantiate ();
749 } else if (!arch_init) {
713 if (op->name) free_string(op->name); 750 if (op->name) free_string(op->name);
714 /* record the name of the broken object */ 751 /* record the name of the broken object */
715 op->name = add_string(yv); 752 op->name = add_string(yv);
716 } 753 }
717 } 754 }
733 */ 770 */
734 ismore=1; 771 ismore=1;
735 } 772 }
736 773
737^end{WS}$ { check_loaded_object(op); 774^end{WS}$ { check_loaded_object(op);
775 thawer.get (op);
738 if (ismore) return LL_MORE; 776 if (ismore) return LL_MORE;
739 else return LL_NORMAL; 777 else return LL_NORMAL;
740 } 778 }
741^last_heal{S} op->last_heal = IVAL; 779^last_heal{S} op->last_heal = IVAL;
742^last_sp{S} op->last_sp = IVAL; 780^last_sp{S} op->last_sp = IVAL;
953^resist_disease{S} SET_RESIST(op, ATNR_DISEASE, IVAL); 991^resist_disease{S} SET_RESIST(op, ATNR_DISEASE, IVAL);
954 992
955 /* Old style resistances */ 993 /* Old style resistances */
956^immune{S} set_protection(op, IVAL, RESIST_IMMUNE); 994^immune{S} set_protection(op, IVAL, RESIST_IMMUNE);
957^protected{S} set_protection(op, IVAL, RESIST_PROT); 995^protected{S} set_protection(op, IVAL, RESIST_PROT);
958^vulnerable{S} set_protection(op, IVAL, RESIST_VULN); 996^vulnerable{S} set_protection(op, IVAL, (uint16) RESIST_VULN);
959 997
960 /* old values - keep them around for now, but they should be removed at some point */ 998 /* old values - keep them around for now, but they should be removed at some point */
961^has_ready_rod{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); 999^has_ready_rod{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL);
962^has_ready_horn{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); 1000^has_ready_horn{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL);
963^has_ready_wand{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); 1001^has_ready_wand{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL);
1002^can_impale{S} { /* That these are for the new combat code */ } 1040^can_impale{S} { /* That these are for the new combat code */ }
1003^can_cut{S} { /* just ignore for now */ } 1041^can_cut{S} { /* just ignore for now */ }
1004^can_dam_armour{S} { } 1042^can_dam_armour{S} { }
1005^weapontype{S} op->weapontype = IVAL; 1043^weapontype{S} op->weapontype = IVAL;
1006^tooltype{S} op->tooltype = IVAL; 1044^tooltype{S} op->tooltype = IVAL;
1007^casting_time{S} op->casting_time = FVAL; 1045^casting_time{S} op->casting_time = (sint16) FVAL;
1008^elevation{S} op->elevation = IVAL; 1046^elevation{S} op->elevation = IVAL;
1009^smoothlevel{S} op->smoothlevel = IVAL; 1047^smoothlevel{S} op->smoothlevel = IVAL;
1010^client_type{S} op->client_type = IVAL; 1048^client_type{S} op->client_type = IVAL;
1011^body_{A} set_body_info(op, yytext); 1049^body_{A} set_body_info(op, yytext);
1012^duration{S} op->duration = IVAL; 1050^duration{S} op->duration = IVAL;
1367 * be reset. 1405 * be reset.
1368 * LO_NOREAD (3): Reset the buffers, but don't read from it. (op can be null) 1406 * LO_NOREAD (3): Reset the buffers, but don't read from it. (op can be null)
1369 * 1407 *
1370 */ 1408 */
1371 1409
1372int load_object(FILE *fp, object *op, int bufstate, int map_flags) { 1410int load_object(FILE *fp, object_thawer &thawer, object *op, int bufstate, int map_flags) {
1373 int retval; 1411 int retval;
1374 char inbuf[MAX_BUF]; 1412 char inbuf[MAX_BUF];
1375 1413
1376 strcpy(msgbuf, ""); 1414 strcpy(msgbuf, "");
1377 strcpy(lorebuf, ""); 1415 strcpy(lorebuf, "");
1383 } 1421 }
1384 if (bufstate==LO_LINEMODE) { 1422 if (bufstate==LO_LINEMODE) {
1385 YY_BUFFER_STATE yybufstate; 1423 YY_BUFFER_STATE yybufstate;
1386 while (fgets(inbuf, MAX_BUF-3, fp)) { 1424 while (fgets(inbuf, MAX_BUF-3, fp)) {
1387 yybufstate=yy_scan_string(inbuf); 1425 yybufstate=yy_scan_string(inbuf);
1388 retval=lex_load(op, map_flags); 1426 retval=lex_load(op, thawer, map_flags);
1389 yy_delete_buffer(yybufstate); 1427 yy_delete_buffer(yybufstate);
1390 if (retval==LL_NORMAL) return retval; 1428 if (retval==LL_NORMAL) return retval;
1391 } 1429 }
1392 LOG(llevDebug,"Got eof while scanning strings\n"); 1430 LOG(llevDebug,"Got eof while scanning strings\n");
1393 return LL_EOF; 1431 return LL_EOF;
1394 } 1432 }
1395 1433
1396 retval=lex_load(op, map_flags); 1434 retval=lex_load(op, thawer, map_flags);
1397 if (op->current_weapon_script != NULL) 1435 if (op->current_weapon_script != NULL)
1398 { 1436 {
1399 op->current_weapon = find_best_weapon_used_match(op, op->current_weapon_script); 1437 op->current_weapon = find_best_weapon_used_match(op, op->current_weapon_script);
1400 LOG(llevDebug, "CurrentWeapon Loaded !\n"); 1438 LOG(llevDebug, "CurrentWeapon Loaded !\n");
1401 }; 1439 };
1412 * override values and in c_wiz to mutate values. 1450 * override values and in c_wiz to mutate values.
1413 */ 1451 */
1414int set_variable(object *op,char *buf) { 1452int set_variable(object *op,char *buf) {
1415 YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER; 1453 YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER;
1416 int retval; 1454 int retval;
1455 object_thawer thawer;
1417 1456
1418 strcpy(msgbuf, ""); 1457 strcpy(msgbuf, "");
1419 strcpy(lorebuf, ""); 1458 strcpy(lorebuf, "");
1420 yy_push_state(INITIAL); 1459 yy_push_state(INITIAL);
1421 yybufstate=yy_scan_string(buf); 1460 yybufstate=yy_scan_string(buf);
1422 retval=lex_load(op,0); 1461 retval=lex_load(op,thawer,0);
1423 yy_switch_to_buffer(yycurbuf); 1462 yy_switch_to_buffer(yycurbuf);
1424 yy_delete_buffer(yybufstate); 1463 yy_delete_buffer(yybufstate);
1425 yy_pop_state(); 1464 yy_pop_state();
1426 return retval; 1465 return retval;
1427} 1466}
1616 * NEVER touch buf between PREPARE_FASTCAT(buf) and 1655 * NEVER touch buf between PREPARE_FASTCAT(buf) and
1617 * FINISH_FASTCAT(buf) 1656 * FINISH_FASTCAT(buf)
1618 */ 1657 */
1619 static int already_run = 0; 1658 static int already_run = 0;
1620 static int flag_lens[NUM_FLAGS]; 1659 static int flag_lens[NUM_FLAGS];
1621 static char buf2[HUGE_BUF]; 1660 char buf2[4096]; // / was HUFE_BUF, which was hugely incorrect, as is this value, but much less so
1622 static char buf[HUGE_BUF]; 1661 static char buf[128*1024]; // < the assumption is that every object always fits. fixing this bug, however
1623 char* fastbuf; 1662 char* fastbuf; // \ requires a large rewrite of the code, so its left to the next total rewrite.
1624 int tmp; 1663 int tmp;
1625 int i; 1664 int i;
1626#if 0
1627/*Memory polluting code. Should help detect problems, very slow*/
1628 for (i=0;i<HUGE_BUF;i++){
1629 buf[i]='a'+(unsigned short)(i%25);
1630 }
1631#endif
1632 event *etmp; 1665 event *etmp;
1633 event *etmp2; 1666 event *etmp2;
1634 key_value * my_field; 1667 key_value * my_field;
1635 key_value * arch_field; 1668 key_value * arch_field;
1636 1669
1967 get_string_move_type(op->move_slow), 2000 get_string_move_type(op->move_slow),
1968 10); 2001 10);
1969 } 2002 }
1970 2003
1971 if (op->move_slow_penalty != op2->move_slow_penalty) { 2004 if (op->move_slow_penalty != op2->move_slow_penalty) {
1972 FAST_SAVE_LONG(fastbuf,"move_slow_penalty ",op->move_slow_penalty,18); 2005 FAST_SAVE_LONG(fastbuf,"move_slow_penalty ",(long) op->move_slow_penalty,18);
1973 } 2006 }
1974 2007
1975 if (!COMPARE_FLAGS(op,op2)) { 2008 if (!COMPARE_FLAGS(op,op2)) {
1976 for (tmp=0; tmp <= NUM_FLAGS; tmp++) { 2009 for (tmp=0; tmp <= NUM_FLAGS; tmp++) {
1977 if (flag_names[tmp] && (QUERY_FLAG(op, tmp) != QUERY_FLAG(op2, tmp))) { 2010 if (flag_names[tmp] && (QUERY_FLAG(op, tmp) != QUERY_FLAG(op2, tmp))) {
2000 * the only place this is not set is when saving the player. 2033 * the only place this is not set is when saving the player.
2001 * If bit 1 of flag is set, don't remove the object after save. As of now, 2034 * If bit 1 of flag is set, don't remove the object after save. As of now,
2002 * all of the callers are setting this. 2035 * all of the callers are setting this.
2003 */ 2036 */
2004 2037
2005void save_object(FILE *fp,object *op, int flag) { 2038void save_object(FILE *fp,object_freezer &freezer,object *op, int flag) {
2006 archetype *at; 2039 archetype *at;
2007 char *cp; 2040 char *cp;
2008 object *tmp,*old; 2041 object *tmp,*old;
2009 2042
2010 /* Even if the object does have an owner, it would seem that we should 2043 /* Even if the object does have an owner, it would seem that we should
2028 2061
2029 old=NULL; 2062 old=NULL;
2030 2063
2031 if (flag & 2 ) 2064 if (flag & 2 )
2032 for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) 2065 for(tmp=op->inv;tmp!=NULL;tmp=tmp->below)
2033 save_object(fp,tmp,flag); 2066 save_object(fp,freezer,tmp,flag);
2034 2067
2035 /* Slightly different logic because tmp/op will be removed by 2068 /* Slightly different logic because tmp/op will be removed by
2036 * the save_object we call. So we just keep looking at op->inv 2069 * the save_object we call. So we just keep looking at op->inv
2037 * until there is nothing left. In theory, the variable old 2070 * until there is nothing left. In theory, the variable old
2038 * should not be needed, as recursive loops shouldn't happen. 2071 * should not be needed, as recursive loops shouldn't happen.
2040 else while ((tmp=op->inv)!=NULL) { 2073 else while ((tmp=op->inv)!=NULL) {
2041 if(old==tmp) { 2074 if(old==tmp) {
2042 LOG(llevError," Recursive loop in inventory\n"); 2075 LOG(llevError," Recursive loop in inventory\n");
2043 break; 2076 break;
2044 } 2077 }
2045 save_object(fp,tmp,flag); 2078 save_object(fp,freezer,tmp,flag);
2046 old=tmp; 2079 old=tmp;
2047 } 2080 }
2048 2081
2049 if (!(flag&2)) { 2082 if (!(flag&2)) {
2050 remove_ob(op); 2083 remove_ob(op);
2051 free_object (op); 2084 free_object (op);
2052 } 2085 }
2053 2086
2054 fprintf(fp,"end\n"); 2087 fprintf(fp,"end\n");
2088 freezer.put (op);
2055} 2089}
2056 2090
2057void insert_event(object* op, int etype, char *ehook, char *eplug, char *eoptions) 2091void insert_event(object* op, int etype, char *ehook, char *eplug, char *eoptions)
2058{ 2092{
2059 event *evt; 2093 event *evt;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines