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.1.1.1 by root, Fri Feb 3 07:11:36 2006 UTC vs.
Revision 1.17 by root, Thu Aug 31 09:19:33 2006 UTC

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
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
48/* Maps the MOVE_* values to names */
49static 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 */
58char *spell_mapping[] = { 62const 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.
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}
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
571static 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
1323int load_object(FILE *fp, object *op, int bufstate, int map_flags) { 1131int 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 */
1365int set_variable(object *op,char *buf) { 1168int 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 */
1391static char *flag_names[NUM_FLAGS+1] = { 1195static 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 */,
1395NULL /* flying */, "monster", "friendly", "generator", 1199NULL /* 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 */
1421NULL 1225NULL
1422}; 1226};
1423 1227
1424 1228
1425void 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
1438void init_vars() { 1234void init_vars() {
1439} 1235}
1440 1236
1441/*For get_ob_diff speed reason*/ 1237/*For get_ob_diff speed reason*/
1442typedef struct { 1238typedef struct {
1443 char* name; 1239 const char *name;
1444 int length; 1240 int length;
1445}genericname; 1241}genericname;
1446static genericname evtnames[13]= 1242
1243/* This returns a string of the integer movement type */
1244static 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
1463static 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
1480static 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
1901void save_object(FILE *fp,object *op, int flag) { 1678void 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
1953void 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
1991event* find_event(object* op, int etype) 1731event* find_event(object* op, int etype)
1992{ 1732{
1993 event *found; 1733 event *found;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines