--- deliantra/server/common/loader.C 2009/11/11 18:06:46 1.147 +++ deliantra/server/common/loader.C 2010/01/16 13:41:37 1.151 @@ -1,7 +1,7 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team * Copyright (©) 1992,2007 Frank Tore Johansen * @@ -23,7 +23,6 @@ */ #include -#include #include ///////////////////////////////////////////////////////////////////////////// @@ -335,6 +334,13 @@ if (material == MATERIAL_NULL && !(is_weapon () && level > 0)) select_material (this, map ? map->difficulty : 5); + if (speed < 0.) + { + flag [FLAG_RANDOM_SPEED] = true; + speed = -speed; + // speed_left will be randomised in instantiate () and copy_to () + } + /* only do these when program is first run - a bit * excessive to do this at every run - most of this is * really just to catch any errors - program will still run, but @@ -482,7 +488,7 @@ } static void -set_move (MoveType &mt, const char *str) +set_move (MoveType &mt, object_thawer &f) { static const struct flagstr { const char *name; @@ -498,13 +504,9 @@ { "all" , MOVE_ALL }, }; - if (!str) - { - mt = 0; - return; - } + const char *str = f.get_str (); - if (isdigit (*str)) + if (!*str || isdigit (*str)) { mt = atoi (str); return; @@ -512,7 +514,7 @@ mt = 0; - for (str = strtok ((char *) str, " "); str; str = strtok (0, " ")) + for (str = strtok ((char *)str, " "); str; str = strtok (0, " ")) { bool negate = 0; @@ -556,12 +558,11 @@ switch (f.kw) { case KW_uuid: - if (const char *s = f.get_str ()) - if (!uuid.parse (s)) - { - f.parse_warn ("unparseable uuid"); - uuid = UUID::gen (); - } + if (!uuid.parse (f.get_str ())) + { + f.parse_warn ("unparseable uuid"); + uuid = UUID::gen (); + } break; case KW_oid: @@ -636,8 +637,7 @@ CLEAR_FLAG (this, FLAG_ANIMATE); animation_id = 0; - const char *str = f.get_str (); - if (str && (animation_id = find_animation (str))) + if (f.has_value () && (animation_id = find_animation (f.get_str ()))) SET_FLAG (this, FLAG_ANIMATE); //TODO: should not be forced to true here } break; @@ -646,6 +646,7 @@ case KW_last_sp: f.get (last_sp); break; case KW_last_grace: f.get (last_grace); break; case KW_last_eat: f.get (last_eat); break; + case KW_sl: case KW_speed_left: f.get (speed_left); break; case KW_speed: @@ -664,19 +665,29 @@ break; case KW_face: - face = face_find (f.get_str ()); + face = f.has_value () ? face_find (f.get_str ()) : blank_face; break; case KW_sound: - sound = sound_find (f.get_str ()); - if (!sound) - f.parse_warn ("sound not found"); + if (f.has_value ()) + { + sound = sound_find (f.get_str ()); + if (!sound) + f.parse_warn (format ("sound '%s' not found", f.get_str ())); + } + else + sound = 0; break; case KW_sound_destroy: - sound_destroy = sound_find (f.get_str ()); - if (!sound_destroy) - f.parse_warn ("sound not found"); + if (f.has_value ()) + { + sound_destroy = sound_find (f.get_str ()); + if (!sound_destroy) + f.parse_warn (format ("sound '%s' not found", f.get_str ())); + } + else + sound_destroy = 0; break; case KW_x: f.get (x); break; @@ -737,12 +748,12 @@ break; /* These are the new values */ - case KW_move_block: set_move (move_block, f.get_str ()); break; - case KW_move_allow: set_move (move_allow, f.get_str ()); break; - case KW_move_type: set_move (move_type, f.get_str ()); break; - case KW_move_on: set_move (move_on, f.get_str ()); break; - case KW_move_off: set_move (move_off, f.get_str ()); break; - case KW_move_slow: set_move (move_slow, f.get_str ()); break; + case KW_move_block: set_move (move_block, f); break; + case KW_move_allow: set_move (move_allow, f); break; + case KW_move_type: set_move (move_type , f); break; + case KW_move_on: set_move (move_on , f); break; + case KW_move_off: set_move (move_off , f); break; + case KW_move_slow: set_move (move_slow , f); break; /* These are all legacy - any new objects should use the move_ .. values */ case KW_no_pass: @@ -914,6 +925,7 @@ case KW_destroy_on_death: GET_FLAG (this, FLAG_DESTROY_ON_DEATH); break; case KW_treasure_env: GET_FLAG (this, FLAG_TREASURE_ENV); break; case KW_precious: GET_FLAG (this, FLAG_PRECIOUS); break; + case KW_random_speed: GET_FLAG (this, FLAG_RANDOM_SPEED); break; case KW_armour: f.get (resist[ATNR_PHYSICAL]); break; case KW_resist_physical: f.get (resist[ATNR_PHYSICAL]); break; @@ -998,7 +1010,7 @@ break; case KW_randomitems: - if (f.get_str ()) + if (f.has_value ()) { randomitems = loading_arch @@ -1244,7 +1256,7 @@ KW_no_attack, KW_no_damage, KW_obj_original, - KW_NULL, + KW_random_speed, KW_activate_on_push, KW_activate_on_release, KW_is_water, @@ -1289,8 +1301,8 @@ f.alloc (ptr - cur); } -#define CMP_OUT(v) if (expect_false (op->v != arch->v)) f.put (KW_ ## v, op->v) -#define CMP_OUT2(k,v) if (expect_false (op->v != arch->v)) f.put (KW_ ## k, op->v) +#define CMP_OUT(v) if (expect_false (op->v != arch->v)) f.put (KW (v), op->v) +#define CMP_OUT2(k,v) if (expect_false (op->v != arch->v)) f.put (KW (k), op->v) CMP_OUT (x); CMP_OUT (y); @@ -1301,7 +1313,6 @@ CMP_OUT (name); CMP_OUT (name_pl); - CMP_OUT (speed); // speed_left is a major time-burner, and has good locality, so @@ -1309,14 +1320,14 @@ if (op->speed_left != arch->speed_left) { static double last_speed_left = 0.; - static char last_speed_left_str [256] = "speed_left 0\n"; - static int last_speed_left_len = sizeof ("speed_left 0\n") - 1; + static char last_speed_left_str [256] = "sl 0\n"; + static int last_speed_left_len = sizeof ("sl 0\n") - 1; if (last_speed_left != op->speed_left) { last_speed_left = op->speed_left; - last_speed_left_len = sizeof ("speed_left ") - 1 - + sprintf (last_speed_left_str + sizeof ("speed_left ") - 1, "%.7g\n", last_speed_left); + last_speed_left_len = sizeof ("sl ") - 1 + + sprintf (last_speed_left_str + sizeof ("sl ") - 1, "%.7g\n", last_speed_left); } f.add (last_speed_left_str, last_speed_left_len); @@ -1331,25 +1342,25 @@ CMP_OUT (custom_name); if (object *owner = op->owner) - f.put (KW_owner, static_cast(owner->ref ())); + f.put (KW(owner), static_cast(owner->ref ())); // memory, attacked_by, chosen_skill, spellitem, spell, current_weapon, arch not saved CMP_OUT (other_arch); - if (op->msg != arch->msg ) f.put (KW_msg , KW_endmsg , op->msg ); - if (op->lore != arch->lore) f.put (KW_lore, KW_endlore, op->lore); + if (op->msg != arch->msg ) f.put (KW(msg) , KW(endmsg) , op->msg ); + if (op->lore != arch->lore) f.put (KW(lore), KW(endlore), op->lore); - if (op->face != arch->face ) f.put (KW_face , op->face ? &faces [op->face ] : 0); - if (op->sound != arch->sound ) f.put (KW_sound , op->sound ? &faces [op->sound ] : 0); - if (op->sound_destroy != arch->sound_destroy) f.put (KW_sound_destroy, op->sound_destroy ? &faces [op->sound_destroy] : 0); + if (op->face != arch->face ) f.put (KW(face) , op->face ? &faces [op->face ] : 0); + if (op->sound != arch->sound ) f.put (KW(sound) , op->sound ? &faces [op->sound ] : 0); + if (op->sound_destroy != arch->sound_destroy) f.put (KW(sound_destroy), op->sound_destroy ? &faces [op->sound_destroy] : 0); if (op->animation_id != arch->animation_id) if (op->has_anim ()) - f.put (KW_animation, op->anim ().name); + f.put (KW(animation), op->anim ().name); else { - f.put (KW_animation, (const char *)0); + f.put (KW(animation)); op->flag [FLAG_ANIMATE] = false; // TODO: why force to false here? } @@ -1395,7 +1406,7 @@ CMP_OUT2 (material, materials);//TODO: nuke if (op->material != arch->material) - f.put (KW_materialname, op->material->name); + f.put (KW(materialname), op->material->name); CMP_OUT (value); CMP_OUT (carrying); @@ -1411,9 +1422,10 @@ if (op->flag [FLAG_IS_LINKED]) if (auto (ol, op->find_link ())) - f.put (KW_connected, ol->id); + f.put (KW(connected), ol->id); CMP_OUT (randomitems); + CMP_OUT2 (container, weight_limit); CMP_OUT (run_away); @@ -1441,7 +1453,7 @@ object::flags_t diff = (op->flag ^ arch->flag) & flagmask; if (diff [FLAG_OBJ_ORIGINAL]) - f.put (flag_names [FLAG_OBJ_ORIGINAL], op->flag [FLAG_OBJ_ORIGINAL] ? "1" : "0"); + f.put (flag_names [FLAG_OBJ_ORIGINAL], op->flag [FLAG_OBJ_ORIGINAL] ? CS(1) : CS(0)); diff.reset (FLAG_OBJ_ORIGINAL); @@ -1449,7 +1461,7 @@ if (expect_true (diff.any ())) for (int i = 0; i < NUM_FLAGS; i++) if (expect_false (diff [i])) - f.put (flag_names [i], op->flag [i] ? "1" : "0"); + f.put (flag_names [i], op->flag [i] ? CS(1) : CS(0)); // save body locations. gcc's memcmp does an abysmal job when used for (int i = 0; i < NUM_BODY_LOCATIONS; i++) @@ -1465,14 +1477,14 @@ bool object::write (object_freezer &f) { - if (is_arch ()) + if (expect_false (is_arch ())) { - f.put (KW_object, arch->archname); + f.put (KW(object), arch->archname); write_diff (f, this, archetype::empty); } else { - f.put (KW_arch, arch->archname); + f.put (KW(arch), arch->archname); write_diff (f, this, arch); } @@ -1480,7 +1492,7 @@ tmp->write (f); f.put (this); - f.put (KW_end); + f.put (KW(end)); return true; }