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.3 by elmex, Wed Mar 15 14:04:37 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.3 2006/03/15 14:04:37 elmex 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 47
48/* Maps the MOVE_* values to names */ 48/* Maps the MOVE_* values to names */
49static const char *const move_name[] = {"walk", "fly_low", "fly_high", "swim", "boat", 49static const char *const move_name[] = {"walk", "fly_low", "fly_high", "swim", "boat",
50 NULL}; 50 NULL};
51 51
57 * If you are adding a new spell, you should not modify this - you 57 * If you are adding a new spell, you should not modify this - you
58 * new spell won't have been used, and thus won't have any legacy object. 58 * new spell won't have been used, and thus won't have any legacy object.
59 * NULL entries in this table are valid - to denote objects that should 59 * NULL entries in this table are valid - to denote objects that should
60 * not be updated for whatever reason. 60 * not be updated for whatever reason.
61 */ 61 */
62const char *const spell_mapping[] = { 62const char *spell_mapping[] = {
63"spell_magic_bullet", /* 0 */ 63"spell_magic_bullet", /* 0 */
64"spell_small_fireball", /* 1 */ 64"spell_small_fireball", /* 1 */
65"spell_medium_fireball", /* 2 */ 65"spell_medium_fireball", /* 2 */
66"spell_large_fireball", /* 3 */ 66"spell_large_fireball", /* 3 */
67"spell_burning_hands", /* 4 */ 67"spell_burning_hands", /* 4 */
325 } 325 }
326 } 326 }
327 LOG(llevError,"set_body_info called with bogus params: %s\n", params); 327 LOG(llevError,"set_body_info called with bogus params: %s\n", params);
328} 328}
329 329
330// return a suitable strign describign an objetc in enough detail to find it
331// used only in check_loaded_object: TODO remove static, move it elsewhere and
332// use it in more log messages.
333static char *op_debug_info_ (object *op, char *info)
334{
335 char info2[256 * 3];
336 char *p = info;
337
338 p += snprintf (p, 256, "%d=\"%s%s%s\"",
339 op->count,
340 op->name ? op->name : "(anon)",
341 op->title ? " " : "",
342 op->title ? op->title : "");
343
344 if (op->env)
345 p += snprintf (p, 256, "(in %s)", op_debug_info_ (op->env, info2));
346
347 if (op->map)
348 p += snprintf (p, 256, "(on %s@%d+%d)", op->map->path, op->x, op->y);
349
350 return info;
351}
352
353static char *op_debug_info (object *op)
354{
355 static char info[256 * 3];
356
357 return op_debug_info_ (op, info);
358}
330 359
331/* This function checks the object after it has been loaded (when we 360/* This function checks the object after it has been loaded (when we
332 * get the 'end' in the input stream). This function can be used to 361 * get the 'end' in the input stream). This function can be used to
333 * deal with legacy objects where fields may have changed. It can also be used 362 * deal with legacy objects where fields may have changed. It can also be used
334 * to check for objects to make sure there are no common errors. 363 * to check for objects to make sure there are no common errors.
363 * really just to catch any errors - program will still run, but 392 * really just to catch any errors - program will still run, but
364 * not in the ideal fashion. 393 * not in the ideal fashion.
365 */ 394 */
366 if ((op->type == WEAPON || op->type==BOW) && arch_init) { 395 if ((op->type == WEAPON || op->type==BOW) && arch_init) {
367 if (!op->skill) { 396 if (!op->skill) {
368 LOG(llevError,"Weapon %s lacks a skill.\n", op->name); 397 LOG(llevError,"Weapon %s lacks a skill.\n", op_debug_info (op));
369 } else if ((!strcmp(op->skill,"one handed weapons") && op->body_info[1] != -1) || 398 } else if ((!strcmp(op->skill,"one handed weapons") && op->body_info[1] != -1) ||
370 (!strcmp(op->skill,"two handed weapons") && op->body_info[1] != -2)) { 399 (!strcmp(op->skill,"two handed weapons") && op->body_info[1] != -2)) {
371 LOG(llevError,"weapon %s arm usage does not match skill: %d, %s\n", 400 LOG(llevError,"weapon %s arm usage does not match skill: %d, %s\n",
372 op->name, op->body_info[1], op->skill); 401 op_debug_info (op), op->body_info[1], op->skill);
373 } 402 }
374 } 403 }
375 404
376 /* We changed last_heal to gen_sp_armour, which is what it 405 /* We changed last_heal to gen_sp_armour, which is what it
377 * really does for many objects. Need to catch any in maps 406 * really does for many objects. Need to catch any in maps
382 (op->type == SHIELD) || (op->type == RING) || 411 (op->type == SHIELD) || (op->type == RING) ||
383 (op->type == BOOTS) || (op->type == GLOVES) || 412 (op->type == BOOTS) || (op->type == GLOVES) ||
384 (op->type == AMULET ) || (op->type == GIRDLE) || 413 (op->type == AMULET ) || (op->type == GIRDLE) ||
385 (op->type == BRACERS ) || (op->type == CLOAK)) { 414 (op->type == BRACERS ) || (op->type == CLOAK)) {
386 if (op->last_heal) { 415 if (op->last_heal) {
387 LOG(llevDebug,"Object %s still has last_heal set, not gen_sp_armour\n", 416 LOG(llevDebug,"Object %s still has last_heal set, not gen_sp_armour\n", op_debug_info (op));
388 op->name?op->name:"NULL");
389 op->gen_sp_armour = op->last_heal; 417 op->gen_sp_armour = op->last_heal;
390 op->last_heal = 0; 418 op->last_heal = 0;
391 } 419 }
392 if (editor) ip =0; 420 if (editor) ip =0;
393 else ip = calc_item_power(op, 0); 421 else ip = calc_item_power(op, 0);
394 /* Legacy objects from before item power was in the game */ 422 /* Legacy objects from before item power was in the game */
395 if (!op->item_power && ip) { 423 if (!op->item_power && ip) {
396 if (ip > 3) { 424 if (ip > 3) {
397 LOG(llevDebug,"Object %s had no item power, using %d\n", 425 LOG(llevDebug,"Object %s had no item power, using %d\n", op_debug_info (op), ip);
398 op->name?op->name:"NULL", ip);
399 } 426 }
400 op->item_power = ip; 427 op->item_power = ip;
401 } 428 }
402 /* Check for possibly bogus values. Has to meet both these criteria - 429 /* Check for possibly bogus values. Has to meet both these criteria -
403 * something that has item_power 1 is probably just fine if our calculated 430 * something that has item_power 1 is probably just fine if our calculated
405 * similarly, it item_power is 0, the first check will always pass, 432 * similarly, it item_power is 0, the first check will always pass,
406 * but not the second one. 433 * but not the second one.
407 */ 434 */
408 if (ip > 2 *op->item_power && ip > (op->item_power + 3)) { 435 if (ip > 2 *op->item_power && ip > (op->item_power + 3)) {
409 LOG(llevDebug,"Object %s seems to have too low item power? %d > %d\n", 436 LOG(llevDebug,"Object %s seems to have too low item power? %d > %d\n",
410 op->name?op->name:"NULL", ip, op->item_power); 437 op_debug_info (op), ip, op->item_power);
411 } 438 }
412 439
413 } 440 }
414 /* Old spellcasting object - need to load in the appropiate object */ 441 /* Old spellcasting object - need to load in the appropiate object */
415 if ((op->type == ROD || op->type == WAND || op->type == SCROLL || op->type == HORN 442 if ((op->type == ROD || op->type == WAND || op->type == SCROLL || op->type == HORN
438 } 465 }
439 466
440 if (QUERY_FLAG(op, FLAG_MONSTER)) { 467 if (QUERY_FLAG(op, FLAG_MONSTER)) {
441 if (op->stats.hp > op->stats.maxhp) 468 if (op->stats.hp > op->stats.maxhp)
442 LOG(llevDebug,"Monster %s has hp set higher than maxhp (%d>%d)\n", 469 LOG(llevDebug,"Monster %s has hp set higher than maxhp (%d>%d)\n",
443 op->name, 470 op_debug_info (op),
444 op->stats.hp, op->stats.maxhp); 471 op->stats.hp, op->stats.maxhp);
445 472
446 /* The archs just need to be updated for this */ 473 /* The archs just need to be updated for this */
447 if (op->move_type ==0) op->move_type = MOVE_WALK; 474 if (op->move_type ==0) op->move_type = MOVE_WALK;
448 } 475 }
616 643
617%} 644%}
618 645
619^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; } 646^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; }
620<MESSAGE>^endmsg{WS}$ { BEGIN( INITIAL ); 647<MESSAGE>^endmsg{WS}$ { BEGIN( INITIAL );
621 op->msg=add_string(msgbuf);
622 /* Just print a warning so we can be reasonably safe 648 /* Just print a warning so we can be reasonably safe
623 * about not overflowing the buffer. 649 * about not overflowing the buffer.
624 */ 650 */
625 if (strlen(op->msg) > (HUGE_BUF/2)) 651 if (strlen(msgbuf) >= HUGE_BUF)
652 {
626 LOG(llevDebug, "\n\tWarning message length > %d (max allowed=%d): %d\n>%.80s<\n", 653 LOG(llevDebug, "\n\tError message length >= %d: %d\n>%.80s<\n",
627 HUGE_BUF/2, HUGE_BUF, strlen(op->msg),op->msg); 654 HUGE_BUF, strlen(op->msg),op->msg);
655 op->msg = add_string ("ERROR, please report: string too long, winged.\n");
656 }
657 else
658 op->msg = add_string (msgbuf);
628 } 659 }
629<MESSAGE>.* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); } 660<MESSAGE>.* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); }
630 661
631^lore{WS}$ { BEGIN( LORE ); lorebuf[0]='\0'; } 662^lore{WS}$ { BEGIN( LORE ); lorebuf[0]='\0'; }
632<LORE>^endlore{WS}$ { BEGIN( INITIAL ); 663<LORE>^endlore{WS}$ { BEGIN( INITIAL );
662^name_pl{S} { char *yv=yval(); 693^name_pl{S} { char *yv=yval();
663 694
664 if (*yv=='\0') LOG(llevError,"Name without val\n"); 695 if (*yv=='\0') LOG(llevError,"Name without val\n");
665 else FREE_AND_COPY(op->name_pl, yv); 696 else FREE_AND_COPY(op->name_pl, yv);
666 } 697 }
698^attach{S} { char *yv=yval();
699 if (*yv)
700 op->attach = add_string (yv);
701 }
667^skill{S} FREE_AND_COPY(op->skill,yval()); 702^skill{S} FREE_AND_COPY(op->skill,yval());
668^custom_name{S} { char *yv=yval(); 703^custom_name{S} { char *yv=yval();
669 704
670 if (*yv=='\0') LOG(llevError,"Custom name without val\n"); 705 if (*yv=='\0') LOG(llevError,"Custom name without val\n");
671 else FREE_AND_COPY(op->custom_name, yv); 706 else FREE_AND_COPY(op->custom_name, yv);
681 */ 716 */
682 if (op->arch) { 717 if (op->arch) {
683 object *tmp; 718 object *tmp;
684 char *yv=yval(); 719 char *yv=yval();
685 720
686 tmp=get_object();
687 tmp->arch = find_archetype(yv); 721 archetype *arch = find_archetype(yv);
688 if (tmp->arch!=NULL) 722 if (arch!=NULL)
689 copy_object(&tmp->arch->clone,tmp); 723 tmp = arch_to_object (arch);
690 else { 724 else {
725 tmp = get_object ();
691 if (tmp->name) free_string(tmp->name); 726 if (tmp->name) free_string(tmp->name);
692 /* record the name of the broken object */ 727 /* record the name of the broken object */
693 tmp->name = add_string(yv); 728 tmp->name = add_string(yv);
694 } 729 }
695 strcpy(msgbuf, ""); 730 strcpy(msgbuf, "");
696 strcpy(lorebuf, ""); 731 strcpy(lorebuf, "");
697 lex_load(tmp, map_flags); 732 lex_load(tmp, thawer, map_flags);
698 if (tmp->arch) { 733 if (tmp->arch) {
699 insert_ob_in_ob(tmp,op); 734 insert_ob_in_ob(tmp,op);
700 } 735 }
701 else { 736 else {
702 LOG(llevDebug,"Discarding object without arch: %s\n", tmp->name?tmp->name:"(null)"); 737 LOG(llevDebug,"Discarding object without arch: %s\n", tmp->name?tmp->name:"(null)");
706 /* This is the actual archetype definition then */ 741 /* This is the actual archetype definition then */
707 else { 742 else {
708 char *yv=yval(); 743 char *yv=yval();
709 744
710 op->arch=find_archetype(yv); 745 op->arch=find_archetype(yv);
711 if (op->arch!=NULL) copy_object(&op->arch->clone,op); 746 if (op->arch!=NULL) {
712 else if (!arch_init) { 747 copy_object(&op->arch->clone,op);
748 } else if (!arch_init) {
713 if (op->name) free_string(op->name); 749 if (op->name) free_string(op->name);
714 /* record the name of the broken object */ 750 /* record the name of the broken object */
715 op->name = add_string(yv); 751 op->name = add_string(yv);
716 } 752 }
717 } 753 }
731^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,
732 * so the calling function can glue things back together 768 * so the calling function can glue things back together
733 */ 769 */
734 ismore=1; 770 ismore=1;
735 } 771 }
736
737^end{WS}$ { check_loaded_object(op); 772^end{WS}$ { check_loaded_object(op);
773
774 if (!arch_init)
775 op->instantiate ();
776
738 if (ismore) return LL_MORE; 777 if (ismore) return LL_MORE;
739 else return LL_NORMAL; 778 else return LL_NORMAL;
740 } 779 }
780^oid{S} {
781 thawer.get (op, IVAL);
782 }
741^last_heal{S} op->last_heal = IVAL; 783^last_heal{S} op->last_heal = IVAL;
742^last_sp{S} op->last_sp = IVAL; 784^last_sp{S} op->last_sp = IVAL;
743^last_grace{S} op->last_grace = IVAL; 785^last_grace{S} op->last_grace = IVAL;
744^last_eat{S} op->last_eat = IVAL; 786^last_eat{S} op->last_eat = IVAL;
745^speed{S} { op->speed = FVAL; 787^speed{S} { op->speed = FVAL;
834^neutral{S} SET_OR_CLEAR_FLAG(op, FLAG_NEUTRAL, IVAL); 876^neutral{S} SET_OR_CLEAR_FLAG(op, FLAG_NEUTRAL, IVAL);
835^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);
836^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);
837^friendly{S} { if (IVAL) { 879^friendly{S} { if (IVAL) {
838 SET_FLAG(op, FLAG_FRIENDLY); 880 SET_FLAG(op, FLAG_FRIENDLY);
839 if (op->type != PLAYER) { 881 if (op->type != PLAYER)
840 LOG(llevDebug," Adding friendly object %s.\n",op->name);
841 add_friendly_object(op); 882 add_friendly_object (op);
842 }
843 } 883 }
844 else CLEAR_FLAG(op, FLAG_FRIENDLY); 884 else CLEAR_FLAG(op, FLAG_FRIENDLY);
845 } 885 }
846^generator{S} SET_OR_CLEAR_FLAG(op, FLAG_GENERATOR, IVAL); 886^generator{S} SET_OR_CLEAR_FLAG(op, FLAG_GENERATOR, IVAL);
847^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);
955^resist_disease{S} SET_RESIST(op, ATNR_DISEASE, IVAL); 995^resist_disease{S} SET_RESIST(op, ATNR_DISEASE, IVAL);
956 996
957 /* Old style resistances */ 997 /* Old style resistances */
958^immune{S} set_protection(op, IVAL, RESIST_IMMUNE); 998^immune{S} set_protection(op, IVAL, RESIST_IMMUNE);
959^protected{S} set_protection(op, IVAL, RESIST_PROT); 999^protected{S} set_protection(op, IVAL, RESIST_PROT);
960^vulnerable{S} set_protection(op, IVAL, RESIST_VULN); 1000^vulnerable{S} set_protection(op, IVAL, (uint16) RESIST_VULN);
961 1001
962 /* 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 */
963^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);
964^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);
965^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);
1004^can_impale{S} { /* That these are for the new combat code */ } 1044^can_impale{S} { /* That these are for the new combat code */ }
1005^can_cut{S} { /* just ignore for now */ } 1045^can_cut{S} { /* just ignore for now */ }
1006^can_dam_armour{S} { } 1046^can_dam_armour{S} { }
1007^weapontype{S} op->weapontype = IVAL; 1047^weapontype{S} op->weapontype = IVAL;
1008^tooltype{S} op->tooltype = IVAL; 1048^tooltype{S} op->tooltype = IVAL;
1009^casting_time{S} op->casting_time = FVAL; 1049^casting_time{S} op->casting_time = (sint16) FVAL;
1010^elevation{S} op->elevation = IVAL; 1050^elevation{S} op->elevation = IVAL;
1011^smoothlevel{S} op->smoothlevel = IVAL; 1051^smoothlevel{S} op->smoothlevel = IVAL;
1012^client_type{S} op->client_type = IVAL; 1052^client_type{S} op->client_type = IVAL;
1013^body_{A} set_body_info(op, yytext); 1053^body_{A} set_body_info(op, yytext);
1014^duration{S} op->duration = IVAL; 1054^duration{S} op->duration = IVAL;
1016^range_modifier{S} op->range_modifier = IVAL; 1056^range_modifier{S} op->range_modifier = IVAL;
1017^dam_modifier{S} op->dam_modifier = IVAL; 1057^dam_modifier{S} op->dam_modifier = IVAL;
1018^duration_modifier{S} op->duration_modifier = IVAL; 1058^duration_modifier{S} op->duration_modifier = IVAL;
1019^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 );
1020 1060
1021^event_apply{S} { 1061^event_ {
1022 char *yv=yval(); 1062 LOG (llevError, "stray event_* in map file, skipping.");
1023 if (*yv=='\0')
1024 LOG(llevError,"Event (apply) without val\n");
1025 else
1026 insert_event(op,EVENT_APPLY,yv,NULL,NULL);
1027} 1063}
1028
1029^event_apply_plugin{S} {
1030 char *yv=yval();
1031 if (*yv=='\0')
1032 LOG(llevError,"Event (apply) without plugin\n");
1033 else
1034 insert_event(op,EVENT_APPLY,NULL,yv,NULL);
1035}
1036
1037^event_apply_options{S} {
1038 char *yv=yval();
1039 if (*yv=='\0')
1040 LOG(llevError,"Event (apply) without options\n");
1041 else
1042 insert_event(op,EVENT_APPLY,NULL,NULL,yv);
1043}
1044
1045^event_attack{S} {
1046 char *yv=yval();
1047 if (*yv=='\0')
1048 LOG(llevError,"Event (attack) without val\n");
1049 else
1050 insert_event(op,EVENT_ATTACK,yv,NULL,NULL);
1051}
1052
1053^event_attack_plugin{S} {
1054 char *yv=yval();
1055 if (*yv=='\0')
1056 LOG(llevError,"Event (attack) without plugin\n");
1057 else
1058 insert_event(op,EVENT_ATTACK,NULL,yv,NULL);
1059}
1060
1061^event_attack_options{S} {
1062 char *yv=yval();
1063 if (*yv=='\0')
1064 LOG(llevError,"Event (attack) without options\n");
1065 else
1066 insert_event(op,EVENT_ATTACK,NULL,NULL,yv);
1067}
1068^event_death{S} {
1069 char *yv=yval();
1070 if (*yv=='\0')
1071 LOG(llevError,"Event (death) without val\n");
1072 else
1073 insert_event(op,EVENT_DEATH,yv,NULL,NULL);
1074}
1075
1076^event_death_plugin{S} {
1077 char *yv=yval();
1078 if (*yv=='\0')
1079 LOG(llevError,"Event (death) without plugin\n");
1080 else
1081 insert_event(op,EVENT_DEATH,NULL,yv,NULL);
1082}
1083
1084^event_death_options{S} {
1085 char *yv=yval();
1086 if (*yv=='\0')
1087 LOG(llevError,"Event (death) without options\n");
1088 else
1089 insert_event(op,EVENT_DEATH,NULL,NULL,yv);
1090}
1091^event_drop{S} {
1092 char *yv=yval();
1093 if (*yv=='\0')
1094 LOG(llevError,"Event (drop) without val\n");
1095 else
1096 insert_event(op,EVENT_DROP,yv,NULL,NULL);
1097}
1098
1099^event_drop_plugin{S} {
1100 char *yv=yval();
1101 if (*yv=='\0')
1102 LOG(llevError,"Event (drop) without plugin\n");
1103 else
1104 insert_event(op,EVENT_DROP,NULL,yv,NULL);
1105}
1106
1107^event_drop_options{S} {
1108 char *yv=yval();
1109 if (*yv=='\0')
1110 LOG(llevError,"Event (drop) without options\n");
1111 else
1112 insert_event(op,EVENT_DROP,NULL,NULL,yv);
1113}
1114^event_pickup{S} {
1115 char *yv=yval();
1116 if (*yv=='\0')
1117 LOG(llevError,"Event (pickup) without val\n");
1118 else
1119 insert_event(op,EVENT_PICKUP,yv,NULL,NULL);
1120}
1121
1122^event_pickup_plugin{S} {
1123 char *yv=yval();
1124 if (*yv=='\0')
1125 LOG(llevError,"Event (pickup) without plugin\n");
1126 else
1127 insert_event(op,EVENT_PICKUP,NULL,yv,NULL);
1128}
1129
1130^event_pickup_options{S} {
1131 char *yv=yval();
1132 if (*yv=='\0')
1133 LOG(llevError,"Event (pickup) without options\n");
1134 else
1135 insert_event(op,EVENT_PICKUP,NULL,NULL,yv);
1136}
1137^event_say{S} {
1138 char *yv=yval();
1139 if (*yv=='\0')
1140 LOG(llevError,"Event (say) without val\n");
1141 else
1142 insert_event(op,EVENT_SAY,yv,NULL,NULL);
1143}
1144
1145^event_say_plugin{S} {
1146 char *yv=yval();
1147 if (*yv=='\0')
1148 LOG(llevError,"Event (say) without plugin\n");
1149 else
1150 insert_event(op,EVENT_SAY,NULL,yv,NULL);
1151}
1152
1153^event_say_options{S} {
1154 char *yv=yval();
1155 if (*yv=='\0')
1156 LOG(llevError,"Event (say) without options\n");
1157 else
1158 insert_event(op,EVENT_SAY,NULL,NULL,yv);
1159}
1160^event_stop{S} {
1161 char *yv=yval();
1162 if (*yv=='\0')
1163 LOG(llevError,"Event (stop) without val\n");
1164 else
1165 insert_event(op,EVENT_STOP,yv,NULL,NULL);
1166}
1167
1168^event_stop_plugin{S} {
1169 char *yv=yval();
1170 if (*yv=='\0')
1171 LOG(llevError,"Event (stop) without plugin\n");
1172 else
1173 insert_event(op,EVENT_STOP,NULL,yv,NULL);
1174}
1175
1176^event_stop_options{S} {
1177 char *yv=yval();
1178 if (*yv=='\0')
1179 LOG(llevError,"Event (stop) without options\n");
1180 else
1181 insert_event(op,EVENT_STOP,NULL,NULL,yv);
1182}
1183^event_time{S} {
1184 char *yv=yval();
1185 if (*yv=='\0')
1186 LOG(llevError,"Event (time) without val\n");
1187 else
1188 insert_event(op,EVENT_TIME,yv,NULL,NULL);
1189}
1190
1191^event_time_plugin{S} {
1192 char *yv=yval();
1193 if (*yv=='\0')
1194 LOG(llevError,"Event (time) without plugin\n");
1195 else
1196 insert_event(op,EVENT_TIME,NULL,yv,NULL);
1197}
1198
1199^event_time_options{S} {
1200 char *yv=yval();
1201 if (*yv=='\0')
1202 LOG(llevError,"Event (time) without options\n");
1203 else
1204 insert_event(op,EVENT_TIME,NULL,NULL,yv);
1205}
1206^event_throw{S} {
1207 char *yv=yval();
1208 if (*yv=='\0')
1209 LOG(llevError,"Event (throw) without val\n");
1210 else
1211 insert_event(op,EVENT_THROW,yv,NULL,NULL);
1212}
1213
1214^event_throw_plugin{S} {
1215 char *yv=yval();
1216 if (*yv=='\0')
1217 LOG(llevError,"Event (throw) without plugin\n");
1218 else
1219 insert_event(op,EVENT_THROW,NULL,yv,NULL);
1220}
1221
1222^event_throw_options{S} {
1223 char *yv=yval();
1224 if (*yv=='\0')
1225 LOG(llevError,"Event (apply) without options\n");
1226 else
1227 insert_event(op,EVENT_THROW,NULL,NULL,yv);
1228}
1229^event_trigger{S} {
1230 char *yv=yval();
1231 if (*yv=='\0')
1232 LOG(llevError,"Event (trigger) without val\n");
1233 else
1234 insert_event(op,EVENT_TRIGGER,yv,NULL,NULL);
1235}
1236
1237^event_trigger_plugin{S} {
1238 char *yv=yval();
1239 if (*yv=='\0')
1240 LOG(llevError,"Event (trigger) without plugin\n");
1241 else
1242 insert_event(op,EVENT_TRIGGER,NULL,yv,NULL);
1243}
1244
1245^event_trigger_options{S} {
1246 char *yv=yval();
1247 if (*yv=='\0')
1248 LOG(llevError,"Event (trigger) without options\n");
1249 else
1250 insert_event(op,EVENT_TRIGGER,NULL,NULL,yv);
1251}
1252^event_close{S} {
1253 char *yv=yval();
1254 if (*yv=='\0')
1255 LOG(llevError,"Event (close) without val\n");
1256 else
1257 insert_event(op,EVENT_CLOSE,yv,NULL,NULL);
1258}
1259
1260^event_close_plugin{S} {
1261 char *yv=yval();
1262 if (*yv=='\0')
1263 LOG(llevError,"Event (close) without plugin\n");
1264 else
1265 insert_event(op,EVENT_CLOSE,NULL,yv,NULL);
1266}
1267
1268^event_close_options{S} {
1269 char *yv=yval();
1270 if (*yv=='\0')
1271 LOG(llevError,"Event (close) without options\n");
1272 else
1273 insert_event(op,EVENT_CLOSE,NULL,NULL,yv);
1274}
1275^event_timer{S} {
1276 char *yv=yval();
1277 if (*yv=='\0')
1278 LOG(llevError,"Event (timer) without val\n");
1279 else
1280 insert_event(op,EVENT_TIMER,yv,NULL,NULL);
1281}
1282
1283^event_timer_plugin{S} {
1284 char *yv=yval();
1285 if (*yv=='\0')
1286 LOG(llevError,"Event (timer) without plugin\n");
1287 else
1288 insert_event(op,EVENT_TIMER,NULL,yv,NULL);
1289}
1290
1291^event_timer_options{S} {
1292 char *yv=yval();
1293 if (*yv=='\0')
1294 LOG(llevError,"Event (timer) without options\n");
1295 else
1296 insert_event(op,EVENT_TIMER,NULL,NULL,yv);
1297}
1298
1299^current_weapon_script{S} { char *yv=yval();
1300
1301 if (*yv=='\0') LOG(llevError,"Script (current weapon) without val\n");
1302 else
1303 {
1304 FREE_AND_COPY(op->current_weapon_script, yv);
1305 };
1306 }
1307 1064
1308<*>(^{WS}$)|\n {/* ignore empty lines, newlines we don't do above */} 1065<*>(^{WS}$)|\n {/* ignore empty lines, newlines we don't do above */}
1309#.*\n {} 1066#.*\n {}
1310 1067
1311<<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 */
1369 * be reset. 1126 * be reset.
1370 * 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)
1371 * 1128 *
1372 */ 1129 */
1373 1130
1374int load_object(FILE *fp, object *op, int bufstate, int map_flags) { 1131int load_object(object_thawer &fp, object *op, int bufstate, int map_flags) {
1375 int retval; 1132 int retval;
1376 char inbuf[MAX_BUF]; 1133 char inbuf[MAX_BUF];
1377 1134
1378 strcpy(msgbuf, ""); 1135 strcpy(msgbuf, "");
1379 strcpy(lorebuf, ""); 1136 strcpy(lorebuf, "");
1385 } 1142 }
1386 if (bufstate==LO_LINEMODE) { 1143 if (bufstate==LO_LINEMODE) {
1387 YY_BUFFER_STATE yybufstate; 1144 YY_BUFFER_STATE yybufstate;
1388 while (fgets(inbuf, MAX_BUF-3, fp)) { 1145 while (fgets(inbuf, MAX_BUF-3, fp)) {
1389 yybufstate=yy_scan_string(inbuf); 1146 yybufstate=yy_scan_string(inbuf);
1390 retval=lex_load(op, map_flags); 1147 retval=lex_load(op, fp, map_flags);
1391 yy_delete_buffer(yybufstate); 1148 yy_delete_buffer(yybufstate);
1392 if (retval==LL_NORMAL) return retval; 1149 if (retval==LL_NORMAL) return retval;
1393 } 1150 }
1394 LOG(llevDebug,"Got eof while scanning strings\n"); 1151 LOG(llevDebug,"Got eof while scanning strings\n");
1395 return LL_EOF; 1152 return LL_EOF;
1396 } 1153 }
1397 1154
1398 retval=lex_load(op, map_flags); 1155 retval=lex_load(op, fp, map_flags);
1399 if (op->current_weapon_script != NULL)
1400 {
1401 op->current_weapon = find_best_weapon_used_match(op, op->current_weapon_script);
1402 LOG(llevDebug, "CurrentWeapon Loaded !\n");
1403 };
1404 1156
1405/* LOG(llevDebug," load completed, object=%s\n",op->name);*/ 1157/* LOG(llevDebug," load completed, object=%s\n",op->name);*/
1406 return retval; 1158 return retval;
1407} 1159}
1408 1160
1414 * override values and in c_wiz to mutate values. 1166 * override values and in c_wiz to mutate values.
1415 */ 1167 */
1416int set_variable(object *op,char *buf) { 1168int set_variable(object *op,char *buf) {
1417 YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER; 1169 YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER;
1418 int retval; 1170 int retval;
1171 object_thawer thawer (0);
1419 1172
1420 strcpy(msgbuf, ""); 1173 strcpy(msgbuf, "");
1421 strcpy(lorebuf, ""); 1174 strcpy(lorebuf, "");
1422 yy_push_state(INITIAL); 1175 yy_push_state(INITIAL);
1423 yybufstate=yy_scan_string(buf); 1176 yybufstate=yy_scan_string(buf);
1424 retval=lex_load(op,0); 1177 retval=lex_load(op,thawer,0);
1425 yy_switch_to_buffer(yycurbuf); 1178 yy_switch_to_buffer(yycurbuf);
1426 yy_delete_buffer(yybufstate); 1179 yy_delete_buffer(yybufstate);
1427 yy_pop_state(); 1180 yy_pop_state();
1428 return retval; 1181 return retval;
1429} 1182}
1484/*For get_ob_diff speed reason*/ 1237/*For get_ob_diff speed reason*/
1485typedef struct { 1238typedef struct {
1486 const char *name; 1239 const char *name;
1487 int length; 1240 int length;
1488}genericname; 1241}genericname;
1489static genericname evtnames[13]=
1490{
1491 {"event_none ",11},
1492 {"event_apply ",12},
1493 {"event_attack ",13},
1494 {"event_death ",12},
1495 {"event_drop ",11},
1496 {"event_pickup ",13},
1497 {"event_say ",10},
1498 {"event_stop ",11},
1499 {"event_time ",11},
1500 {"event_throw ",12},
1501 {"event_trigger ",14},
1502 {"event_close ",12},
1503 {"event_timer ",12}
1504} ;
1505
1506static genericname plgnames[13]=
1507{
1508 {"event_none_plugin ",18},
1509 {"event_apply_plugin ",19},
1510 {"event_attack_plugin ",20},
1511 {"event_death_plugin ",19},
1512 {"event_drop_plugin ",18},
1513 {"event_pickup_plugin ",20},
1514 {"event_say_plugin ",17},
1515 {"event_stop_plugin ",18},
1516 {"event_time_plugin ",18},
1517 {"event_throw_plugin ",19},
1518 {"event_trigger_plugin ",21},
1519 {"event_close_plugin ",19},
1520 {"event_timer_plugin ",19}
1521};
1522
1523static genericname plgoptions[13]=
1524{
1525 {"event_none_options ",19},
1526 {"event_apply_options ",20},
1527 {"event_attack_options ",21},
1528 {"event_death_options ",20},
1529 {"event_drop_options ",19},
1530 {"event_pickup_options ",21},
1531 {"event_say_options ",18},
1532 {"event_stop_options ",19},
1533 {"event_time_options ",19},
1534 {"event_throw_options ",20},
1535 {"event_trigger_options ",22},
1536 {"event_close_options ",20},
1537 {"event_timer_options ",20}
1538};
1539 1242
1540/* This returns a string of the integer movement type */ 1243/* This returns a string of the integer movement type */
1541static char* get_string_move_type(MoveType mt) 1244static char* get_string_move_type(MoveType mt)
1542{ 1245{
1543 static char retbuf[MAX_BUF], retbuf_all[MAX_BUF]; 1246 static char retbuf[MAX_BUF], retbuf_all[MAX_BUF];
1618 * NEVER touch buf between PREPARE_FASTCAT(buf) and 1321 * NEVER touch buf between PREPARE_FASTCAT(buf) and
1619 * FINISH_FASTCAT(buf) 1322 * FINISH_FASTCAT(buf)
1620 */ 1323 */
1621 static int already_run = 0; 1324 static int already_run = 0;
1622 static int flag_lens[NUM_FLAGS]; 1325 static int flag_lens[NUM_FLAGS];
1623 static char buf2[HUGE_BUF]; 1326 char buf2[4096]; // / was HUFE_BUF, which was hugely incorrect, as is this value, but much less so
1624 static char buf[HUGE_BUF]; 1327 static char buf[128*1024]; // < the assumption is that every object always fits. fixing this bug, however
1625 char* fastbuf; 1328 char* fastbuf; // \ requires a large rewrite of the code, so its left to the next total rewrite.
1626 int tmp; 1329 int tmp;
1627 int i; 1330 int i;
1628#if 0
1629/*Memory polluting code. Should help detect problems, very slow*/
1630 for (i=0;i<HUGE_BUF;i++){
1631 buf[i]='a'+(unsigned short)(i%25);
1632 }
1633#endif
1634 event *etmp; 1331 event *etmp;
1635 event *etmp2; 1332 event *etmp2;
1636 key_value * my_field; 1333 key_value * my_field;
1637 key_value * arch_field; 1334 key_value * arch_field;
1638 1335
1704 op->other_arch->name) { 1401 op->other_arch->name) {
1705 ADD_STRINGLINE_ENTRY(fastbuf,"other_arch ",op->other_arch->name,11); 1402 ADD_STRINGLINE_ENTRY(fastbuf,"other_arch ",op->other_arch->name,11);
1706 } 1403 }
1707 if(op->face!=op2->face) { 1404 if(op->face!=op2->face) {
1708 ADD_STRINGLINE_ENTRY(fastbuf,"face ",op->face->name,5); 1405 ADD_STRINGLINE_ENTRY(fastbuf,"face ",op->face->name,5);
1709 }
1710
1711 for(etmp=op->events;etmp!=NULL;etmp=etmp->next)
1712 {
1713 /* First we find the event for the reference object */
1714 etmp2=find_event(op2,etmp->type);
1715 if ((etmp->hook != NULL) && ((etmp2 == NULL) || (etmp2->hook == NULL) || (strcmp(etmp2->hook,etmp->hook))))
1716 /* Either there's no matching event in the reference object,
1717 * or the hook is different */
1718 {
1719 ADD_STRINGLINE_ENTRY(fastbuf,evtnames[etmp->type].name,etmp->hook,evtnames[etmp->type].length);
1720 }
1721 if ((etmp->plugin != NULL) && ((etmp2 == NULL) || (etmp2->plugin == NULL) || (strcmp(etmp2->plugin,etmp->plugin))))
1722 {
1723
1724 ADD_STRINGLINE_ENTRY(fastbuf,plgnames[etmp->type].name,etmp->plugin,plgnames[etmp->type].length);
1725 }
1726 if ((etmp->options != NULL) && ((etmp2 == NULL) || (etmp2->options == NULL) || (strcmp(etmp2->options,etmp->options))))
1727 {
1728 ADD_STRINGLINE_ENTRY(fastbuf,plgoptions[etmp->type].name,etmp->options,plgoptions[etmp->type].length);
1729 }
1730
1731 } 1406 }
1732 1407
1733 if (op->animation_id != op2->animation_id) { 1408 if (op->animation_id != op2->animation_id) {
1734 if (op->animation_id) { 1409 if (op->animation_id) {
1735 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);
1886 if (op->will_apply!=op2->will_apply) 1561 if (op->will_apply!=op2->will_apply)
1887 FAST_SAVE_LONG(fastbuf,"will_apply ",op->will_apply,11); 1562 FAST_SAVE_LONG(fastbuf,"will_apply ",op->will_apply,11);
1888 if(op->smoothlevel!=op2->smoothlevel) 1563 if(op->smoothlevel!=op2->smoothlevel)
1889 FAST_SAVE_LONG(fastbuf,"smoothlevel ",op->smoothlevel,12); 1564 FAST_SAVE_LONG(fastbuf,"smoothlevel ",op->smoothlevel,12);
1890 1565
1891 if (op->current_weapon_script!=op2->current_weapon_script){
1892 ADD_STRINGLINE_ENTRY(fastbuf,"current_weapon_script ",op->current_weapon_script,22);
1893 };
1894
1895 if(op->weapontype && op->weapontype!=op2->weapontype) { 1566 if(op->weapontype && op->weapontype!=op2->weapontype) {
1896 FAST_SAVE_LONG(fastbuf,"weapontype ",op->weapontype,11); 1567 FAST_SAVE_LONG(fastbuf,"weapontype ",op->weapontype,11);
1897 } 1568 }
1898 if(op->tooltype && op->tooltype!=op2->tooltype) { 1569 if(op->tooltype && op->tooltype!=op2->tooltype) {
1899 FAST_SAVE_LONG(fastbuf,"tooltype ",op->tooltype,9); 1570 FAST_SAVE_LONG(fastbuf,"tooltype ",op->tooltype,9);
1969 get_string_move_type(op->move_slow), 1640 get_string_move_type(op->move_slow),
1970 10); 1641 10);
1971 } 1642 }
1972 1643
1973 if (op->move_slow_penalty != op2->move_slow_penalty) { 1644 if (op->move_slow_penalty != op2->move_slow_penalty) {
1974 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);
1975 } 1646 }
1976 1647
1977 if (!COMPARE_FLAGS(op,op2)) { 1648 if (!COMPARE_FLAGS(op,op2)) {
1978 for (tmp=0; tmp <= NUM_FLAGS; tmp++) { 1649 for (tmp=0; tmp <= NUM_FLAGS; tmp++) {
1979 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))) {
2002 * 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.
2003 * 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,
2004 * all of the callers are setting this. 1675 * all of the callers are setting this.
2005 */ 1676 */
2006 1677
2007void save_object(FILE *fp,object *op, int flag) { 1678void save_object(object_freezer &fp,object *op, int flag) {
2008 archetype *at; 1679 archetype *at;
2009 char *cp; 1680 char *cp;
2010 object *tmp,*old; 1681 object *tmp,*old;
2011 1682
2012 /* 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
2013 * still save it. 1684 * still save it.
2014 */ 1685 */
2015 if(op->owner!=NULL || fp == NULL) 1686 if(op->owner!=NULL)
2016 return; 1687 return;
2017 1688
2018 /* 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. */
2019 if(!(flag&1)&&(QUERY_FLAG(op, FLAG_UNPAID))) { 1690 if(!(flag&1)&&(QUERY_FLAG(op, FLAG_UNPAID))) {
2020 return; 1691 return;
2051 if (!(flag&2)) { 1722 if (!(flag&2)) {
2052 remove_ob(op); 1723 remove_ob(op);
2053 free_object (op); 1724 free_object (op);
2054 } 1725 }
2055 1726
1727 fp.put (op);
2056 fprintf(fp,"end\n"); 1728 fprintf(fp,"end\n");
2057}
2058
2059void insert_event(object* op, int etype, char *ehook, char *eplug, char *eoptions)
2060{
2061 event *evt;
2062 event *tmp;
2063
2064 evt = find_event(op,etype);
2065 if (evt == NULL)
2066 {
2067 evt = (event *)malloc(sizeof(event));
2068 evt->next = NULL;
2069 evt->type = etype;
2070 evt->hook = NULL;
2071 evt->plugin = NULL;
2072 evt->options = NULL;
2073 if (op->events==NULL)
2074 {
2075 op->events=evt;
2076 }
2077 else
2078 {
2079 for(tmp=op->events;;tmp=tmp->next)
2080 {
2081 if (tmp->next == NULL)
2082 {
2083 tmp->next = evt;
2084 break;
2085 }
2086 }
2087 }
2088 }
2089 if (ehook != NULL)
2090 FREE_AND_COPY(evt->hook,ehook);
2091 if (eplug != NULL)
2092 FREE_AND_COPY(evt->plugin,eplug);
2093 if (eoptions != NULL)
2094 FREE_AND_COPY(evt->options,eoptions);
2095} 1729}
2096 1730
2097event* find_event(object* op, int etype) 1731event* find_event(object* op, int etype)
2098{ 1732{
2099 event *found; 1733 event *found;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines