--- deliantra/server/common/loader.l 2006/05/11 18:37:20 1.2 +++ deliantra/server/common/loader.l 2006/08/31 06:23:19 1.16 @@ -37,13 +37,13 @@ #include #include -#define YY_DECL int lex_load(object *op, int map_flags) +#define YY_DECL int lex_load(object *op, object_thawer &thawer, int map_flags) static char *yval(); static int lex_error; -static char msgbuf[HUGE_BUF]; -static char lorebuf[HUGE_BUF]; +static char msgbuf[65536]; +static char lorebuf[65536]; /* Maps the MOVE_* values to names */ static const char *const move_name[] = {"walk", "fly_low", "fly_high", "swim", "boat", @@ -59,7 +59,7 @@ * NULL entries in this table are valid - to denote objects that should * not be updated for whatever reason. */ -const char *const spell_mapping[] = { +const char *spell_mapping[] = { "spell_magic_bullet", /* 0 */ "spell_small_fireball", /* 1 */ "spell_medium_fireball", /* 2 */ @@ -327,6 +327,35 @@ LOG(llevError,"set_body_info called with bogus params: %s\n", params); } +// return a suitable strign describign an objetc in enough detail to find it +// used only in check_loaded_object: TODO remove static, move it elsewhere and +// use it in more log messages. +static char *op_debug_info_ (object *op, char *info) +{ + char info2[256 * 3]; + char *p = info; + + p += snprintf (p, 256, "%d=\"%s%s%s\"", + op->count, + op->name ? op->name : "(anon)", + op->title ? " " : "", + op->title ? op->title : ""); + + if (op->env) + p += snprintf (p, 256, "(in %s)", op_debug_info_ (op->env, info2)); + + if (op->map) + p += snprintf (p, 256, "(on %s@%d+%d)", op->map->path, op->x, op->y); + + return info; +} + +static char *op_debug_info (object *op) +{ + static char info[256 * 3]; + + return op_debug_info_ (op, info); +} /* This function checks the object after it has been loaded (when we * get the 'end' in the input stream). This function can be used to @@ -365,11 +394,11 @@ */ if ((op->type == WEAPON || op->type==BOW) && arch_init) { if (!op->skill) { - LOG(llevError,"Weapon %s lacks a skill.\n", op->name); + LOG(llevError,"Weapon %s lacks a skill.\n", op_debug_info (op)); } else if ((!strcmp(op->skill,"one handed weapons") && op->body_info[1] != -1) || (!strcmp(op->skill,"two handed weapons") && op->body_info[1] != -2)) { LOG(llevError,"weapon %s arm usage does not match skill: %d, %s\n", - op->name, op->body_info[1], op->skill); + op_debug_info (op), op->body_info[1], op->skill); } } @@ -384,8 +413,7 @@ (op->type == AMULET ) || (op->type == GIRDLE) || (op->type == BRACERS ) || (op->type == CLOAK)) { if (op->last_heal) { - LOG(llevDebug,"Object %s still has last_heal set, not gen_sp_armour\n", - op->name?op->name:"NULL"); + LOG(llevDebug,"Object %s still has last_heal set, not gen_sp_armour\n", op_debug_info (op)); op->gen_sp_armour = op->last_heal; op->last_heal = 0; } @@ -394,8 +422,7 @@ /* Legacy objects from before item power was in the game */ if (!op->item_power && ip) { if (ip > 3) { - LOG(llevDebug,"Object %s had no item power, using %d\n", - op->name?op->name:"NULL", ip); + LOG(llevDebug,"Object %s had no item power, using %d\n", op_debug_info (op), ip); } op->item_power = ip; } @@ -407,7 +434,7 @@ */ if (ip > 2 *op->item_power && ip > (op->item_power + 3)) { LOG(llevDebug,"Object %s seems to have too low item power? %d > %d\n", - op->name?op->name:"NULL", ip, op->item_power); + op_debug_info (op), ip, op->item_power); } } @@ -440,7 +467,7 @@ if (QUERY_FLAG(op, FLAG_MONSTER)) { if (op->stats.hp > op->stats.maxhp) LOG(llevDebug,"Monster %s has hp set higher than maxhp (%d>%d)\n", - op->name, + op_debug_info (op), op->stats.hp, op->stats.maxhp); /* The archs just need to be updated for this */ @@ -618,13 +645,17 @@ ^msg{WS}$ { BEGIN( MESSAGE ); msgbuf[0]='\0'; } ^endmsg{WS}$ { BEGIN( INITIAL ); - op->msg=add_string(msgbuf); /* Just print a warning so we can be reasonably safe * about not overflowing the buffer. */ - if (strlen(op->msg) > (HUGE_BUF/2)) - LOG(llevDebug, "\n\tWarning message length > %d (max allowed=%d): %d\n>%.80s<\n", - HUGE_BUF/2, HUGE_BUF, strlen(op->msg),op->msg); + if (strlen(msgbuf) >= HUGE_BUF) + { + LOG(llevDebug, "\n\tError message length >= %d: %d\n>%.80s<\n", + HUGE_BUF, strlen(op->msg),op->msg); + op->msg = add_string ("ERROR, please report: string too long, winged.\n"); + } + else + op->msg = add_string (msgbuf); } .* {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); } @@ -664,6 +695,10 @@ if (*yv=='\0') LOG(llevError,"Name without val\n"); else FREE_AND_COPY(op->name_pl, yv); } +^attach{S} { char *yv=yval(); + if (*yv) + op->attach = add_string (yv); + } ^skill{S} FREE_AND_COPY(op->skill,yval()); ^custom_name{S} { char *yv=yval(); @@ -683,18 +718,18 @@ object *tmp; char *yv=yval(); - tmp=get_object(); - tmp->arch = find_archetype(yv); - if (tmp->arch!=NULL) - copy_object(&tmp->arch->clone,tmp); + archetype *arch = find_archetype(yv); + if (arch!=NULL) + tmp = arch_to_object (arch); else { + tmp = get_object (); if (tmp->name) free_string(tmp->name); /* record the name of the broken object */ tmp->name = add_string(yv); } strcpy(msgbuf, ""); strcpy(lorebuf, ""); - lex_load(tmp, map_flags); + lex_load(tmp, thawer, map_flags); if (tmp->arch) { insert_ob_in_ob(tmp,op); } @@ -708,8 +743,9 @@ char *yv=yval(); op->arch=find_archetype(yv); - if (op->arch!=NULL) copy_object(&op->arch->clone,op); - else if (!arch_init) { + if (op->arch!=NULL) { + copy_object(&op->arch->clone,op); + } else if (!arch_init) { if (op->name) free_string(op->name); /* record the name of the broken object */ op->name = add_string(yv); @@ -733,11 +769,17 @@ */ ismore=1; } - ^end{WS}$ { check_loaded_object(op); + + if (!arch_init) + op->instantiate (); + if (ismore) return LL_MORE; else return LL_NORMAL; } +^oid{S} { + thawer.get (op, IVAL); + } ^last_heal{S} op->last_heal = IVAL; ^last_sp{S} op->last_sp = IVAL; ^last_grace{S} op->last_grace = IVAL; @@ -955,7 +997,7 @@ /* Old style resistances */ ^immune{S} set_protection(op, IVAL, RESIST_IMMUNE); ^protected{S} set_protection(op, IVAL, RESIST_PROT); -^vulnerable{S} set_protection(op, IVAL, RESIST_VULN); +^vulnerable{S} set_protection(op, IVAL, (uint16) RESIST_VULN); /* old values - keep them around for now, but they should be removed at some point */ ^has_ready_rod{S} SET_OR_CLEAR_FLAG(op, FLAG_READY_RANGE, IVAL); @@ -1004,7 +1046,7 @@ ^can_dam_armour{S} { } ^weapontype{S} op->weapontype = IVAL; ^tooltype{S} op->tooltype = IVAL; -^casting_time{S} op->casting_time = FVAL; +^casting_time{S} op->casting_time = (sint16) FVAL; ^elevation{S} op->elevation = IVAL; ^smoothlevel{S} op->smoothlevel = IVAL; ^client_type{S} op->client_type = IVAL; @@ -1016,293 +1058,10 @@ ^duration_modifier{S} op->duration_modifier = IVAL; ^is_buildable{S} SET_OR_CLEAR_FLAG( op, FLAG_IS_BUILDABLE, IVAL ); -^event_apply{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (apply) without val\n"); - else - insert_event(op,EVENT_APPLY,yv,NULL,NULL); -} - -^event_apply_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (apply) without plugin\n"); - else - insert_event(op,EVENT_APPLY,NULL,yv,NULL); -} - -^event_apply_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (apply) without options\n"); - else - insert_event(op,EVENT_APPLY,NULL,NULL,yv); -} - -^event_attack{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (attack) without val\n"); - else - insert_event(op,EVENT_ATTACK,yv,NULL,NULL); -} - -^event_attack_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (attack) without plugin\n"); - else - insert_event(op,EVENT_ATTACK,NULL,yv,NULL); -} - -^event_attack_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (attack) without options\n"); - else - insert_event(op,EVENT_ATTACK,NULL,NULL,yv); -} -^event_death{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (death) without val\n"); - else - insert_event(op,EVENT_DEATH,yv,NULL,NULL); -} - -^event_death_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (death) without plugin\n"); - else - insert_event(op,EVENT_DEATH,NULL,yv,NULL); -} - -^event_death_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (death) without options\n"); - else - insert_event(op,EVENT_DEATH,NULL,NULL,yv); -} -^event_drop{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (drop) without val\n"); - else - insert_event(op,EVENT_DROP,yv,NULL,NULL); -} - -^event_drop_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (drop) without plugin\n"); - else - insert_event(op,EVENT_DROP,NULL,yv,NULL); -} - -^event_drop_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (drop) without options\n"); - else - insert_event(op,EVENT_DROP,NULL,NULL,yv); -} -^event_pickup{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (pickup) without val\n"); - else - insert_event(op,EVENT_PICKUP,yv,NULL,NULL); -} - -^event_pickup_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (pickup) without plugin\n"); - else - insert_event(op,EVENT_PICKUP,NULL,yv,NULL); -} - -^event_pickup_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (pickup) without options\n"); - else - insert_event(op,EVENT_PICKUP,NULL,NULL,yv); -} -^event_say{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (say) without val\n"); - else - insert_event(op,EVENT_SAY,yv,NULL,NULL); -} - -^event_say_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (say) without plugin\n"); - else - insert_event(op,EVENT_SAY,NULL,yv,NULL); -} - -^event_say_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (say) without options\n"); - else - insert_event(op,EVENT_SAY,NULL,NULL,yv); -} -^event_stop{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (stop) without val\n"); - else - insert_event(op,EVENT_STOP,yv,NULL,NULL); -} - -^event_stop_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (stop) without plugin\n"); - else - insert_event(op,EVENT_STOP,NULL,yv,NULL); -} - -^event_stop_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (stop) without options\n"); - else - insert_event(op,EVENT_STOP,NULL,NULL,yv); -} -^event_time{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (time) without val\n"); - else - insert_event(op,EVENT_TIME,yv,NULL,NULL); -} - -^event_time_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (time) without plugin\n"); - else - insert_event(op,EVENT_TIME,NULL,yv,NULL); -} - -^event_time_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (time) without options\n"); - else - insert_event(op,EVENT_TIME,NULL,NULL,yv); -} -^event_throw{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (throw) without val\n"); - else - insert_event(op,EVENT_THROW,yv,NULL,NULL); -} - -^event_throw_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (throw) without plugin\n"); - else - insert_event(op,EVENT_THROW,NULL,yv,NULL); -} - -^event_throw_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (apply) without options\n"); - else - insert_event(op,EVENT_THROW,NULL,NULL,yv); -} -^event_trigger{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (trigger) without val\n"); - else - insert_event(op,EVENT_TRIGGER,yv,NULL,NULL); -} - -^event_trigger_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (trigger) without plugin\n"); - else - insert_event(op,EVENT_TRIGGER,NULL,yv,NULL); -} - -^event_trigger_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (trigger) without options\n"); - else - insert_event(op,EVENT_TRIGGER,NULL,NULL,yv); -} -^event_close{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (close) without val\n"); - else - insert_event(op,EVENT_CLOSE,yv,NULL,NULL); -} - -^event_close_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (close) without plugin\n"); - else - insert_event(op,EVENT_CLOSE,NULL,yv,NULL); -} - -^event_close_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (close) without options\n"); - else - insert_event(op,EVENT_CLOSE,NULL,NULL,yv); -} -^event_timer{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (timer) without val\n"); - else - insert_event(op,EVENT_TIMER,yv,NULL,NULL); -} - -^event_timer_plugin{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (timer) without plugin\n"); - else - insert_event(op,EVENT_TIMER,NULL,yv,NULL); -} - -^event_timer_options{S} { - char *yv=yval(); - if (*yv=='\0') - LOG(llevError,"Event (timer) without options\n"); - else - insert_event(op,EVENT_TIMER,NULL,NULL,yv); +^event_ { + LOG (llevError, "stray event_* in map file, skipping."); } -^current_weapon_script{S} { char *yv=yval(); - - if (*yv=='\0') LOG(llevError,"Script (current weapon) without val\n"); - else - { - FREE_AND_COPY(op->current_weapon_script, yv); - }; - } - <*>(^{WS}$)|\n {/* ignore empty lines, newlines we don't do above */} #.*\n {} @@ -1369,7 +1128,7 @@ * */ -int load_object(FILE *fp, object *op, int bufstate, int map_flags) { +int load_object(object_thawer &fp, object *op, int bufstate, int map_flags) { int retval; char inbuf[MAX_BUF]; @@ -1385,7 +1144,7 @@ YY_BUFFER_STATE yybufstate; while (fgets(inbuf, MAX_BUF-3, fp)) { yybufstate=yy_scan_string(inbuf); - retval=lex_load(op, map_flags); + retval=lex_load(op, fp, map_flags); yy_delete_buffer(yybufstate); if (retval==LL_NORMAL) return retval; } @@ -1393,12 +1152,7 @@ return LL_EOF; } - retval=lex_load(op, map_flags); - if (op->current_weapon_script != NULL) - { - op->current_weapon = find_best_weapon_used_match(op, op->current_weapon_script); - LOG(llevDebug, "CurrentWeapon Loaded !\n"); - }; + retval=lex_load(op, fp, map_flags); /* LOG(llevDebug," load completed, object=%s\n",op->name);*/ return retval; @@ -1414,12 +1168,13 @@ int set_variable(object *op,char *buf) { YY_BUFFER_STATE yybufstate,yycurbuf=YY_CURRENT_BUFFER; int retval; + object_thawer thawer (0); strcpy(msgbuf, ""); strcpy(lorebuf, ""); yy_push_state(INITIAL); yybufstate=yy_scan_string(buf); - retval=lex_load(op,0); + retval=lex_load(op,thawer,0); yy_switch_to_buffer(yycurbuf); yy_delete_buffer(yybufstate); yy_pop_state(); @@ -1618,17 +1373,11 @@ */ static int already_run = 0; static int flag_lens[NUM_FLAGS]; - static char buf2[HUGE_BUF]; - static char buf[HUGE_BUF]; - char* fastbuf; + char buf2[4096]; // / was HUFE_BUF, which was hugely incorrect, as is this value, but much less so + static char buf[128*1024]; // < the assumption is that every object always fits. fixing this bug, however + char* fastbuf; // \ requires a large rewrite of the code, so its left to the next total rewrite. int tmp; int i; -#if 0 -/*Memory polluting code. Should help detect problems, very slow*/ - for (i=0;ismoothlevel!=op2->smoothlevel) FAST_SAVE_LONG(fastbuf,"smoothlevel ",op->smoothlevel,12); - if (op->current_weapon_script!=op2->current_weapon_script){ - ADD_STRINGLINE_ENTRY(fastbuf,"current_weapon_script ",op->current_weapon_script,22); - }; - if(op->weapontype && op->weapontype!=op2->weapontype) { FAST_SAVE_LONG(fastbuf,"weapontype ",op->weapontype,11); } @@ -1969,7 +1714,7 @@ } if (op->move_slow_penalty != op2->move_slow_penalty) { - FAST_SAVE_LONG(fastbuf,"move_slow_penalty ",op->move_slow_penalty,18); + FAST_SAVE_LONG(fastbuf,"move_slow_penalty ",(long) op->move_slow_penalty,18); } if (!COMPARE_FLAGS(op,op2)) { @@ -2002,7 +1747,7 @@ * all of the callers are setting this. */ -void save_object(FILE *fp,object *op, int flag) { +void save_object(object_freezer &fp,object *op, int flag) { archetype *at; char *cp; object *tmp,*old; @@ -2010,7 +1755,7 @@ /* Even if the object does have an owner, it would seem that we should * still save it. */ - if(op->owner!=NULL || fp == NULL) + if(op->owner!=NULL) return; /* If it is unpaid and we don't want to save those, just return. */ @@ -2051,6 +1796,7 @@ free_object (op); } + fp.put (op); fprintf(fp,"end\n"); }