--- deliantra/server/common/loader.C 2006/12/18 02:35:00 1.24 +++ deliantra/server/common/loader.C 2007/01/11 01:10:01 1.44 @@ -1,6 +1,7 @@ /* CrossFire, A Multiplayer game for X-windows + Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team Copyright (C) 2002 Mark Wedel & Crossfire Development Team Copyright (C) 1992 Frank Tore Johansen @@ -265,9 +266,9 @@ { int ip; - /* We do some specialized handling to handle legacy cases of name_pl. + /* We do some specialised handling to handle legacy cases of name_pl. * If the object doesn't have a name_pl, we just use the object name - - * this isn't perfect (things won't be properly pluralized), but works to + * this isn't perfect (things won't be properly pluralised), but works to * that degree (5 heart is still quite understandable). But the case we * also have to catch is if this object is not using the normal name for * the object. In that case, we also want to use the loaded name. @@ -281,7 +282,7 @@ op->name_pl = op->name; /* objects now have a materialname. try to patch it in */ - if (!(IS_WEAPON (op) && op->level > 0)) + if (!(op->is_weapon () && op->level > 0)) { if (op->map != NULL) set_materialname (op, op->map->difficulty, NULL); @@ -322,10 +323,8 @@ op->gen_sp_armour = op->last_heal; op->last_heal = 0; } - if (editor) - ip = 0; - else - ip = calc_item_power (op, 0); + + ip = calc_item_power (op, 0); /* Legacy objects from before item power was in the game */ if (!op->item_power && ip) { @@ -489,7 +488,7 @@ CLEAR_FLAG (op, flag) \ int -parse_object (object *op, object_thawer & thawer, int map_flags) +parse_object (object *op, object_thawer &thawer, int map_flags) { bool ismore = 0; object *op_inv = op->inv; @@ -504,7 +503,7 @@ case KW_object: thawer.get (op->name); - if (op->arch != NULL) + if (op->arch) op->arch->name = op->name; break; @@ -553,7 +552,7 @@ object *tmp; - if (arch != NULL) + if (arch) tmp = arch_to_object (arch); else { @@ -562,6 +561,11 @@ tmp->name = str; } + // decativate the object we, as we are still going + // to read the speed value. Objects should be activated + // when the map, object or player is completly loaded. + tmp->deactivate (); + parse_object (tmp, thawer, map_flags); if (tmp->arch) @@ -603,7 +607,11 @@ op->arch = archetype::find (str); if (op->arch) - op->arch->clone.copy_to (op); + { + op->arch->clone.copy_to (op); + // copy_to activates, this should be fixed properly + op->deactivate (); + } else if (!arch_init) /* record the name of the broken object */ op->name = str; @@ -643,13 +651,9 @@ thawer.get (op->speed); //TODO: maybe do in check_object - if (!(map_flags & MAP_STYLE)) - { - if (op->speed < 0) - op->speed_left = op->speed_left - RANDOM () % 100 / 100.0; - - update_ob_speed (op); - } + // removed check for style maps + if (op->speed < 0) + op->speed_left = op->speed_left - RANDOM () % 100 / 100.0; break; @@ -813,21 +817,21 @@ break; case KW_friendly: - GET_FLAG (op, FLAG_FRIENDLY); - //TODO: move to check_object or so - if (op->type != PLAYER && QUERY_FLAG (op, FLAG_FRIENDLY)) - add_friendly_object (op); + if (thawer.get_sint32 ()) + if (op->type != PLAYER) + add_friendly_object (op); + break; case KW_monster: GET_FLAG (op, FLAG_MONSTER); break; case KW_neutral: GET_FLAG (op, FLAG_NEUTRAL); break; case KW_no_attack: GET_FLAG (op, FLAG_NO_ATTACK); break; case KW_no_damage: GET_FLAG (op, FLAG_NO_DAMAGE); break; + case KW_obj_original: GET_FLAG (op, FLAG_OBJ_ORIGINAL); break; case KW_generator: GET_FLAG (op, FLAG_GENERATOR); break; case KW_use_content_on_gen: GET_FLAG (op, FLAG_CONTENT_ON_GEN); break; case KW_is_thrown: GET_FLAG (op, FLAG_IS_THROWN); break; case KW_auto_apply: GET_FLAG (op, FLAG_AUTO_APPLY); break; - case KW_treasure: GET_FLAG (op, FLAG_TREASURE); break; case KW_see_invisible: GET_FLAG (op, FLAG_SEE_INVISIBLE); break; case KW_can_roll: GET_FLAG (op, FLAG_CAN_ROLL); break; case KW_overlay_floor: GET_FLAG (op, FLAG_OVERLAY_FLOOR); break; @@ -904,6 +908,7 @@ case KW_one_hit: GET_FLAG (op, FLAG_ONE_HIT); break; case KW_berserk: GET_FLAG (op, FLAG_BERSERK); break; case KW_is_buildable: GET_FLAG (op, FLAG_IS_BUILDABLE); break; + case KW_destroy_on_death: GET_FLAG (op, FLAG_DESTROY_ON_DEATH); break; case KW_armour: thawer.get (op->resist[ATNR_PHYSICAL]); break; case KW_resist_physical: thawer.get (op->resist[ATNR_PHYSICAL]); break; @@ -983,30 +988,24 @@ break; case KW_msg: - { - thawer.get_ml (KW_endmsg, op->msg); - //TODO: allow longer messages - if (strlen (op->msg) >= HUGE_BUF) - { - LOG (llevDebug, "\n\tError message length >= %d: %d\n>%.80s<\n", HUGE_BUF, strlen (op->msg), &op->msg); - op->msg = "ERROR, please report: string too long, winged.\n"; - } - } + thawer.get_ml (KW_endmsg, op->msg); + //TODO: allow longer messages + if (strlen (op->msg) >= HUGE_BUF) + { + LOG (llevDebug, "\tError message length >= %d: %d\n>%.80s<\n", HUGE_BUF, strlen (op->msg), &op->msg); + op->msg = "ERROR, please report: string too long, winged.\n"; + } break; case KW_lore: - { - shstr msgbuf; - - thawer.get_ml (KW_endlore, op->lore); - //TODO: allow longer messages - /* Just print a warning so we can be reasonably safe - * about not overflowing the buffer. - */ - if (strlen (op->lore) > (HUGE_BUF / 2)) - LOG (llevDebug, "\n\tWarning lore length > %d (max allowed=%d): %d\n>%.80s<\n", - HUGE_BUF / 2, HUGE_BUF, strlen (op->lore), &op->lore); - } + thawer.get_ml (KW_endlore, op->lore); + //TODO: allow longer messages + /* Just print a warning so we can be reasonably safe + * about not overflowing the buffer. + */ + if (strlen (op->lore) > (HUGE_BUF / 2)) + LOG (llevDebug, "\tWarning lore length > %d (max allowed=%d): %d\n>%.80s<\n", + HUGE_BUF / 2, HUGE_BUF, strlen (op->lore), &op->lore); break; case KW_editable: @@ -1033,15 +1032,8 @@ return LL_EOF; case KW_ERROR: - set_ob_key_value (op, thawer.line, thawer.last_value, true); - //printf ("addkv(%s,%s)\n", thawer.line, thawer.get_str());//D - - //TODO: skip line, ugly, factor parsing better - if (thawer.last_value) - thawer.line = thawer.last_value; - - thawer.line += strlen (thawer.line) + 1; - + set_ob_key_value (op, thawer.last_keyword, thawer.last_value, true); + //fprintf (stderr, "addkv(%s,%s)\n", thawer.last_keyword, thawer.last_value);//D break; default: @@ -1065,14 +1057,14 @@ * LO_NOREAD (3): Reset the buffers, but don't read from it. (op can be null) * */ - int -load_object (object_thawer & fp, object *op, int map_flags) +load_object (object_thawer &fp, object *op, int map_flags) { + coroapi::cede_every (1000); // cede once in a while + return parse_object (op, fp, map_flags); } - /* This takes a buffer, scans it for variables, and sets those variables * as appropriate in op. * @@ -1184,7 +1176,7 @@ KW_generator, KW_is_thrown, KW_auto_apply, - KW_treasure, + KW_NULL, // was KW_treasure KW_player_sold, /* 20 */ KW_see_invisible, @@ -1277,7 +1269,7 @@ /* 100 */ KW_no_attack, KW_no_damage, - KW_NULL, + KW_obj_original, KW_NULL, KW_activate_on_push, KW_activate_on_release, @@ -1286,6 +1278,8 @@ KW_NULL, KW_is_buildable, /* 110 */ + KW_destroy_on_death, + KW_NULL, }; int i; @@ -1293,7 +1287,7 @@ /* This saves the key/value lists. We do it first so that any * keys that match field names will be overwritten by the loader. */ - for (key_value *my_field = op->key_values; my_field != NULL; my_field = my_field->next) + for (key_value *my_field = op->key_values; my_field; my_field = my_field->next) { /* Find the field in the opposing member. */ key_value *arch_field = get_ob_key_link (tmp, my_field->key); @@ -1431,10 +1425,10 @@ CMP_OUT (move_slow); CMP_OUT (move_slow_penalty); - if (op->flags != tmp->flags) + if (op->flag != tmp->flag) for (i = 0; i <= NUM_FLAGS; i++) - if (flag_names[i] && (QUERY_FLAG (op, i) != QUERY_FLAG (tmp, i))) - f.put (flag_names[i], QUERY_FLAG (op, i) ? "1" : "0"); + if (flag_names [i] && op->flag [i] != tmp->flag [i]) + f.put (flag_names [i], op->flag [i] ? "1" : "0"); /* Save body locations */ for (i = 0; i < NUM_BODY_LOCATIONS; i++) @@ -1446,16 +1440,10 @@ * Dumps all variables in an object to a file. * If bit 0 of flag is set, unpaid objects will be saved. As of now, * the only place this is not set is when saving the player. - * If bit 1 of flag is set, don't remove the object after save. As of now, - * all of the callers are setting this. */ - void -save_object (object_freezer & fp, object *op, int flag) +save_object (object_freezer &fp, object *op, int flag) { - archetype *at; - object *tmp, *old; - /* Even if the object does have an owner, it would seem that we should * still save it. */ @@ -1463,45 +1451,20 @@ return; /* If it is unpaid and we don't want to save those, just return. */ - if (!(flag & 1) && (QUERY_FLAG (op, FLAG_UNPAID))) + if (!(flag & 1) && op->flag [FLAG_UNPAID]) return; - if ((at = op->arch) == NULL) - at = empty_archetype; + archetype *at = op->arch ? (archetype *)op->arch : empty_archetype; fp.put (KW_arch, at->name); - put (fp, op, &at->clone); /* Eneq(@csd.uu.se): Added this to allow containers being saved with contents */ - old = NULL; - - if (flag & 2) - for (tmp = op->inv; tmp != NULL; tmp = tmp->below) - save_object (fp, tmp, flag); - else - /* Slightly different logic because tmp/op will be removed by - * the save_object we call. So we just keep looking at op->inv - * until there is nothing left. In theory, the variable old - * should not be needed, as recursive loops shouldn't happen. - */ - while ((tmp = op->inv) != NULL) - { - if (old == tmp) - { - LOG (llevError, " Recursive loop in inventory\n"); - break; - } - - save_object (fp, tmp, flag); - old = tmp; - } - - if (!(flag & 2)) - op->destroy (); + for (object *tmp = op->inv; tmp; tmp = tmp->below) + save_object (fp, tmp, flag); fp.put (op); - fprintf (fp, "end\n"); + fp.put (KW_end); }