1 | %{ |
1 | %{ |
2 | /* |
2 | /* |
3 | * static char *rcsid_object_c = |
3 | * static char *rcsid_object_c = |
4 | * "$Id: loader.l,v 1.7 2006/08/13 17:16:00 elmex Exp $"; |
4 | * "$Id: loader.l,v 1.11 2006/08/27 17:59:25 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 | |
42 | static char *yval(); |
42 | static char *yval(); |
43 | |
43 | |
44 | static int lex_error; |
44 | static int lex_error; |
45 | static char msgbuf[HUGE_BUF]; |
45 | static char msgbuf[65536]; |
46 | static char lorebuf[HUGE_BUF]; |
46 | static char lorebuf[65536]; |
47 | |
47 | |
48 | /* Maps the MOVE_* values to names */ |
48 | /* Maps the MOVE_* values to names */ |
49 | static const char *const move_name[] = {"walk", "fly_low", "fly_high", "swim", "boat", |
49 | static const char *const move_name[] = {"walk", "fly_low", "fly_high", "swim", "boat", |
50 | NULL}; |
50 | NULL}; |
51 | |
51 | |
… | |
… | |
693 | ^name_pl{S} { char *yv=yval(); |
693 | ^name_pl{S} { char *yv=yval(); |
694 | |
694 | |
695 | if (*yv=='\0') LOG(llevError,"Name without val\n"); |
695 | if (*yv=='\0') LOG(llevError,"Name without val\n"); |
696 | else FREE_AND_COPY(op->name_pl, yv); |
696 | else FREE_AND_COPY(op->name_pl, yv); |
697 | } |
697 | } |
|
|
698 | ^attach{S} { char *yv=yval(); |
|
|
699 | if (*yv) |
|
|
700 | op->attach = add_string (yv); |
|
|
701 | } |
698 | ^skill{S} FREE_AND_COPY(op->skill,yval()); |
702 | ^skill{S} FREE_AND_COPY(op->skill,yval()); |
699 | ^custom_name{S} { char *yv=yval(); |
703 | ^custom_name{S} { char *yv=yval(); |
700 | |
704 | |
701 | if (*yv=='\0') LOG(llevError,"Custom name without val\n"); |
705 | if (*yv=='\0') LOG(llevError,"Custom name without val\n"); |
702 | else FREE_AND_COPY(op->custom_name, yv); |
706 | else FREE_AND_COPY(op->custom_name, yv); |
… | |
… | |
712 | */ |
716 | */ |
713 | if (op->arch) { |
717 | if (op->arch) { |
714 | object *tmp; |
718 | object *tmp; |
715 | char *yv=yval(); |
719 | char *yv=yval(); |
716 | |
720 | |
717 | tmp=get_object(); |
|
|
718 | tmp->arch = find_archetype(yv); |
721 | archetype *arch = find_archetype(yv); |
719 | if (tmp->arch!=NULL) |
722 | if (arch!=NULL) |
720 | copy_object(&tmp->arch->clone,tmp); |
723 | tmp = arch_to_object (arch); |
721 | else { |
724 | else { |
|
|
725 | tmp = get_object (); |
722 | if (tmp->name) free_string(tmp->name); |
726 | if (tmp->name) free_string(tmp->name); |
723 | /* record the name of the broken object */ |
727 | /* record the name of the broken object */ |
724 | tmp->name = add_string(yv); |
728 | tmp->name = add_string(yv); |
725 | } |
729 | } |
726 | strcpy(msgbuf, ""); |
730 | strcpy(msgbuf, ""); |
727 | strcpy(lorebuf, ""); |
731 | strcpy(lorebuf, ""); |
728 | lex_load(tmp, map_flags); |
732 | lex_load(tmp, thawer, map_flags); |
729 | if (tmp->arch) { |
733 | if (tmp->arch) { |
730 | insert_ob_in_ob(tmp,op); |
734 | insert_ob_in_ob(tmp,op); |
731 | } |
735 | } |
732 | else { |
736 | else { |
733 | 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)"); |
… | |
… | |
737 | /* This is the actual archetype definition then */ |
741 | /* This is the actual archetype definition then */ |
738 | else { |
742 | else { |
739 | char *yv=yval(); |
743 | char *yv=yval(); |
740 | |
744 | |
741 | op->arch=find_archetype(yv); |
745 | op->arch=find_archetype(yv); |
742 | if (op->arch!=NULL) copy_object(&op->arch->clone,op); |
746 | if (op->arch!=NULL) { |
743 | else if (!arch_init) { |
747 | copy_object(&op->arch->clone,op); |
|
|
748 | } else if (!arch_init) { |
744 | if (op->name) free_string(op->name); |
749 | if (op->name) free_string(op->name); |
745 | /* record the name of the broken object */ |
750 | /* record the name of the broken object */ |
746 | op->name = add_string(yv); |
751 | op->name = add_string(yv); |
747 | } |
752 | } |
748 | } |
753 | } |
… | |
… | |
764 | */ |
769 | */ |
765 | ismore=1; |
770 | ismore=1; |
766 | } |
771 | } |
767 | |
772 | |
768 | ^end{WS}$ { check_loaded_object(op); |
773 | ^end{WS}$ { check_loaded_object(op); |
|
|
774 | |
|
|
775 | if (!arch_init) |
|
|
776 | { |
|
|
777 | thawer.get (op); |
|
|
778 | op->instantiate (); |
|
|
779 | } |
|
|
780 | |
769 | if (ismore) return LL_MORE; |
781 | if (ismore) return LL_MORE; |
770 | else return LL_NORMAL; |
782 | else return LL_NORMAL; |
771 | } |
783 | } |
772 | ^last_heal{S} op->last_heal = IVAL; |
784 | ^last_heal{S} op->last_heal = IVAL; |
773 | ^last_sp{S} op->last_sp = IVAL; |
785 | ^last_sp{S} op->last_sp = IVAL; |
… | |
… | |
1398 | * be reset. |
1410 | * be reset. |
1399 | * LO_NOREAD (3): Reset the buffers, but don't read from it. (op can be null) |
1411 | * LO_NOREAD (3): Reset the buffers, but don't read from it. (op can be null) |
1400 | * |
1412 | * |
1401 | */ |
1413 | */ |
1402 | |
1414 | |
1403 | int load_object(FILE *fp, object *op, int bufstate, int map_flags) { |
1415 | int load_object(FILE *fp, object_thawer &thawer, object *op, int bufstate, int map_flags) { |
1404 | int retval; |
1416 | int retval; |
1405 | char inbuf[MAX_BUF]; |
1417 | char inbuf[MAX_BUF]; |
1406 | |
1418 | |
1407 | strcpy(msgbuf, ""); |
1419 | strcpy(msgbuf, ""); |
1408 | strcpy(lorebuf, ""); |
1420 | strcpy(lorebuf, ""); |
… | |
… | |
1414 | } |
1426 | } |
1415 | if (bufstate==LO_LINEMODE) { |
1427 | if (bufstate==LO_LINEMODE) { |
1416 | YY_BUFFER_STATE yybufstate; |
1428 | YY_BUFFER_STATE yybufstate; |
1417 | while (fgets(inbuf, MAX_BUF-3, fp)) { |
1429 | while (fgets(inbuf, MAX_BUF-3, fp)) { |
1418 | yybufstate=yy_scan_string(inbuf); |
1430 | yybufstate=yy_scan_string(inbuf); |
1419 | retval=lex_load(op, map_flags); |
1431 | retval=lex_load(op, thawer, map_flags); |
1420 | yy_delete_buffer(yybufstate); |
1432 | yy_delete_buffer(yybufstate); |
1421 | if (retval==LL_NORMAL) return retval; |
1433 | if (retval==LL_NORMAL) return retval; |
1422 | } |
1434 | } |
1423 | LOG(llevDebug,"Got eof while scanning strings\n"); |
1435 | LOG(llevDebug,"Got eof while scanning strings\n"); |
1424 | return LL_EOF; |
1436 | return LL_EOF; |
1425 | } |
1437 | } |
1426 | |
1438 | |
1427 | retval=lex_load(op, map_flags); |
1439 | retval=lex_load(op, thawer, map_flags); |
1428 | if (op->current_weapon_script != NULL) |
1440 | if (op->current_weapon_script != NULL) |
1429 | { |
1441 | { |
1430 | op->current_weapon = find_best_weapon_used_match(op, op->current_weapon_script); |
1442 | op->current_weapon = find_best_weapon_used_match(op, op->current_weapon_script); |
1431 | LOG(llevDebug, "CurrentWeapon Loaded !\n"); |
1443 | LOG(llevDebug, "CurrentWeapon Loaded !\n"); |
1432 | }; |
1444 | }; |
… | |
… | |
1443 | * override values and in c_wiz to mutate values. |
1455 | * override values and in c_wiz to mutate values. |
1444 | */ |
1456 | */ |
1445 | int set_variable(object *op,char *buf) { |
1457 | int set_variable(object *op,char *buf) { |
1446 | YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER; |
1458 | YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER; |
1447 | int retval; |
1459 | int retval; |
|
|
1460 | object_thawer thawer; |
1448 | |
1461 | |
1449 | strcpy(msgbuf, ""); |
1462 | strcpy(msgbuf, ""); |
1450 | strcpy(lorebuf, ""); |
1463 | strcpy(lorebuf, ""); |
1451 | yy_push_state(INITIAL); |
1464 | yy_push_state(INITIAL); |
1452 | yybufstate=yy_scan_string(buf); |
1465 | yybufstate=yy_scan_string(buf); |
1453 | retval=lex_load(op,0); |
1466 | retval=lex_load(op,thawer,0); |
1454 | yy_switch_to_buffer(yycurbuf); |
1467 | yy_switch_to_buffer(yycurbuf); |
1455 | yy_delete_buffer(yybufstate); |
1468 | yy_delete_buffer(yybufstate); |
1456 | yy_pop_state(); |
1469 | yy_pop_state(); |
1457 | return retval; |
1470 | return retval; |
1458 | } |
1471 | } |
… | |
… | |
2025 | * the only place this is not set is when saving the player. |
2038 | * the only place this is not set is when saving the player. |
2026 | * If bit 1 of flag is set, don't remove the object after save. As of now, |
2039 | * If bit 1 of flag is set, don't remove the object after save. As of now, |
2027 | * all of the callers are setting this. |
2040 | * all of the callers are setting this. |
2028 | */ |
2041 | */ |
2029 | |
2042 | |
2030 | void save_object(FILE *fp,object *op, int flag) { |
2043 | void save_object(FILE *fp,object_freezer &freezer,object *op, int flag) { |
2031 | archetype *at; |
2044 | archetype *at; |
2032 | char *cp; |
2045 | char *cp; |
2033 | object *tmp,*old; |
2046 | object *tmp,*old; |
2034 | |
2047 | |
2035 | /* Even if the object does have an owner, it would seem that we should |
2048 | /* Even if the object does have an owner, it would seem that we should |
… | |
… | |
2053 | |
2066 | |
2054 | old=NULL; |
2067 | old=NULL; |
2055 | |
2068 | |
2056 | if (flag & 2 ) |
2069 | if (flag & 2 ) |
2057 | for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) |
2070 | for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) |
2058 | save_object(fp,tmp,flag); |
2071 | save_object(fp,freezer,tmp,flag); |
2059 | |
2072 | |
2060 | /* Slightly different logic because tmp/op will be removed by |
2073 | /* Slightly different logic because tmp/op will be removed by |
2061 | * the save_object we call. So we just keep looking at op->inv |
2074 | * the save_object we call. So we just keep looking at op->inv |
2062 | * until there is nothing left. In theory, the variable old |
2075 | * until there is nothing left. In theory, the variable old |
2063 | * should not be needed, as recursive loops shouldn't happen. |
2076 | * should not be needed, as recursive loops shouldn't happen. |
… | |
… | |
2065 | else while ((tmp=op->inv)!=NULL) { |
2078 | else while ((tmp=op->inv)!=NULL) { |
2066 | if(old==tmp) { |
2079 | if(old==tmp) { |
2067 | LOG(llevError," Recursive loop in inventory\n"); |
2080 | LOG(llevError," Recursive loop in inventory\n"); |
2068 | break; |
2081 | break; |
2069 | } |
2082 | } |
2070 | save_object(fp,tmp,flag); |
2083 | save_object(fp,freezer,tmp,flag); |
2071 | old=tmp; |
2084 | old=tmp; |
2072 | } |
2085 | } |
2073 | |
2086 | |
2074 | if (!(flag&2)) { |
2087 | if (!(flag&2)) { |
2075 | remove_ob(op); |
2088 | remove_ob(op); |
2076 | free_object (op); |
2089 | free_object (op); |
2077 | } |
2090 | } |
2078 | |
2091 | |
2079 | fprintf(fp,"end\n"); |
2092 | fprintf(fp,"end\n"); |
|
|
2093 | freezer.put (op); |
2080 | } |
2094 | } |
2081 | |
2095 | |
2082 | void insert_event(object* op, int etype, char *ehook, char *eplug, char *eoptions) |
2096 | void insert_event(object* op, int etype, char *ehook, char *eplug, char *eoptions) |
2083 | { |
2097 | { |
2084 | event *evt; |
2098 | event *evt; |