--- deliantra/server/common/loader.C 2008/04/20 05:24:55 1.110 +++ deliantra/server/common/loader.C 2008/05/06 16:32:34 1.116 @@ -21,10 +21,6 @@ * The authors can be reached via e-mail to */ -/* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects. - sub/add_weight will transcend the environment updating the carrying - variable. */ - #include #include #include @@ -411,7 +407,7 @@ LOG (llevError, "spellbook/rune found without inv but slaying: %s", debug_desc ()); object *tmp = get_archetype_by_object_name (slaying); insert_ob_in_ob (tmp, this); - randomitems = NULL; /* So another spell isn't created for this object */ + randomitems = 0; /* So another spell isn't created for this object */ /* without this, value is all screwed up */ value = arch->value * inv->value; } @@ -525,6 +521,7 @@ object::parse_kv (object_thawer &f) { object *op_inv = inv; + key_value *last_kv = key_values; for (;;) { @@ -612,7 +609,7 @@ const char *str = f.get_str (); if (str && (animation_id = find_animation (str))) - SET_FLAG (this, FLAG_ANIMATE); + SET_FLAG (this, FLAG_ANIMATE); //TODO: should not be forced to true here } break; @@ -993,7 +990,26 @@ return true; case KW_ERROR: - set_ob_key_value (this, f.kw_str, f.value, true); + // append as key value pair (do not use kv_set as it prepends) + // we also do not even try to find old values, duplicate keys stay duplicate + { + key_value *kv = new key_value; + + kv->next = 0; + kv->key = shstr (f.kw_str); + kv->value = shstr (f.value); + + if (!last_kv) + key_values = last_kv = kv; + else + { + while (last_kv->next) + last_kv = last_kv->next; + + last_kv->next = kv; + last_kv = kv; + } + } //fprintf (stderr, "addkv(%s,%s)\n", f.kw_str, f.value);//D break; @@ -1024,11 +1040,9 @@ f.next (); - object *op = object::create (); - + object *op = arch->instance (); op->map = map; - arch->copy_to (op); - // copy_to activates, this should be fixed properly + // instance() activates, this should be fixed properly op->deactivate (); if (!op->parse_kv (f)) @@ -1248,20 +1262,12 @@ KW_NULL, }; - int i; - /* 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; my_field = my_field->next) - { - /* Find the field in the opposing member. */ - key_value *arch_field = get_ob_key_link (tmp, my_field->key); - - /* If there's no partnering field, or it's got a different value, save our field. */ - if (!arch_field || my_field->value != arch_field->value) - f.put (my_field->key, my_field->value); - } + for (key_value *kv = op->key_values; kv; kv = kv->next) + if (!tmp->key_values || tmp->kv (kv->key) != kv->value) + f.put (kv->key, kv->value); /* We don't need to worry about the arch's extra fields - they * will get taken care of the copy_to method. @@ -1280,6 +1286,7 @@ CMP_OUT (custom_name); CMP_OUT (title); CMP_OUT (race); + CMP_OUT (skill); CMP_OUT (slaying); CMP_OUT (tag); CMP_OUT (other_arch); @@ -1293,14 +1300,12 @@ if (op->animation_id != tmp->animation_id) if (op->animation_id) + f.put (KW_animation, animations[GET_ANIM_ID (op)].name); + else { - f.put (KW_animation, animations[GET_ANIM_ID (op)].name); - - if (!QUERY_FLAG (op, FLAG_ANIMATE)) - f.put (KW_is_animated, (sint32)0); + f.put (KW_animation, (const char *)0); + op->flag [FLAG_ANIMATE] = false; // TODO: why force to false here? } - else - f.put (KW_animation, (const char *)0); CMP_OUT2 (str, stats.Str); CMP_OUT2 (dex, stats.Dex); @@ -1340,7 +1345,7 @@ CMP_OUT (subtype); CMP_OUT (attacktype); - for (i = 0; i < NROFATTACKS; i++) + for (int i = 0; i < NROFATTACKS; i++) if (expect_false (op->resist[i] != tmp->resist[i])) f.put (resist_save[i], op->resist[i]); @@ -1361,8 +1366,9 @@ CMP_OUT (last_eat); CMP_OUT (glow_radius); - if (QUERY_FLAG (op, FLAG_IS_LINKED) && (i = get_button_value (op))) - f.put (KW_connected, i); + if (op->flag [FLAG_IS_LINKED]) + if (int i = get_button_value (op)) + f.put (KW_connected, i); CMP_OUT (randomitems); CMP_OUT2 (container, weight_limit); @@ -1392,12 +1398,12 @@ CMP_OUT (move_slow_penalty); if (op->flag != tmp->flag) - for (i = 0; i <= NUM_FLAGS; i++) + for (int i = 0; i <= NUM_FLAGS; i++) if (expect_false (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++) + for (int i = 0; i < NUM_BODY_LOCATIONS; i++) if (expect_false (op->slot[i].info != tmp->slot[i].info)) f.put (body_locations[i].save_name, op->slot[i].info); }