1 | %{ |
1 | %{ |
2 | /* |
2 | /* |
3 | * static char *rcsid_object_c = |
3 | * static char *rcsid_object_c = |
4 | * "$Id: loader.l,v 1.1.1.1 2006/02/03 07:11:36 root Exp $"; |
4 | * "$Id: loader.l,v 1.17 2006/08/31 09:19:33 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 | |
|
|
48 | /* Maps the MOVE_* values to names */ |
|
|
49 | static const char *const move_name[] = {"walk", "fly_low", "fly_high", "swim", "boat", |
|
|
50 | NULL}; |
47 | |
51 | |
48 | /* This table is only necessary to convert objects that existed before the |
52 | /* This table is only necessary to convert objects that existed before the |
49 | * spell object conversion to the new object. It was not practical |
53 | * spell object conversion to the new object. It was not practical |
50 | * to go through every mapping looking for every potion, rod, wand, etc |
54 | * to go through every mapping looking for every potion, rod, wand, etc |
51 | * that had a sp set and update to the new value. So this maps the |
55 | * that had a sp set and update to the new value. So this maps the |
… | |
… | |
53 | * 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 |
54 | * 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. |
55 | * 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 |
56 | * not be updated for whatever reason. |
60 | * not be updated for whatever reason. |
57 | */ |
61 | */ |
58 | char *spell_mapping[] = { |
62 | const char *spell_mapping[] = { |
59 | "spell_magic_bullet", /* 0 */ |
63 | "spell_magic_bullet", /* 0 */ |
60 | "spell_small_fireball", /* 1 */ |
64 | "spell_small_fireball", /* 1 */ |
61 | "spell_medium_fireball", /* 2 */ |
65 | "spell_medium_fireball", /* 2 */ |
62 | "spell_large_fireball", /* 3 */ |
66 | "spell_large_fireball", /* 3 */ |
63 | "spell_burning_hands", /* 4 */ |
67 | "spell_burning_hands", /* 4 */ |
… | |
… | |
321 | } |
325 | } |
322 | } |
326 | } |
323 | 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); |
324 | } |
328 | } |
325 | |
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. |
|
|
333 | static 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 | |
|
|
353 | static char *op_debug_info (object *op) |
|
|
354 | { |
|
|
355 | static char info[256 * 3]; |
|
|
356 | |
|
|
357 | return op_debug_info_ (op, info); |
|
|
358 | } |
326 | |
359 | |
327 | /* 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 |
328 | * 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 |
329 | * 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 |
330 | * 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. |
… | |
… | |
359 | * really just to catch any errors - program will still run, but |
392 | * really just to catch any errors - program will still run, but |
360 | * not in the ideal fashion. |
393 | * not in the ideal fashion. |
361 | */ |
394 | */ |
362 | if ((op->type == WEAPON || op->type==BOW) && arch_init) { |
395 | if ((op->type == WEAPON || op->type==BOW) && arch_init) { |
363 | if (!op->skill) { |
396 | if (!op->skill) { |
364 | LOG(llevError,"Weapon %s lacks a skill.\n", op->name); |
397 | LOG(llevError,"Weapon %s lacks a skill.\n", op_debug_info (op)); |
365 | } 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) || |
366 | (!strcmp(op->skill,"two handed weapons") && op->body_info[1] != -2)) { |
399 | (!strcmp(op->skill,"two handed weapons") && op->body_info[1] != -2)) { |
367 | 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", |
368 | op->name, op->body_info[1], op->skill); |
401 | op_debug_info (op), op->body_info[1], op->skill); |
369 | } |
402 | } |
370 | } |
403 | } |
371 | |
404 | |
372 | /* 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 |
373 | * really does for many objects. Need to catch any in maps |
406 | * really does for many objects. Need to catch any in maps |
… | |
… | |
378 | (op->type == SHIELD) || (op->type == RING) || |
411 | (op->type == SHIELD) || (op->type == RING) || |
379 | (op->type == BOOTS) || (op->type == GLOVES) || |
412 | (op->type == BOOTS) || (op->type == GLOVES) || |
380 | (op->type == AMULET ) || (op->type == GIRDLE) || |
413 | (op->type == AMULET ) || (op->type == GIRDLE) || |
381 | (op->type == BRACERS ) || (op->type == CLOAK)) { |
414 | (op->type == BRACERS ) || (op->type == CLOAK)) { |
382 | if (op->last_heal) { |
415 | if (op->last_heal) { |
383 | 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)); |
384 | op->name?op->name:"NULL"); |
|
|
385 | op->gen_sp_armour = op->last_heal; |
417 | op->gen_sp_armour = op->last_heal; |
386 | op->last_heal = 0; |
418 | op->last_heal = 0; |
387 | } |
419 | } |
388 | if (editor) ip =0; |
420 | if (editor) ip =0; |
389 | else ip = calc_item_power(op, 0); |
421 | else ip = calc_item_power(op, 0); |
390 | /* Legacy objects from before item power was in the game */ |
422 | /* Legacy objects from before item power was in the game */ |
391 | if (!op->item_power && ip) { |
423 | if (!op->item_power && ip) { |
392 | if (ip > 3) { |
424 | if (ip > 3) { |
393 | 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); |
394 | op->name?op->name:"NULL", ip); |
|
|
395 | } |
426 | } |
396 | op->item_power = ip; |
427 | op->item_power = ip; |
397 | } |
428 | } |
398 | /* Check for possibly bogus values. Has to meet both these criteria - |
429 | /* Check for possibly bogus values. Has to meet both these criteria - |
399 | * 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 |
… | |
… | |
401 | * 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, |
402 | * but not the second one. |
433 | * but not the second one. |
403 | */ |
434 | */ |
404 | if (ip > 2 *op->item_power && ip > (op->item_power + 3)) { |
435 | if (ip > 2 *op->item_power && ip > (op->item_power + 3)) { |
405 | 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", |
406 | op->name?op->name:"NULL", ip, op->item_power); |
437 | op_debug_info (op), ip, op->item_power); |
407 | } |
438 | } |
408 | |
439 | |
409 | } |
440 | } |
410 | /* Old spellcasting object - need to load in the appropiate object */ |
441 | /* Old spellcasting object - need to load in the appropiate object */ |
411 | 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 |
… | |
… | |
434 | } |
465 | } |
435 | |
466 | |
436 | if (QUERY_FLAG(op, FLAG_MONSTER)) { |
467 | if (QUERY_FLAG(op, FLAG_MONSTER)) { |
437 | if (op->stats.hp > op->stats.maxhp) |
468 | if (op->stats.hp > op->stats.maxhp) |
438 | 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", |
439 | op->name, |
470 | op_debug_info (op), |
440 | op->stats.hp, op->stats.maxhp); |
471 | op->stats.hp, op->stats.maxhp); |
441 | |
472 | |
442 | /* The archs just need to be updated for this */ |
473 | /* The archs just need to be updated for this */ |
443 | if (op->move_type ==0) op->move_type = MOVE_WALK; |
474 | if (op->move_type ==0) op->move_type = MOVE_WALK; |
444 | } |
475 | } |
… | |
… | |
535 | *end='\0'; |
566 | *end='\0'; |
536 | } |
567 | } |
537 | set_ob_key_value(op, key, value, TRUE); |
568 | set_ob_key_value(op, key, value, TRUE); |
538 | } |
569 | } |
539 | |
570 | |
|
|
571 | static void set_move(MoveType *mt, char *params) { |
|
|
572 | char *str; |
|
|
573 | int i, negate; |
|
|
574 | |
|
|
575 | if (isdigit(*params)) { |
|
|
576 | *mt = atoi(params); |
|
|
577 | } else { |
|
|
578 | *mt=0; |
|
|
579 | for (str=strtok(params, " "); str; str=strtok(NULL, " ")) { |
|
|
580 | negate=0; |
|
|
581 | if (!strcasecmp(str, "all")) |
|
|
582 | *mt |= MOVE_ALL; |
|
|
583 | else { |
|
|
584 | if (*str=='-') { |
|
|
585 | negate = 1; |
|
|
586 | str++; |
|
|
587 | } |
|
|
588 | for (i=0; move_name[i] != NULL; i++) { |
|
|
589 | if (!strcasecmp(move_name[i], str)) { |
|
|
590 | if (negate) { |
|
|
591 | *mt &= ~(1<<i); |
|
|
592 | } else { |
|
|
593 | *mt |= (1<<i); |
|
|
594 | } |
|
|
595 | break; |
|
|
596 | } |
|
|
597 | } |
|
|
598 | if (move_name[i] == NULL) { |
|
|
599 | /* fly is a special case - covers both fly_low and |
|
|
600 | * fly_high - since it doesn't match to a specific |
|
|
601 | * single bit, have to special case it. |
|
|
602 | */ |
|
|
603 | if (!strcasecmp(str,"flying")) { |
|
|
604 | if (negate) { |
|
|
605 | *mt &= ~MOVE_FLYING; |
|
|
606 | } else { |
|
|
607 | *mt |= MOVE_FLYING; |
|
|
608 | } |
|
|
609 | } else { |
|
|
610 | LOG(llevDebug, "common/loader.l: set_move - unknown move string '%s'\n", str); |
|
|
611 | } |
|
|
612 | } |
|
|
613 | } /* Else not all move types */ |
|
|
614 | } /* for strtok */ |
|
|
615 | } /* Else not a numeric value */ |
|
|
616 | } |
540 | |
617 | |
541 | %} |
618 | %} |
542 | |
619 | |
543 | |
620 | |
544 | |
621 | |
… | |
… | |
566 | |
643 | |
567 | %} |
644 | %} |
568 | |
645 | |
569 | ^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; } |
646 | ^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; } |
570 | <MESSAGE>^endmsg{WS}$ { BEGIN( INITIAL ); |
647 | <MESSAGE>^endmsg{WS}$ { BEGIN( INITIAL ); |
571 | op->msg=add_string(msgbuf); |
|
|
572 | /* Just print a warning so we can be reasonably safe |
648 | /* Just print a warning so we can be reasonably safe |
573 | * about not overflowing the buffer. |
649 | * about not overflowing the buffer. |
574 | */ |
650 | */ |
575 | if (strlen(op->msg) > (HUGE_BUF/2)) |
651 | if (strlen(msgbuf) >= HUGE_BUF) |
|
|
652 | { |
576 | 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", |
577 | 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); |
578 | } |
659 | } |
579 | <MESSAGE>.* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); } |
660 | <MESSAGE>.* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); } |
580 | |
661 | |
581 | ^lore{WS}$ { BEGIN( LORE ); lorebuf[0]='\0'; } |
662 | ^lore{WS}$ { BEGIN( LORE ); lorebuf[0]='\0'; } |
582 | <LORE>^endlore{WS}$ { BEGIN( INITIAL ); |
663 | <LORE>^endlore{WS}$ { BEGIN( INITIAL ); |
… | |
… | |
612 | ^name_pl{S} { char *yv=yval(); |
693 | ^name_pl{S} { char *yv=yval(); |
613 | |
694 | |
614 | if (*yv=='\0') LOG(llevError,"Name without val\n"); |
695 | if (*yv=='\0') LOG(llevError,"Name without val\n"); |
615 | else FREE_AND_COPY(op->name_pl, yv); |
696 | else FREE_AND_COPY(op->name_pl, yv); |
616 | } |
697 | } |
|
|
698 | ^attach{S} { char *yv=yval(); |
|
|
699 | if (*yv) |
|
|
700 | op->attach = add_string (yv); |
|
|
701 | } |
617 | ^skill{S} FREE_AND_COPY(op->skill,yval()); |
702 | ^skill{S} FREE_AND_COPY(op->skill,yval()); |
618 | ^custom_name{S} { char *yv=yval(); |
703 | ^custom_name{S} { char *yv=yval(); |
619 | |
704 | |
620 | if (*yv=='\0') LOG(llevError,"Custom name without val\n"); |
705 | if (*yv=='\0') LOG(llevError,"Custom name without val\n"); |
621 | else FREE_AND_COPY(op->custom_name, yv); |
706 | else FREE_AND_COPY(op->custom_name, yv); |
… | |
… | |
631 | */ |
716 | */ |
632 | if (op->arch) { |
717 | if (op->arch) { |
633 | object *tmp; |
718 | object *tmp; |
634 | char *yv=yval(); |
719 | char *yv=yval(); |
635 | |
720 | |
636 | tmp=get_object(); |
|
|
637 | tmp->arch = find_archetype(yv); |
721 | archetype *arch = find_archetype(yv); |
638 | if (tmp->arch!=NULL) |
722 | if (arch!=NULL) |
639 | copy_object(&tmp->arch->clone,tmp); |
723 | tmp = arch_to_object (arch); |
640 | else { |
724 | else { |
|
|
725 | tmp = get_object (); |
641 | if (tmp->name) free_string(tmp->name); |
726 | if (tmp->name) free_string(tmp->name); |
642 | /* record the name of the broken object */ |
727 | /* record the name of the broken object */ |
643 | tmp->name = add_string(yv); |
728 | tmp->name = add_string(yv); |
644 | } |
729 | } |
645 | strcpy(msgbuf, ""); |
730 | strcpy(msgbuf, ""); |
646 | strcpy(lorebuf, ""); |
731 | strcpy(lorebuf, ""); |
647 | lex_load(tmp, map_flags); |
732 | lex_load(tmp, thawer, map_flags); |
648 | if (tmp->arch) { |
733 | if (tmp->arch) { |
649 | insert_ob_in_ob(tmp,op); |
734 | insert_ob_in_ob(tmp,op); |
650 | } |
735 | } |
651 | else { |
736 | else { |
652 | 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)"); |
… | |
… | |
656 | /* This is the actual archetype definition then */ |
741 | /* This is the actual archetype definition then */ |
657 | else { |
742 | else { |
658 | char *yv=yval(); |
743 | char *yv=yval(); |
659 | |
744 | |
660 | op->arch=find_archetype(yv); |
745 | op->arch=find_archetype(yv); |
661 | if (op->arch!=NULL) copy_object(&op->arch->clone,op); |
746 | if (op->arch!=NULL) { |
662 | else if (!arch_init) { |
747 | copy_object(&op->arch->clone,op); |
|
|
748 | } else if (!arch_init) { |
663 | if (op->name) free_string(op->name); |
749 | if (op->name) free_string(op->name); |
664 | /* record the name of the broken object */ |
750 | /* record the name of the broken object */ |
665 | op->name = add_string(yv); |
751 | op->name = add_string(yv); |
666 | } |
752 | } |
667 | } |
753 | } |
… | |
… | |
681 | ^more{WS}$ { /* We need to record that this is a multipart object, |
767 | ^more{WS}$ { /* We need to record that this is a multipart object, |
682 | * so the calling function can glue things back together |
768 | * so the calling function can glue things back together |
683 | */ |
769 | */ |
684 | ismore=1; |
770 | ismore=1; |
685 | } |
771 | } |
686 | |
|
|
687 | ^end{WS}$ { check_loaded_object(op); |
772 | ^end{WS}$ { check_loaded_object(op); |
|
|
773 | |
|
|
774 | if (!arch_init) |
|
|
775 | op->instantiate (); |
|
|
776 | |
688 | if (ismore) return LL_MORE; |
777 | if (ismore) return LL_MORE; |
689 | else return LL_NORMAL; |
778 | else return LL_NORMAL; |
690 | } |
779 | } |
|
|
780 | ^oid{S} { |
|
|
781 | thawer.get (op, IVAL); |
|
|
782 | } |
691 | ^last_heal{S} op->last_heal = IVAL; |
783 | ^last_heal{S} op->last_heal = IVAL; |
692 | ^last_sp{S} op->last_sp = IVAL; |
784 | ^last_sp{S} op->last_sp = IVAL; |
693 | ^last_grace{S} op->last_grace = IVAL; |
785 | ^last_grace{S} op->last_grace = IVAL; |
694 | ^last_eat{S} op->last_eat = IVAL; |
786 | ^last_eat{S} op->last_eat = IVAL; |
695 | ^speed{S} { op->speed = FVAL; |
787 | ^speed{S} { op->speed = FVAL; |
… | |
… | |
769 | ^fly_off{S} { if (IVAL) op->move_off |= MOVE_FLY_LOW; else op->move_off &= ~MOVE_FLY_LOW; } |
861 | ^fly_off{S} { if (IVAL) op->move_off |= MOVE_FLY_LOW; else op->move_off &= ~MOVE_FLY_LOW; } |
770 | ^flying{S} { if (IVAL) op->move_type |= MOVE_FLY_LOW; else op->move_type &= ~MOVE_FLY_LOW; } |
862 | ^flying{S} { if (IVAL) op->move_type |= MOVE_FLY_LOW; else op->move_type &= ~MOVE_FLY_LOW; } |
771 | |
863 | |
772 | %{ /* These are the new values */ |
864 | %{ /* These are the new values */ |
773 | %} |
865 | %} |
774 | ^move_block{S} op->move_block = IVAL; |
866 | ^move_block{S} set_move(&op->move_block, yval()); |
775 | ^move_type{S} op->move_type = IVAL; |
867 | ^move_allow{S} set_move(&op->move_allow, yval()); |
776 | ^move_on{S} op->move_on = IVAL; |
868 | ^move_type{S} set_move(&op->move_type, yval()); |
777 | ^move_off{S} op->move_off = IVAL; |
869 | ^move_on{S} set_move(&op->move_on, yval()); |
778 | ^move_slow{S} op->move_slow = IVAL; |
870 | ^move_off{S} set_move(&op->move_off, yval()); |
|
|
871 | ^move_slow{S} set_move(&op->move_slow, yval()); |
779 | ^move_slow_penalty{S} op->move_slow_penalty = FVAL; |
872 | ^move_slow_penalty{S} op->move_slow_penalty = FVAL; |
780 | |
873 | |
781 | |
874 | |
782 | ^monster{S} SET_OR_CLEAR_FLAG(op, FLAG_MONSTER, IVAL); |
875 | ^monster{S} SET_OR_CLEAR_FLAG(op, FLAG_MONSTER, IVAL); |
783 | ^neutral{S} SET_OR_CLEAR_FLAG(op, FLAG_NEUTRAL, IVAL); |
876 | ^neutral{S} SET_OR_CLEAR_FLAG(op, FLAG_NEUTRAL, IVAL); |
784 | ^no_attack{S} SET_OR_CLEAR_FLAG(op, FLAG_NO_ATTACK, IVAL); |
877 | ^no_attack{S} SET_OR_CLEAR_FLAG(op, FLAG_NO_ATTACK, IVAL); |
785 | ^no_damage{S} SET_OR_CLEAR_FLAG(op, FLAG_NO_DAMAGE, IVAL); |
878 | ^no_damage{S} SET_OR_CLEAR_FLAG(op, FLAG_NO_DAMAGE, IVAL); |
786 | ^friendly{S} { if (IVAL) { |
879 | ^friendly{S} { if (IVAL) { |
787 | SET_FLAG(op, FLAG_FRIENDLY); |
880 | SET_FLAG(op, FLAG_FRIENDLY); |
788 | if (op->type != PLAYER) { |
881 | if (op->type != PLAYER) |
789 | LOG(llevDebug," Adding friendly object %s.\n",op->name); |
|
|
790 | add_friendly_object(op); |
882 | add_friendly_object (op); |
791 | } |
|
|
792 | } |
883 | } |
793 | else CLEAR_FLAG(op, FLAG_FRIENDLY); |
884 | else CLEAR_FLAG(op, FLAG_FRIENDLY); |
794 | } |
885 | } |
795 | ^generator{S} SET_OR_CLEAR_FLAG(op, FLAG_GENERATOR, IVAL); |
886 | ^generator{S} SET_OR_CLEAR_FLAG(op, FLAG_GENERATOR, IVAL); |
796 | ^use_content_on_gen{S} SET_OR_CLEAR_FLAG (op,FLAG_CONTENT_ON_GEN, IVAL); |
887 | ^use_content_on_gen{S} SET_OR_CLEAR_FLAG (op,FLAG_CONTENT_ON_GEN, IVAL); |
… | |
… | |
904 | ^resist_disease{S} SET_RESIST(op, ATNR_DISEASE, IVAL); |
995 | ^resist_disease{S} SET_RESIST(op, ATNR_DISEASE, IVAL); |
905 | |
996 | |
906 | /* Old style resistances */ |
997 | /* Old style resistances */ |
907 | ^immune{S} set_protection(op, IVAL, RESIST_IMMUNE); |
998 | ^immune{S} set_protection(op, IVAL, RESIST_IMMUNE); |
908 | ^protected{S} set_protection(op, IVAL, RESIST_PROT); |
999 | ^protected{S} set_protection(op, IVAL, RESIST_PROT); |
909 | ^vulnerable{S} set_protection(op, IVAL, RESIST_VULN); |
1000 | ^vulnerable{S} set_protection(op, IVAL, (uint16) RESIST_VULN); |
910 | |
1001 | |
911 | /* old values - keep them around for now, but they should be removed at some point */ |
1002 | /* old values - keep them around for now, but they should be removed at some point */ |
912 | ^has_ready_rod{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
1003 | ^has_ready_rod{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
913 | ^has_ready_horn{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
1004 | ^has_ready_horn{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
914 | ^has_ready_wand{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
1005 | ^has_ready_wand{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); |
… | |
… | |
953 | ^can_impale{S} { /* That these are for the new combat code */ } |
1044 | ^can_impale{S} { /* That these are for the new combat code */ } |
954 | ^can_cut{S} { /* just ignore for now */ } |
1045 | ^can_cut{S} { /* just ignore for now */ } |
955 | ^can_dam_armour{S} { } |
1046 | ^can_dam_armour{S} { } |
956 | ^weapontype{S} op->weapontype = IVAL; |
1047 | ^weapontype{S} op->weapontype = IVAL; |
957 | ^tooltype{S} op->tooltype = IVAL; |
1048 | ^tooltype{S} op->tooltype = IVAL; |
958 | ^casting_time{S} op->casting_time = FVAL; |
1049 | ^casting_time{S} op->casting_time = (sint16) FVAL; |
959 | ^elevation{S} op->elevation = IVAL; |
1050 | ^elevation{S} op->elevation = IVAL; |
960 | ^smoothlevel{S} op->smoothlevel = IVAL; |
1051 | ^smoothlevel{S} op->smoothlevel = IVAL; |
961 | ^client_type{S} op->client_type = IVAL; |
1052 | ^client_type{S} op->client_type = IVAL; |
962 | ^body_{A} set_body_info(op, yytext); |
1053 | ^body_{A} set_body_info(op, yytext); |
963 | ^duration{S} op->duration = IVAL; |
1054 | ^duration{S} op->duration = IVAL; |
… | |
… | |
965 | ^range_modifier{S} op->range_modifier = IVAL; |
1056 | ^range_modifier{S} op->range_modifier = IVAL; |
966 | ^dam_modifier{S} op->dam_modifier = IVAL; |
1057 | ^dam_modifier{S} op->dam_modifier = IVAL; |
967 | ^duration_modifier{S} op->duration_modifier = IVAL; |
1058 | ^duration_modifier{S} op->duration_modifier = IVAL; |
968 | ^is_buildable{S} SET_OR_CLEAR_FLAG( op, FLAG_IS_BUILDABLE, IVAL ); |
1059 | ^is_buildable{S} SET_OR_CLEAR_FLAG( op, FLAG_IS_BUILDABLE, IVAL ); |
969 | |
1060 | |
970 | ^event_apply{S} { |
1061 | ^event_ { |
971 | char *yv=yval(); |
1062 | LOG (llevError, "stray event_* in map file, skipping."); |
972 | if (*yv=='\0') |
|
|
973 | LOG(llevError,"Event (apply) without val\n"); |
|
|
974 | else |
|
|
975 | insert_event(op,EVENT_APPLY,yv,NULL,NULL); |
|
|
976 | } |
1063 | } |
977 | |
|
|
978 | ^event_apply_plugin{S} { |
|
|
979 | char *yv=yval(); |
|
|
980 | if (*yv=='\0') |
|
|
981 | LOG(llevError,"Event (apply) without plugin\n"); |
|
|
982 | else |
|
|
983 | insert_event(op,EVENT_APPLY,NULL,yv,NULL); |
|
|
984 | } |
|
|
985 | |
|
|
986 | ^event_apply_options{S} { |
|
|
987 | char *yv=yval(); |
|
|
988 | if (*yv=='\0') |
|
|
989 | LOG(llevError,"Event (apply) without options\n"); |
|
|
990 | else |
|
|
991 | insert_event(op,EVENT_APPLY,NULL,NULL,yv); |
|
|
992 | } |
|
|
993 | |
|
|
994 | ^event_attack{S} { |
|
|
995 | char *yv=yval(); |
|
|
996 | if (*yv=='\0') |
|
|
997 | LOG(llevError,"Event (attack) without val\n"); |
|
|
998 | else |
|
|
999 | insert_event(op,EVENT_ATTACK,yv,NULL,NULL); |
|
|
1000 | } |
|
|
1001 | |
|
|
1002 | ^event_attack_plugin{S} { |
|
|
1003 | char *yv=yval(); |
|
|
1004 | if (*yv=='\0') |
|
|
1005 | LOG(llevError,"Event (attack) without plugin\n"); |
|
|
1006 | else |
|
|
1007 | insert_event(op,EVENT_ATTACK,NULL,yv,NULL); |
|
|
1008 | } |
|
|
1009 | |
|
|
1010 | ^event_attack_options{S} { |
|
|
1011 | char *yv=yval(); |
|
|
1012 | if (*yv=='\0') |
|
|
1013 | LOG(llevError,"Event (attack) without options\n"); |
|
|
1014 | else |
|
|
1015 | insert_event(op,EVENT_ATTACK,NULL,NULL,yv); |
|
|
1016 | } |
|
|
1017 | ^event_death{S} { |
|
|
1018 | char *yv=yval(); |
|
|
1019 | if (*yv=='\0') |
|
|
1020 | LOG(llevError,"Event (death) without val\n"); |
|
|
1021 | else |
|
|
1022 | insert_event(op,EVENT_DEATH,yv,NULL,NULL); |
|
|
1023 | } |
|
|
1024 | |
|
|
1025 | ^event_death_plugin{S} { |
|
|
1026 | char *yv=yval(); |
|
|
1027 | if (*yv=='\0') |
|
|
1028 | LOG(llevError,"Event (death) without plugin\n"); |
|
|
1029 | else |
|
|
1030 | insert_event(op,EVENT_DEATH,NULL,yv,NULL); |
|
|
1031 | } |
|
|
1032 | |
|
|
1033 | ^event_death_options{S} { |
|
|
1034 | char *yv=yval(); |
|
|
1035 | if (*yv=='\0') |
|
|
1036 | LOG(llevError,"Event (death) without options\n"); |
|
|
1037 | else |
|
|
1038 | insert_event(op,EVENT_DEATH,NULL,NULL,yv); |
|
|
1039 | } |
|
|
1040 | ^event_drop{S} { |
|
|
1041 | char *yv=yval(); |
|
|
1042 | if (*yv=='\0') |
|
|
1043 | LOG(llevError,"Event (drop) without val\n"); |
|
|
1044 | else |
|
|
1045 | insert_event(op,EVENT_DROP,yv,NULL,NULL); |
|
|
1046 | } |
|
|
1047 | |
|
|
1048 | ^event_drop_plugin{S} { |
|
|
1049 | char *yv=yval(); |
|
|
1050 | if (*yv=='\0') |
|
|
1051 | LOG(llevError,"Event (drop) without plugin\n"); |
|
|
1052 | else |
|
|
1053 | insert_event(op,EVENT_DROP,NULL,yv,NULL); |
|
|
1054 | } |
|
|
1055 | |
|
|
1056 | ^event_drop_options{S} { |
|
|
1057 | char *yv=yval(); |
|
|
1058 | if (*yv=='\0') |
|
|
1059 | LOG(llevError,"Event (drop) without options\n"); |
|
|
1060 | else |
|
|
1061 | insert_event(op,EVENT_DROP,NULL,NULL,yv); |
|
|
1062 | } |
|
|
1063 | ^event_pickup{S} { |
|
|
1064 | char *yv=yval(); |
|
|
1065 | if (*yv=='\0') |
|
|
1066 | LOG(llevError,"Event (pickup) without val\n"); |
|
|
1067 | else |
|
|
1068 | insert_event(op,EVENT_PICKUP,yv,NULL,NULL); |
|
|
1069 | } |
|
|
1070 | |
|
|
1071 | ^event_pickup_plugin{S} { |
|
|
1072 | char *yv=yval(); |
|
|
1073 | if (*yv=='\0') |
|
|
1074 | LOG(llevError,"Event (pickup) without plugin\n"); |
|
|
1075 | else |
|
|
1076 | insert_event(op,EVENT_PICKUP,NULL,yv,NULL); |
|
|
1077 | } |
|
|
1078 | |
|
|
1079 | ^event_pickup_options{S} { |
|
|
1080 | char *yv=yval(); |
|
|
1081 | if (*yv=='\0') |
|
|
1082 | LOG(llevError,"Event (pickup) without options\n"); |
|
|
1083 | else |
|
|
1084 | insert_event(op,EVENT_PICKUP,NULL,NULL,yv); |
|
|
1085 | } |
|
|
1086 | ^event_say{S} { |
|
|
1087 | char *yv=yval(); |
|
|
1088 | if (*yv=='\0') |
|
|
1089 | LOG(llevError,"Event (say) without val\n"); |
|
|
1090 | else |
|
|
1091 | insert_event(op,EVENT_SAY,yv,NULL,NULL); |
|
|
1092 | } |
|
|
1093 | |
|
|
1094 | ^event_say_plugin{S} { |
|
|
1095 | char *yv=yval(); |
|
|
1096 | if (*yv=='\0') |
|
|
1097 | LOG(llevError,"Event (say) without plugin\n"); |
|
|
1098 | else |
|
|
1099 | insert_event(op,EVENT_SAY,NULL,yv,NULL); |
|
|
1100 | } |
|
|
1101 | |
|
|
1102 | ^event_say_options{S} { |
|
|
1103 | char *yv=yval(); |
|
|
1104 | if (*yv=='\0') |
|
|
1105 | LOG(llevError,"Event (say) without options\n"); |
|
|
1106 | else |
|
|
1107 | insert_event(op,EVENT_SAY,NULL,NULL,yv); |
|
|
1108 | } |
|
|
1109 | ^event_stop{S} { |
|
|
1110 | char *yv=yval(); |
|
|
1111 | if (*yv=='\0') |
|
|
1112 | LOG(llevError,"Event (stop) without val\n"); |
|
|
1113 | else |
|
|
1114 | insert_event(op,EVENT_STOP,yv,NULL,NULL); |
|
|
1115 | } |
|
|
1116 | |
|
|
1117 | ^event_stop_plugin{S} { |
|
|
1118 | char *yv=yval(); |
|
|
1119 | if (*yv=='\0') |
|
|
1120 | LOG(llevError,"Event (stop) without plugin\n"); |
|
|
1121 | else |
|
|
1122 | insert_event(op,EVENT_STOP,NULL,yv,NULL); |
|
|
1123 | } |
|
|
1124 | |
|
|
1125 | ^event_stop_options{S} { |
|
|
1126 | char *yv=yval(); |
|
|
1127 | if (*yv=='\0') |
|
|
1128 | LOG(llevError,"Event (stop) without options\n"); |
|
|
1129 | else |
|
|
1130 | insert_event(op,EVENT_STOP,NULL,NULL,yv); |
|
|
1131 | } |
|
|
1132 | ^event_time{S} { |
|
|
1133 | char *yv=yval(); |
|
|
1134 | if (*yv=='\0') |
|
|
1135 | LOG(llevError,"Event (time) without val\n"); |
|
|
1136 | else |
|
|
1137 | insert_event(op,EVENT_TIME,yv,NULL,NULL); |
|
|
1138 | } |
|
|
1139 | |
|
|
1140 | ^event_time_plugin{S} { |
|
|
1141 | char *yv=yval(); |
|
|
1142 | if (*yv=='\0') |
|
|
1143 | LOG(llevError,"Event (time) without plugin\n"); |
|
|
1144 | else |
|
|
1145 | insert_event(op,EVENT_TIME,NULL,yv,NULL); |
|
|
1146 | } |
|
|
1147 | |
|
|
1148 | ^event_time_options{S} { |
|
|
1149 | char *yv=yval(); |
|
|
1150 | if (*yv=='\0') |
|
|
1151 | LOG(llevError,"Event (time) without options\n"); |
|
|
1152 | else |
|
|
1153 | insert_event(op,EVENT_TIME,NULL,NULL,yv); |
|
|
1154 | } |
|
|
1155 | ^event_throw{S} { |
|
|
1156 | char *yv=yval(); |
|
|
1157 | if (*yv=='\0') |
|
|
1158 | LOG(llevError,"Event (throw) without val\n"); |
|
|
1159 | else |
|
|
1160 | insert_event(op,EVENT_THROW,yv,NULL,NULL); |
|
|
1161 | } |
|
|
1162 | |
|
|
1163 | ^event_throw_plugin{S} { |
|
|
1164 | char *yv=yval(); |
|
|
1165 | if (*yv=='\0') |
|
|
1166 | LOG(llevError,"Event (throw) without plugin\n"); |
|
|
1167 | else |
|
|
1168 | insert_event(op,EVENT_THROW,NULL,yv,NULL); |
|
|
1169 | } |
|
|
1170 | |
|
|
1171 | ^event_throw_options{S} { |
|
|
1172 | char *yv=yval(); |
|
|
1173 | if (*yv=='\0') |
|
|
1174 | LOG(llevError,"Event (apply) without options\n"); |
|
|
1175 | else |
|
|
1176 | insert_event(op,EVENT_THROW,NULL,NULL,yv); |
|
|
1177 | } |
|
|
1178 | ^event_trigger{S} { |
|
|
1179 | char *yv=yval(); |
|
|
1180 | if (*yv=='\0') |
|
|
1181 | LOG(llevError,"Event (trigger) without val\n"); |
|
|
1182 | else |
|
|
1183 | insert_event(op,EVENT_TRIGGER,yv,NULL,NULL); |
|
|
1184 | } |
|
|
1185 | |
|
|
1186 | ^event_trigger_plugin{S} { |
|
|
1187 | char *yv=yval(); |
|
|
1188 | if (*yv=='\0') |
|
|
1189 | LOG(llevError,"Event (trigger) without plugin\n"); |
|
|
1190 | else |
|
|
1191 | insert_event(op,EVENT_TRIGGER,NULL,yv,NULL); |
|
|
1192 | } |
|
|
1193 | |
|
|
1194 | ^event_trigger_options{S} { |
|
|
1195 | char *yv=yval(); |
|
|
1196 | if (*yv=='\0') |
|
|
1197 | LOG(llevError,"Event (trigger) without options\n"); |
|
|
1198 | else |
|
|
1199 | insert_event(op,EVENT_TRIGGER,NULL,NULL,yv); |
|
|
1200 | } |
|
|
1201 | ^event_close{S} { |
|
|
1202 | char *yv=yval(); |
|
|
1203 | if (*yv=='\0') |
|
|
1204 | LOG(llevError,"Event (close) without val\n"); |
|
|
1205 | else |
|
|
1206 | insert_event(op,EVENT_CLOSE,yv,NULL,NULL); |
|
|
1207 | } |
|
|
1208 | |
|
|
1209 | ^event_close_plugin{S} { |
|
|
1210 | char *yv=yval(); |
|
|
1211 | if (*yv=='\0') |
|
|
1212 | LOG(llevError,"Event (close) without plugin\n"); |
|
|
1213 | else |
|
|
1214 | insert_event(op,EVENT_CLOSE,NULL,yv,NULL); |
|
|
1215 | } |
|
|
1216 | |
|
|
1217 | ^event_close_options{S} { |
|
|
1218 | char *yv=yval(); |
|
|
1219 | if (*yv=='\0') |
|
|
1220 | LOG(llevError,"Event (close) without options\n"); |
|
|
1221 | else |
|
|
1222 | insert_event(op,EVENT_CLOSE,NULL,NULL,yv); |
|
|
1223 | } |
|
|
1224 | ^event_timer{S} { |
|
|
1225 | char *yv=yval(); |
|
|
1226 | if (*yv=='\0') |
|
|
1227 | LOG(llevError,"Event (timer) without val\n"); |
|
|
1228 | else |
|
|
1229 | insert_event(op,EVENT_TIMER,yv,NULL,NULL); |
|
|
1230 | } |
|
|
1231 | |
|
|
1232 | ^event_timer_plugin{S} { |
|
|
1233 | char *yv=yval(); |
|
|
1234 | if (*yv=='\0') |
|
|
1235 | LOG(llevError,"Event (timer) without plugin\n"); |
|
|
1236 | else |
|
|
1237 | insert_event(op,EVENT_TIMER,NULL,yv,NULL); |
|
|
1238 | } |
|
|
1239 | |
|
|
1240 | ^event_timer_options{S} { |
|
|
1241 | char *yv=yval(); |
|
|
1242 | if (*yv=='\0') |
|
|
1243 | LOG(llevError,"Event (timer) without options\n"); |
|
|
1244 | else |
|
|
1245 | insert_event(op,EVENT_TIMER,NULL,NULL,yv); |
|
|
1246 | } |
|
|
1247 | |
|
|
1248 | ^current_weapon_script{S} { char *yv=yval(); |
|
|
1249 | |
|
|
1250 | if (*yv=='\0') LOG(llevError,"Script (current weapon) without val\n"); |
|
|
1251 | else |
|
|
1252 | { |
|
|
1253 | FREE_AND_COPY(op->current_weapon_script, yv); |
|
|
1254 | }; |
|
|
1255 | } |
|
|
1256 | |
1064 | |
1257 | <*>(^{WS}$)|\n {/* ignore empty lines, newlines we don't do above */} |
1065 | <*>(^{WS}$)|\n {/* ignore empty lines, newlines we don't do above */} |
1258 | #.*\n {} |
1066 | #.*\n {} |
1259 | |
1067 | |
1260 | <<EOF>> {/* If we got an error, return the error. Otherwise, return that we got EOF */ |
1068 | <<EOF>> {/* If we got an error, return the error. Otherwise, return that we got EOF */ |
… | |
… | |
1318 | * be reset. |
1126 | * be reset. |
1319 | * LO_NOREAD (3): Reset the buffers, but don't read from it. (op can be null) |
1127 | * LO_NOREAD (3): Reset the buffers, but don't read from it. (op can be null) |
1320 | * |
1128 | * |
1321 | */ |
1129 | */ |
1322 | |
1130 | |
1323 | int load_object(FILE *fp, object *op, int bufstate, int map_flags) { |
1131 | int load_object(object_thawer &fp, object *op, int bufstate, int map_flags) { |
1324 | int retval; |
1132 | int retval; |
1325 | char inbuf[MAX_BUF]; |
1133 | char inbuf[MAX_BUF]; |
1326 | |
1134 | |
1327 | strcpy(msgbuf, ""); |
1135 | strcpy(msgbuf, ""); |
1328 | strcpy(lorebuf, ""); |
1136 | strcpy(lorebuf, ""); |
… | |
… | |
1334 | } |
1142 | } |
1335 | if (bufstate==LO_LINEMODE) { |
1143 | if (bufstate==LO_LINEMODE) { |
1336 | YY_BUFFER_STATE yybufstate; |
1144 | YY_BUFFER_STATE yybufstate; |
1337 | while (fgets(inbuf, MAX_BUF-3, fp)) { |
1145 | while (fgets(inbuf, MAX_BUF-3, fp)) { |
1338 | yybufstate=yy_scan_string(inbuf); |
1146 | yybufstate=yy_scan_string(inbuf); |
1339 | retval=lex_load(op, map_flags); |
1147 | retval=lex_load(op, fp, map_flags); |
1340 | yy_delete_buffer(yybufstate); |
1148 | yy_delete_buffer(yybufstate); |
1341 | if (retval==LL_NORMAL) return retval; |
1149 | if (retval==LL_NORMAL) return retval; |
1342 | } |
1150 | } |
1343 | LOG(llevDebug,"Got eof while scanning strings\n"); |
1151 | LOG(llevDebug,"Got eof while scanning strings\n"); |
1344 | return LL_EOF; |
1152 | return LL_EOF; |
1345 | } |
1153 | } |
1346 | |
1154 | |
1347 | retval=lex_load(op, map_flags); |
1155 | retval=lex_load(op, fp, map_flags); |
1348 | if (op->current_weapon_script != NULL) |
|
|
1349 | { |
|
|
1350 | op->current_weapon = find_best_weapon_used_match(op, op->current_weapon_script); |
|
|
1351 | LOG(llevDebug, "CurrentWeapon Loaded !\n"); |
|
|
1352 | }; |
|
|
1353 | |
1156 | |
1354 | /* LOG(llevDebug," load completed, object=%s\n",op->name);*/ |
1157 | /* LOG(llevDebug," load completed, object=%s\n",op->name);*/ |
1355 | return retval; |
1158 | return retval; |
1356 | } |
1159 | } |
1357 | |
1160 | |
… | |
… | |
1363 | * override values and in c_wiz to mutate values. |
1166 | * override values and in c_wiz to mutate values. |
1364 | */ |
1167 | */ |
1365 | int set_variable(object *op,char *buf) { |
1168 | int set_variable(object *op,char *buf) { |
1366 | YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER; |
1169 | YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER; |
1367 | int retval; |
1170 | int retval; |
|
|
1171 | object_thawer thawer (0); |
1368 | |
1172 | |
1369 | strcpy(msgbuf, ""); |
1173 | strcpy(msgbuf, ""); |
1370 | strcpy(lorebuf, ""); |
1174 | strcpy(lorebuf, ""); |
1371 | yy_push_state(INITIAL); |
1175 | yy_push_state(INITIAL); |
1372 | yybufstate=yy_scan_string(buf); |
1176 | yybufstate=yy_scan_string(buf); |
1373 | retval=lex_load(op,0); |
1177 | retval=lex_load(op,thawer,0); |
1374 | yy_switch_to_buffer(yycurbuf); |
1178 | yy_switch_to_buffer(yycurbuf); |
1375 | yy_delete_buffer(yybufstate); |
1179 | yy_delete_buffer(yybufstate); |
1376 | yy_pop_state(); |
1180 | yy_pop_state(); |
1377 | return retval; |
1181 | return retval; |
1378 | } |
1182 | } |
… | |
… | |
1386 | /* This is a list of pointers that correspond to the FLAG_.. values. |
1190 | /* This is a list of pointers that correspond to the FLAG_.. values. |
1387 | * This is a simple 1:1 mapping - if FLAG_FRIENDLY is 15, then |
1191 | * This is a simple 1:1 mapping - if FLAG_FRIENDLY is 15, then |
1388 | * the 15'th element of this array should match that name. |
1192 | * the 15'th element of this array should match that name. |
1389 | * If an entry is NULL, that is a flag not to loaded/saved. |
1193 | * If an entry is NULL, that is a flag not to loaded/saved. |
1390 | */ |
1194 | */ |
1391 | static char *flag_names[NUM_FLAGS+1] = { |
1195 | static const char *const flag_names[NUM_FLAGS+1] = { |
1392 | "alive", "wiz", NULL, NULL, "was_wiz", "applied", "unpaid", |
1196 | "alive", "wiz", NULL, NULL, "was_wiz", "applied", "unpaid", |
1393 | "can_use_shield", "no_pick", NULL /* walk_on*/, NULL /* no_pass */, /* 10 */ |
1197 | "can_use_shield", "no_pick", NULL /* walk_on*/, NULL /* no_pass */, /* 10 */ |
1394 | "is_animated", NULL /* slow_move */, |
1198 | "is_animated", NULL /* slow_move */, |
1395 | NULL /* flying */, "monster", "friendly", "generator", |
1199 | NULL /* flying */, "monster", "friendly", "generator", |
1396 | "is_thrown", "auto_apply", "treasure", "player sold", /* 20 */ |
1200 | "is_thrown", "auto_apply", "treasure", "player sold", /* 20 */ |
… | |
… | |
1420 | "activate_on_release", "is_water", "use_content_on_gen", NULL, "is_buildable", /* 110 */ |
1224 | "activate_on_release", "is_water", "use_content_on_gen", NULL, "is_buildable", /* 110 */ |
1421 | NULL |
1225 | NULL |
1422 | }; |
1226 | }; |
1423 | |
1227 | |
1424 | |
1228 | |
1425 | void save_double(char *buf,char *name,double v) |
|
|
1426 | { |
|
|
1427 | char tbuf[200]; |
|
|
1428 | |
|
|
1429 | sprintf(tbuf,"%s %f\n",name,v); |
|
|
1430 | strcat(buf,tbuf); |
|
|
1431 | } |
|
|
1432 | |
|
|
1433 | /* |
1229 | /* |
1434 | * Initialises the array of variable-names. Needed before any |
1230 | * Initialises the array of variable-names. Needed before any |
1435 | * objects can be loaded. Called by init_library(). |
1231 | * objects can be loaded. Called by init_library(). |
1436 | */ |
1232 | */ |
1437 | |
1233 | |
1438 | void init_vars() { |
1234 | void init_vars() { |
1439 | } |
1235 | } |
1440 | |
1236 | |
1441 | /*For get_ob_diff speed reason*/ |
1237 | /*For get_ob_diff speed reason*/ |
1442 | typedef struct { |
1238 | typedef struct { |
1443 | char* name; |
1239 | const char *name; |
1444 | int length; |
1240 | int length; |
1445 | }genericname; |
1241 | }genericname; |
1446 | static genericname evtnames[13]= |
1242 | |
|
|
1243 | /* This returns a string of the integer movement type */ |
|
|
1244 | static char* get_string_move_type(MoveType mt) |
1447 | { |
1245 | { |
1448 | {"event_none ",11}, |
1246 | static char retbuf[MAX_BUF], retbuf_all[MAX_BUF]; |
1449 | {"event_apply ",12}, |
1247 | int i, all_count=0, count; |
1450 | {"event_attack ",13}, |
|
|
1451 | {"event_death ",12}, |
|
|
1452 | {"event_drop ",11}, |
|
|
1453 | {"event_pickup ",13}, |
|
|
1454 | {"event_say ",10}, |
|
|
1455 | {"event_stop ",11}, |
|
|
1456 | {"event_time ",11}, |
|
|
1457 | {"event_throw ",12}, |
|
|
1458 | {"event_trigger ",14}, |
|
|
1459 | {"event_close ",12}, |
|
|
1460 | {"event_timer ",12} |
|
|
1461 | } ; |
|
|
1462 | |
1248 | |
1463 | static genericname plgnames[13]= |
1249 | strcpy(retbuf,""); |
1464 | { |
1250 | strcpy(retbuf_all," all"); |
1465 | {"event_none_plugin ",18}, |
|
|
1466 | {"event_apply_plugin ",19}, |
|
|
1467 | {"event_attack_plugin ",20}, |
|
|
1468 | {"event_death_plugin ",19}, |
|
|
1469 | {"event_drop_plugin ",18}, |
|
|
1470 | {"event_pickup_plugin ",20}, |
|
|
1471 | {"event_say_plugin ",17}, |
|
|
1472 | {"event_stop_plugin ",18}, |
|
|
1473 | {"event_time_plugin ",18}, |
|
|
1474 | {"event_throw_plugin ",19}, |
|
|
1475 | {"event_trigger_plugin ",21}, |
|
|
1476 | {"event_close_plugin ",19}, |
|
|
1477 | {"event_timer_plugin ",19} |
|
|
1478 | }; |
|
|
1479 | |
1251 | |
1480 | static genericname plgoptions[13]= |
1252 | /* Quick check, and probably fairly common */ |
1481 | { |
1253 | if (mt == MOVE_ALL) return retbuf_all+1; |
1482 | {"event_none_options ",19}, |
1254 | if (mt == 0) { |
1483 | {"event_apply_options ",20}, |
1255 | strcpy(retbuf,"0"); |
1484 | {"event_attack_options ",21}, |
1256 | return retbuf; |
1485 | {"event_death_options ",20}, |
1257 | } |
1486 | {"event_drop_options ",19}, |
1258 | |
1487 | {"event_pickup_options ",21}, |
1259 | /* We basically slide the bits down. Why look at MOVE_ALL? |
1488 | {"event_say_options ",18}, |
1260 | * because we may want to return a string like 'all -swim', |
1489 | {"event_stop_options ",19}, |
1261 | * and if we just looked at mt, we couldn't get that. |
1490 | {"event_time_options ",19}, |
1262 | */ |
1491 | {"event_throw_options ",20}, |
1263 | for (i=MOVE_ALL, count=0; i!=0; i >>= 1, count++) { |
1492 | {"event_trigger_options ",22}, |
1264 | if (mt & (1<<count)) { |
1493 | {"event_close_options ",20}, |
1265 | strcat(retbuf, " "); |
1494 | {"event_timer_options ",20} |
1266 | strcat(retbuf, move_name[count]); |
1495 | }; |
1267 | } else { |
|
|
1268 | strcat(retbuf_all, " -"); |
|
|
1269 | strcat(retbuf_all, move_name[count]); |
|
|
1270 | all_count++; |
|
|
1271 | } |
|
|
1272 | } |
|
|
1273 | /* Basically, if there is a single negation, return it, eg |
|
|
1274 | * 'all -swim'. But more than that, just return the |
|
|
1275 | * enumerated values. It doesn't make sense to return |
|
|
1276 | * 'all -walk -fly_low' - it is shorter to return 'fly_high swim' |
|
|
1277 | */ |
|
|
1278 | if (all_count <=1) return retbuf_all+1; |
|
|
1279 | else return retbuf+1; |
|
|
1280 | } |
|
|
1281 | |
1496 | |
1282 | |
1497 | /* |
1283 | /* |
1498 | * Returns a pointer to a static string which contains all variables |
1284 | * Returns a pointer to a static string which contains all variables |
1499 | * which are different in the two given objects. op is the what object |
1285 | * which are different in the two given objects. op is the what object |
1500 | * the different values will be taken from. This function is |
1286 | * the different values will be taken from. This function is |
… | |
… | |
1535 | * NEVER touch buf between PREPARE_FASTCAT(buf) and |
1321 | * NEVER touch buf between PREPARE_FASTCAT(buf) and |
1536 | * FINISH_FASTCAT(buf) |
1322 | * FINISH_FASTCAT(buf) |
1537 | */ |
1323 | */ |
1538 | static int already_run = 0; |
1324 | static int already_run = 0; |
1539 | static int flag_lens[NUM_FLAGS]; |
1325 | static int flag_lens[NUM_FLAGS]; |
1540 | static char buf2[HUGE_BUF]; |
1326 | char buf2[4096]; // / was HUFE_BUF, which was hugely incorrect, as is this value, but much less so |
1541 | static char buf[HUGE_BUF]; |
1327 | static char buf[128*1024]; // < the assumption is that every object always fits. fixing this bug, however |
1542 | char* fastbuf; |
1328 | char* fastbuf; // \ requires a large rewrite of the code, so its left to the next total rewrite. |
1543 | int tmp; |
1329 | int tmp; |
1544 | int i; |
1330 | int i; |
1545 | #if 0 |
|
|
1546 | /*Memory polluting code. Should help detect problems, very slow*/ |
|
|
1547 | for (i=0;i<HUGE_BUF;i++){ |
|
|
1548 | buf[i]='a'+(unsigned short)(i%25); |
|
|
1549 | } |
|
|
1550 | #endif |
|
|
1551 | event *etmp; |
1331 | event *etmp; |
1552 | event *etmp2; |
1332 | event *etmp2; |
1553 | key_value * my_field; |
1333 | key_value * my_field; |
1554 | key_value * arch_field; |
1334 | key_value * arch_field; |
1555 | |
1335 | |
… | |
… | |
1621 | op->other_arch->name) { |
1401 | op->other_arch->name) { |
1622 | ADD_STRINGLINE_ENTRY(fastbuf,"other_arch ",op->other_arch->name,11); |
1402 | ADD_STRINGLINE_ENTRY(fastbuf,"other_arch ",op->other_arch->name,11); |
1623 | } |
1403 | } |
1624 | if(op->face!=op2->face) { |
1404 | if(op->face!=op2->face) { |
1625 | ADD_STRINGLINE_ENTRY(fastbuf,"face ",op->face->name,5); |
1405 | ADD_STRINGLINE_ENTRY(fastbuf,"face ",op->face->name,5); |
1626 | } |
|
|
1627 | |
|
|
1628 | for(etmp=op->events;etmp!=NULL;etmp=etmp->next) |
|
|
1629 | { |
|
|
1630 | /* First we find the event for the reference object */ |
|
|
1631 | etmp2=find_event(op2,etmp->type); |
|
|
1632 | if ((etmp->hook != NULL) && ((etmp2 == NULL) || (etmp2->hook == NULL) || (strcmp(etmp2->hook,etmp->hook)))) |
|
|
1633 | /* Either there's no matching event in the reference object, |
|
|
1634 | * or the hook is different */ |
|
|
1635 | { |
|
|
1636 | ADD_STRINGLINE_ENTRY(fastbuf,evtnames[etmp->type].name,etmp->hook,evtnames[etmp->type].length); |
|
|
1637 | } |
|
|
1638 | if ((etmp->plugin != NULL) && ((etmp2 == NULL) || (etmp2->plugin == NULL) || (strcmp(etmp2->plugin,etmp->plugin)))) |
|
|
1639 | { |
|
|
1640 | |
|
|
1641 | ADD_STRINGLINE_ENTRY(fastbuf,plgnames[etmp->type].name,etmp->plugin,plgnames[etmp->type].length); |
|
|
1642 | } |
|
|
1643 | if ((etmp->options != NULL) && ((etmp2 == NULL) || (etmp2->options == NULL) || (strcmp(etmp2->options,etmp->options)))) |
|
|
1644 | { |
|
|
1645 | ADD_STRINGLINE_ENTRY(fastbuf,plgoptions[etmp->type].name,etmp->options,plgoptions[etmp->type].length); |
|
|
1646 | } |
|
|
1647 | |
|
|
1648 | } |
1406 | } |
1649 | |
1407 | |
1650 | if (op->animation_id != op2->animation_id) { |
1408 | if (op->animation_id != op2->animation_id) { |
1651 | if (op->animation_id) { |
1409 | if (op->animation_id) { |
1652 | ADD_STRINGLINE_ENTRY(fastbuf,"animation ",animations[GET_ANIM_ID(op)].name,10); |
1410 | ADD_STRINGLINE_ENTRY(fastbuf,"animation ",animations[GET_ANIM_ID(op)].name,10); |
… | |
… | |
1684 | if(op->stats.maxgrace!=op2->stats.maxgrace) |
1442 | if(op->stats.maxgrace!=op2->stats.maxgrace) |
1685 | FAST_SAVE_LONG(fastbuf,"maxgrace ",op->stats.maxgrace,9); |
1443 | FAST_SAVE_LONG(fastbuf,"maxgrace ",op->stats.maxgrace,9); |
1686 | |
1444 | |
1687 | if(op->stats.exp!=op2->stats.exp) { |
1445 | if(op->stats.exp!=op2->stats.exp) { |
1688 | #ifndef WIN32 |
1446 | #ifndef WIN32 |
1689 | sprintf(buf2,"%lld\n", op->stats.exp); |
1447 | sprintf(buf2,"%lld", op->stats.exp); |
1690 | #else |
1448 | #else |
1691 | sprintf(buf2,"%I64d\n", op->stats.exp); |
1449 | sprintf(buf2,"%I64d", op->stats.exp); |
1692 | #endif |
1450 | #endif |
1693 | ADD_STRINGLINE_ENTRY(fastbuf,"exp ", buf2, 4); |
1451 | ADD_STRINGLINE_ENTRY(fastbuf,"exp ", buf2, 4); |
1694 | } |
1452 | } |
1695 | |
1453 | |
1696 | if(op->perm_exp!=op2->perm_exp) { |
1454 | if(op->perm_exp!=op2->perm_exp) { |
1697 | #ifndef WIN32 |
1455 | #ifndef WIN32 |
1698 | sprintf(buf2,"%lld\n", op->perm_exp); |
1456 | sprintf(buf2,"%lld", op->perm_exp); |
1699 | #else |
1457 | #else |
1700 | sprintf(buf2,"%I64d\n", op->perm_exp); |
1458 | sprintf(buf2,"%I64d", op->perm_exp); |
1701 | #endif |
1459 | #endif |
1702 | ADD_STRINGLINE_ENTRY(fastbuf,"perm_exp ", buf2, 9); |
1460 | ADD_STRINGLINE_ENTRY(fastbuf,"perm_exp ", buf2, 9); |
1703 | } |
1461 | } |
1704 | |
1462 | |
1705 | if(op->expmul!=op2->expmul) |
1463 | if(op->expmul!=op2->expmul) |
… | |
… | |
1803 | if (op->will_apply!=op2->will_apply) |
1561 | if (op->will_apply!=op2->will_apply) |
1804 | FAST_SAVE_LONG(fastbuf,"will_apply ",op->will_apply,11); |
1562 | FAST_SAVE_LONG(fastbuf,"will_apply ",op->will_apply,11); |
1805 | if(op->smoothlevel!=op2->smoothlevel) |
1563 | if(op->smoothlevel!=op2->smoothlevel) |
1806 | FAST_SAVE_LONG(fastbuf,"smoothlevel ",op->smoothlevel,12); |
1564 | FAST_SAVE_LONG(fastbuf,"smoothlevel ",op->smoothlevel,12); |
1807 | |
1565 | |
1808 | if (op->current_weapon_script!=op2->current_weapon_script){ |
|
|
1809 | ADD_STRINGLINE_ENTRY(fastbuf,"current_weapon_script ",op->current_weapon_script,22); |
|
|
1810 | }; |
|
|
1811 | |
|
|
1812 | if(op->weapontype && op->weapontype!=op2->weapontype) { |
1566 | if(op->weapontype && op->weapontype!=op2->weapontype) { |
1813 | FAST_SAVE_LONG(fastbuf,"weapontype ",op->weapontype,11); |
1567 | FAST_SAVE_LONG(fastbuf,"weapontype ",op->weapontype,11); |
1814 | } |
1568 | } |
1815 | if(op->tooltype && op->tooltype!=op2->tooltype) { |
1569 | if(op->tooltype && op->tooltype!=op2->tooltype) { |
1816 | FAST_SAVE_LONG(fastbuf,"tooltype ",op->tooltype,9); |
1570 | FAST_SAVE_LONG(fastbuf,"tooltype ",op->tooltype,9); |
… | |
… | |
1843 | |
1597 | |
1844 | if (op->gen_sp_armour != op2->gen_sp_armour) { |
1598 | if (op->gen_sp_armour != op2->gen_sp_armour) { |
1845 | FAST_SAVE_LONG(fastbuf,"gen_sp_armour ",op->gen_sp_armour,14); |
1599 | FAST_SAVE_LONG(fastbuf,"gen_sp_armour ",op->gen_sp_armour,14); |
1846 | } |
1600 | } |
1847 | |
1601 | |
|
|
1602 | /* I've kept the old int move type saving code commented out. |
|
|
1603 | * In an ideal world, we'd know if we want to do a quick |
|
|
1604 | * save (say to a temp map, where we don't care about strings), |
|
|
1605 | * or a slower save/dm dump, where printing out strings is handy. |
|
|
1606 | */ |
1848 | if (op->move_type != op2->move_type) { |
1607 | if (op->move_type != op2->move_type) { |
1849 | FAST_SAVE_LONG(fastbuf,"move_type ",op->move_type,10); |
1608 | /*FAST_SAVE_LONG(fastbuf,"move_type ",op->move_type,10)*/ |
|
|
1609 | ADD_STRINGLINE_ENTRY(fastbuf,"move_type ", |
|
|
1610 | get_string_move_type(op->move_type), |
|
|
1611 | 10); |
1850 | } |
1612 | } |
1851 | |
|
|
1852 | if (op->move_block != op2->move_block) { |
1613 | if (op->move_block != op2->move_block) { |
1853 | FAST_SAVE_LONG(fastbuf,"move_block ",op->move_block,11); |
1614 | /*FAST_SAVE_LONG(fastbuf,"move_block ",op->move_block,11)*/ |
|
|
1615 | ADD_STRINGLINE_ENTRY(fastbuf,"move_block ", |
|
|
1616 | get_string_move_type(op->move_block), |
|
|
1617 | 11); |
1854 | } |
1618 | } |
1855 | |
1619 | if (op->move_allow != op2->move_allow) { |
|
|
1620 | /*FAST_SAVE_LONG(fastbuf,"move_allow ",op->move_allow,11);*/ |
|
|
1621 | ADD_STRINGLINE_ENTRY(fastbuf,"move_allow ", |
|
|
1622 | get_string_move_type(op->move_allow), |
|
|
1623 | 11); |
|
|
1624 | } |
1856 | if (op->move_on != op2->move_on) { |
1625 | if (op->move_on != op2->move_on) { |
1857 | FAST_SAVE_LONG(fastbuf,"move_on ",op->move_on,8); |
1626 | /*FAST_SAVE_LONG(fastbuf,"move_on ",op->move_on,8);*/ |
|
|
1627 | ADD_STRINGLINE_ENTRY(fastbuf,"move_on ", |
|
|
1628 | get_string_move_type(op->move_on), |
|
|
1629 | 8); |
1858 | } |
1630 | } |
1859 | |
|
|
1860 | if (op->move_off != op2->move_off) { |
1631 | if (op->move_off != op2->move_off) { |
1861 | FAST_SAVE_LONG(fastbuf,"move_off ",op->move_off,9); |
1632 | /*FAST_SAVE_LONG(fastbuf,"move_off ",op->move_off,9);*/ |
|
|
1633 | ADD_STRINGLINE_ENTRY(fastbuf,"move_off ", |
|
|
1634 | get_string_move_type(op->move_off), |
|
|
1635 | 9); |
1862 | } |
1636 | } |
1863 | if (op->move_slow != op2->move_slow) { |
1637 | if (op->move_slow != op2->move_slow) { |
1864 | FAST_SAVE_LONG(fastbuf,"move_slow ",op->move_slow,10); |
1638 | /*FAST_SAVE_LONG(fastbuf,"move_slow ",op->move_slow,10);*/ |
|
|
1639 | ADD_STRINGLINE_ENTRY(fastbuf,"move_slow ", |
|
|
1640 | get_string_move_type(op->move_slow), |
|
|
1641 | 10); |
1865 | } |
1642 | } |
1866 | |
1643 | |
1867 | if (op->move_slow_penalty != op2->move_slow_penalty) { |
1644 | if (op->move_slow_penalty != op2->move_slow_penalty) { |
1868 | FAST_SAVE_LONG(fastbuf,"move_slow_penalty ",op->move_slow_penalty,18); |
1645 | FAST_SAVE_LONG(fastbuf,"move_slow_penalty ",(long) op->move_slow_penalty,18); |
1869 | } |
1646 | } |
1870 | |
1647 | |
1871 | if (!COMPARE_FLAGS(op,op2)) { |
1648 | if (!COMPARE_FLAGS(op,op2)) { |
1872 | for (tmp=0; tmp <= NUM_FLAGS; tmp++) { |
1649 | for (tmp=0; tmp <= NUM_FLAGS; tmp++) { |
1873 | if (flag_names[tmp] && (QUERY_FLAG(op, tmp) != QUERY_FLAG(op2, tmp))) { |
1650 | if (flag_names[tmp] && (QUERY_FLAG(op, tmp) != QUERY_FLAG(op2, tmp))) { |
… | |
… | |
1896 | * the only place this is not set is when saving the player. |
1673 | * the only place this is not set is when saving the player. |
1897 | * If bit 1 of flag is set, don't remove the object after save. As of now, |
1674 | * If bit 1 of flag is set, don't remove the object after save. As of now, |
1898 | * all of the callers are setting this. |
1675 | * all of the callers are setting this. |
1899 | */ |
1676 | */ |
1900 | |
1677 | |
1901 | void save_object(FILE *fp,object *op, int flag) { |
1678 | void save_object(object_freezer &fp,object *op, int flag) { |
1902 | archetype *at; |
1679 | archetype *at; |
1903 | char *cp; |
1680 | char *cp; |
1904 | object *tmp,*old; |
1681 | object *tmp,*old; |
1905 | |
1682 | |
1906 | /* Even if the object does have an owner, it would seem that we should |
1683 | /* Even if the object does have an owner, it would seem that we should |
1907 | * still save it. |
1684 | * still save it. |
1908 | */ |
1685 | */ |
1909 | if(op->owner!=NULL || fp == NULL) |
1686 | if(op->owner!=NULL) |
1910 | return; |
1687 | return; |
1911 | |
1688 | |
1912 | /* If it is unpaid and we don't want to save those, just return. */ |
1689 | /* If it is unpaid and we don't want to save those, just return. */ |
1913 | if(!(flag&1)&&(QUERY_FLAG(op, FLAG_UNPAID))) { |
1690 | if(!(flag&1)&&(QUERY_FLAG(op, FLAG_UNPAID))) { |
1914 | return; |
1691 | return; |
… | |
… | |
1945 | if (!(flag&2)) { |
1722 | if (!(flag&2)) { |
1946 | remove_ob(op); |
1723 | remove_ob(op); |
1947 | free_object (op); |
1724 | free_object (op); |
1948 | } |
1725 | } |
1949 | |
1726 | |
|
|
1727 | fp.put (op); |
1950 | fprintf(fp,"end\n"); |
1728 | fprintf(fp,"end\n"); |
1951 | } |
|
|
1952 | |
|
|
1953 | void insert_event(object* op, int etype, char *ehook, char *eplug, char *eoptions) |
|
|
1954 | { |
|
|
1955 | event *evt; |
|
|
1956 | event *tmp; |
|
|
1957 | |
|
|
1958 | evt = find_event(op,etype); |
|
|
1959 | if (evt == NULL) |
|
|
1960 | { |
|
|
1961 | evt = (event *)malloc(sizeof(event)); |
|
|
1962 | evt->next = NULL; |
|
|
1963 | evt->type = etype; |
|
|
1964 | evt->hook = NULL; |
|
|
1965 | evt->plugin = NULL; |
|
|
1966 | evt->options = NULL; |
|
|
1967 | if (op->events==NULL) |
|
|
1968 | { |
|
|
1969 | op->events=evt; |
|
|
1970 | } |
|
|
1971 | else |
|
|
1972 | { |
|
|
1973 | for(tmp=op->events;;tmp=tmp->next) |
|
|
1974 | { |
|
|
1975 | if (tmp->next == NULL) |
|
|
1976 | { |
|
|
1977 | tmp->next = evt; |
|
|
1978 | break; |
|
|
1979 | } |
|
|
1980 | } |
|
|
1981 | } |
|
|
1982 | } |
|
|
1983 | if (ehook != NULL) |
|
|
1984 | FREE_AND_COPY(evt->hook,ehook); |
|
|
1985 | if (eplug != NULL) |
|
|
1986 | FREE_AND_COPY(evt->plugin,eplug); |
|
|
1987 | if (eoptions != NULL) |
|
|
1988 | FREE_AND_COPY(evt->options,eoptions); |
|
|
1989 | } |
1729 | } |
1990 | |
1730 | |
1991 | event* find_event(object* op, int etype) |
1731 | event* find_event(object* op, int etype) |
1992 | { |
1732 | { |
1993 | event *found; |
1733 | event *found; |