1 | %{ |
1 | %{ |
2 | /* |
2 | /* |
3 | * static char *rcsid_object_c = |
3 | * static char *rcsid_object_c = |
4 | * "$Id: loader.l,v 1.3 2006/05/11 19:07:40 root Exp $"; |
4 | * "$Id: loader.l,v 1.9 2006/08/26 23:36:29 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 | |
… | |
… | |
40 | #define YY_DECL int lex_load(object *op, int map_flags) |
40 | #define YY_DECL int lex_load(object *op, 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 | |
… | |
… | |
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 | */ |
62 | const char *const spell_mapping[] = { |
62 | const 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 */ |
… | |
… | |
333 | static char *op_debug_info_ (object *op, char *info) |
333 | static char *op_debug_info_ (object *op, char *info) |
334 | { |
334 | { |
335 | char info2[256 * 3]; |
335 | char info2[256 * 3]; |
336 | char *p = info; |
336 | char *p = info; |
337 | |
337 | |
338 | p += snprintf (p, 256, "%s%s%s=%d", |
338 | p += snprintf (p, 256, "%d=\"%s%s%s\"", |
|
|
339 | op->count, |
339 | op->name ? op->name : "(anon)", |
340 | op->name ? op->name : "(anon)", |
340 | op->title ? " " : "", |
341 | op->title ? " " : "", |
341 | op->title ? op->title : "", |
342 | op->title ? op->title : ""); |
342 | op->count); |
|
|
343 | |
343 | |
344 | if (op->env) |
344 | if (op->env) |
345 | p += snprintf (p, 256, "(in %s)", op_debug_info_ (op->env, info2)); |
345 | p += snprintf (p, 256, "(in %s)", op_debug_info_ (op->env, info2)); |
346 | |
346 | |
347 | if (op->map) |
347 | if (op->map) |
348 | p += snprintf (p, 256, "(%d+%d@%s)", op->x, op->y, op->map->path); |
348 | p += snprintf (p, 256, "(on %s@%d+%d)", op->map->path, op->x, op->y); |
349 | |
349 | |
350 | return info; |
350 | return info; |
351 | } |
351 | } |
352 | |
352 | |
353 | static char *op_debug_info (object *op) |
353 | static char *op_debug_info (object *op) |
… | |
… | |
643 | |
643 | |
644 | %} |
644 | %} |
645 | |
645 | |
646 | ^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; } |
646 | ^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; } |
647 | <MESSAGE>^endmsg{WS}$ { BEGIN( INITIAL ); |
647 | <MESSAGE>^endmsg{WS}$ { BEGIN( INITIAL ); |
648 | op->msg=add_string(msgbuf); |
|
|
649 | /* Just print a warning so we can be reasonably safe |
648 | /* Just print a warning so we can be reasonably safe |
650 | * about not overflowing the buffer. |
649 | * about not overflowing the buffer. |
651 | */ |
650 | */ |
652 | if (strlen(op->msg) > (HUGE_BUF/2)) |
651 | if (strlen(msgbuf) >= HUGE_BUF) |
|
|
652 | { |
653 | 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", |
654 | 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); |
655 | } |
659 | } |
656 | <MESSAGE>.* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); } |
660 | <MESSAGE>.* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); } |
657 | |
661 | |
658 | ^lore{WS}$ { BEGIN( LORE ); lorebuf[0]='\0'; } |
662 | ^lore{WS}$ { BEGIN( LORE ); lorebuf[0]='\0'; } |
659 | <LORE>^endlore{WS}$ { BEGIN( INITIAL ); |
663 | <LORE>^endlore{WS}$ { BEGIN( INITIAL ); |
… | |
… | |
689 | ^name_pl{S} { char *yv=yval(); |
693 | ^name_pl{S} { char *yv=yval(); |
690 | |
694 | |
691 | if (*yv=='\0') LOG(llevError,"Name without val\n"); |
695 | if (*yv=='\0') LOG(llevError,"Name without val\n"); |
692 | else FREE_AND_COPY(op->name_pl, yv); |
696 | else FREE_AND_COPY(op->name_pl, yv); |
693 | } |
697 | } |
|
|
698 | ^attach{S} { char *yv=yval(); |
|
|
699 | if (*yv) |
|
|
700 | op->attach = add_string (yv); |
|
|
701 | } |
694 | ^skill{S} FREE_AND_COPY(op->skill,yval()); |
702 | ^skill{S} FREE_AND_COPY(op->skill,yval()); |
695 | ^custom_name{S} { char *yv=yval(); |
703 | ^custom_name{S} { char *yv=yval(); |
696 | |
704 | |
697 | if (*yv=='\0') LOG(llevError,"Custom name without val\n"); |
705 | if (*yv=='\0') LOG(llevError,"Custom name without val\n"); |
698 | else FREE_AND_COPY(op->custom_name, yv); |
706 | else FREE_AND_COPY(op->custom_name, yv); |
… | |
… | |
708 | */ |
716 | */ |
709 | if (op->arch) { |
717 | if (op->arch) { |
710 | object *tmp; |
718 | object *tmp; |
711 | char *yv=yval(); |
719 | char *yv=yval(); |
712 | |
720 | |
713 | tmp=get_object(); |
|
|
714 | tmp->arch = find_archetype(yv); |
721 | archetype *arch = find_archetype(yv); |
715 | if (tmp->arch!=NULL) |
722 | if (arch!=NULL) |
716 | copy_object(&tmp->arch->clone,tmp); |
723 | tmp = arch_to_object (arch); |
717 | else { |
724 | else { |
|
|
725 | tmp = get_object (); |
718 | if (tmp->name) free_string(tmp->name); |
726 | if (tmp->name) free_string(tmp->name); |
719 | /* record the name of the broken object */ |
727 | /* record the name of the broken object */ |
720 | tmp->name = add_string(yv); |
728 | tmp->name = add_string(yv); |
721 | } |
729 | } |
722 | strcpy(msgbuf, ""); |
730 | strcpy(msgbuf, ""); |
… | |
… | |
733 | /* This is the actual archetype definition then */ |
741 | /* This is the actual archetype definition then */ |
734 | else { |
742 | else { |
735 | char *yv=yval(); |
743 | char *yv=yval(); |
736 | |
744 | |
737 | op->arch=find_archetype(yv); |
745 | op->arch=find_archetype(yv); |
738 | if (op->arch!=NULL) copy_object(&op->arch->clone,op); |
746 | if (op->arch!=NULL) { |
739 | else if (!arch_init) { |
747 | copy_object(&op->arch->clone,op); |
|
|
748 | op->instantiate (); |
|
|
749 | } else if (!arch_init) { |
740 | if (op->name) free_string(op->name); |
750 | if (op->name) free_string(op->name); |
741 | /* record the name of the broken object */ |
751 | /* record the name of the broken object */ |
742 | op->name = add_string(yv); |
752 | op->name = add_string(yv); |
743 | } |
753 | } |
744 | } |
754 | } |
… | |
… | |
980 | ^resist_disease{S} SET_RESIST(op, ATNR_DISEASE, IVAL); |
990 | ^resist_disease{S} SET_RESIST(op, ATNR_DISEASE, IVAL); |
981 | |
991 | |
982 | /* Old style resistances */ |
992 | /* Old style resistances */ |
983 | ^immune{S} set_protection(op, IVAL, RESIST_IMMUNE); |
993 | ^immune{S} set_protection(op, IVAL, RESIST_IMMUNE); |
984 | ^protected{S} set_protection(op, IVAL, RESIST_PROT); |
994 | ^protected{S} set_protection(op, IVAL, RESIST_PROT); |
985 | ^vulnerable{S} set_protection(op, IVAL, RESIST_VULN); |
995 | ^vulnerable{S} set_protection(op, IVAL, (uint16) RESIST_VULN); |
986 | |
996 | |
987 | /* old values - keep them around for now, but they should be removed at some point */ |
997 | /* old values - keep them around for now, but they should be removed at some point */ |
988 | ^has_ready_rod{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
998 | ^has_ready_rod{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
989 | ^has_ready_horn{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
999 | ^has_ready_horn{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
990 | ^has_ready_wand{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
1000 | ^has_ready_wand{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
… | |
… | |
1029 | ^can_impale{S} { /* That these are for the new combat code */ } |
1039 | ^can_impale{S} { /* That these are for the new combat code */ } |
1030 | ^can_cut{S} { /* just ignore for now */ } |
1040 | ^can_cut{S} { /* just ignore for now */ } |
1031 | ^can_dam_armour{S} { } |
1041 | ^can_dam_armour{S} { } |
1032 | ^weapontype{S} op->weapontype = IVAL; |
1042 | ^weapontype{S} op->weapontype = IVAL; |
1033 | ^tooltype{S} op->tooltype = IVAL; |
1043 | ^tooltype{S} op->tooltype = IVAL; |
1034 | ^casting_time{S} op->casting_time = FVAL; |
1044 | ^casting_time{S} op->casting_time = (sint16) FVAL; |
1035 | ^elevation{S} op->elevation = IVAL; |
1045 | ^elevation{S} op->elevation = IVAL; |
1036 | ^smoothlevel{S} op->smoothlevel = IVAL; |
1046 | ^smoothlevel{S} op->smoothlevel = IVAL; |
1037 | ^client_type{S} op->client_type = IVAL; |
1047 | ^client_type{S} op->client_type = IVAL; |
1038 | ^body_{A} set_body_info(op, yytext); |
1048 | ^body_{A} set_body_info(op, yytext); |
1039 | ^duration{S} op->duration = IVAL; |
1049 | ^duration{S} op->duration = IVAL; |
… | |
… | |
1643 | * NEVER touch buf between PREPARE_FASTCAT(buf) and |
1653 | * NEVER touch buf between PREPARE_FASTCAT(buf) and |
1644 | * FINISH_FASTCAT(buf) |
1654 | * FINISH_FASTCAT(buf) |
1645 | */ |
1655 | */ |
1646 | static int already_run = 0; |
1656 | static int already_run = 0; |
1647 | static int flag_lens[NUM_FLAGS]; |
1657 | static int flag_lens[NUM_FLAGS]; |
1648 | static char buf2[HUGE_BUF]; |
1658 | char buf2[4096]; // / was HUFE_BUF, which was hugely incorrect, as is this value, but much less so |
1649 | static char buf[HUGE_BUF]; |
1659 | static char buf[128*1024]; // < the assumption is that every object always fits. fixing this bug, however |
1650 | char* fastbuf; |
1660 | char* fastbuf; // \ requires a large rewrite of the code, so its left to the next total rewrite. |
1651 | int tmp; |
1661 | int tmp; |
1652 | int i; |
1662 | int i; |
1653 | #if 0 |
|
|
1654 | /*Memory polluting code. Should help detect problems, very slow*/ |
|
|
1655 | for (i=0;i<HUGE_BUF;i++){ |
|
|
1656 | buf[i]='a'+(unsigned short)(i%25); |
|
|
1657 | } |
|
|
1658 | #endif |
|
|
1659 | event *etmp; |
1663 | event *etmp; |
1660 | event *etmp2; |
1664 | event *etmp2; |
1661 | key_value * my_field; |
1665 | key_value * my_field; |
1662 | key_value * arch_field; |
1666 | key_value * arch_field; |
1663 | |
1667 | |
… | |
… | |
1994 | get_string_move_type(op->move_slow), |
1998 | get_string_move_type(op->move_slow), |
1995 | 10); |
1999 | 10); |
1996 | } |
2000 | } |
1997 | |
2001 | |
1998 | if (op->move_slow_penalty != op2->move_slow_penalty) { |
2002 | if (op->move_slow_penalty != op2->move_slow_penalty) { |
1999 | FAST_SAVE_LONG(fastbuf,"move_slow_penalty ",op->move_slow_penalty,18); |
2003 | FAST_SAVE_LONG(fastbuf,"move_slow_penalty ",(long) op->move_slow_penalty,18); |
2000 | } |
2004 | } |
2001 | |
2005 | |
2002 | if (!COMPARE_FLAGS(op,op2)) { |
2006 | if (!COMPARE_FLAGS(op,op2)) { |
2003 | for (tmp=0; tmp <= NUM_FLAGS; tmp++) { |
2007 | for (tmp=0; tmp <= NUM_FLAGS; tmp++) { |
2004 | if (flag_names[tmp] && (QUERY_FLAG(op, tmp) != QUERY_FLAG(op2, tmp))) { |
2008 | if (flag_names[tmp] && (QUERY_FLAG(op, tmp) != QUERY_FLAG(op2, tmp))) { |