--- deliantra/server/common/object.C 2008/04/21 06:16:01 1.208 +++ deliantra/server/common/object.C 2008/04/21 23:35:24 1.212 @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -353,7 +352,14 @@ { weight = weight_adjust (op, weight); + if (!weight) + return; + op->carrying += weight; + + if (object *pl = op->visible_to ()) + esrv_update_item (UPD_WEIGHT, pl, op); + op = op->env; } } @@ -376,7 +382,15 @@ sum += op->total_weight (); } - carrying = weight_adjust (this, sum); + sum = weight_adjust (this, sum); + + if (sum != carrying) + { + carrying = sum; + + if (object *pl = visible_to ()) + esrv_update_item (UPD_WEIGHT, pl, this); + } } /* @@ -918,6 +932,9 @@ void object::do_destroy () { + if (object *pl = visible_to ()) + esrv_del_item (pl->contr, count); + attachable::do_destroy (); if (flag [FLAG_IS_LINKED]) @@ -1479,73 +1496,34 @@ return where->map->insert (this, where->x, where->y, originator, flags); } -/* - * get_split_ob(ob,nr) splits up ob into two parts. The part which - * is returned contains nr objects, and the remaining parts contains - * the rest (or is removed and freed if that number is 0). - * On failure, NULL is returned, and the reason put into the - * global static errmsg array. - */ -object * -object::split_nr (sint32 nr) -{ - if (nrof < nr) - return 0; - else if (nrof == nr) - { - remove (); - return this; - } - else - { - decrease_nr (nr); - - object *op = object_create_clone (this); - op->nrof = nr; - return op; - } -} - -//TODO: remove, but semantics differs from split_nr -object * -get_split_ob (object *orig_ob, uint32 nr) -{ - if (orig_ob->nrof < nr) - { - sprintf (errmsg, "There are only %d %ss.", orig_ob->nrof ? orig_ob->nrof : 1, &orig_ob->name); - return 0; - } - - return orig_ob->split_nr (nr); -} - // find player who can see this object -static object * -visible_to (object *op) +object * +object::visible_to () const { - if (!op->flag [FLAG_REMOVED]) + if (!flag [FLAG_REMOVED]) { // see if we are in a container of sorts - if (object *env = op->env) + if (env) { // the player inventory itself is always visible if (env->type == PLAYER) return env; // else a player could have our env open - env = env->outer_env (); + object *envest = env->outer_env (); // the player itself is always on a map, so we will find him here // even if our inv is in a player. - if (env->is_on_map ()) - if (object *pl = env->ms ().player ()) - if (pl->container == op->env) + if (envest->is_on_map ()) + if (object *pl = envest->ms ().player ()) + if (pl->container == env) return pl; } else { // maybe there is a player standing on the same mapspace - if (object *pl = env->ms ().player ()) + // this will catch the case where "this" is a player + if (object *pl = ms ().player ()) return pl; } } @@ -1554,48 +1532,64 @@ } /* - * decrease_ob_nr(object, number) decreases a specified number from + * decrease(object, number) decreases a specified number from * the amount of an object. If the amount reaches 0, the object * is subsequently removed and freed. * * Return value: 'op' if something is left, NULL if the amount reached 0 */ bool -object::decrease_nr (sint32 nr) +object::decrease (sint32 nr) { - nr = min (nr, nrof); - if (!nr) - return 1; + return true; - nrof -= nr; + nr = min (nr, nrof); - object *visible = visible_to (this); + nrof -= nr; if (nrof) { adjust_weight (env, -weight * nr); // carrying == 0 - if (visible) - esrv_send_item (visible, this); + if (object *pl = visible_to ()) + esrv_update_item (UPD_NROF, pl, this); - return 1; + return true; } else { - if (visible) - esrv_del_item (visible->contr, count); - - this->destroy (1); - return 0; + destroy (1); + return false; } } -//TODO: remove +/* + * split(ob,nr) splits up ob into two parts. The part which + * is returned contains nr objects, and the remaining parts contains + * the rest (or is removed and returned if that number is 0). + * On failure, NULL is returned. + */ object * -decrease_ob_nr (object *op, uint32 i) +object::split (sint32 nr) { - return op->decrease_nr (i) ? op : 0; + int have = number_of (); + + if (have < nr) + return 0; + else if (have == nr) + { + remove (); + return this; + } + else + { + decrease (nr); + + object *op = object_create_clone (this); + op->nrof = nr; + return op; + } } object * @@ -1646,6 +1640,8 @@ /* return the original object and remove inserted object (client needs the original object) */ tmp->nrof += op->nrof; + adjust_weight (this, op->total_weight ()); + op->destroy (1); op = tmp; goto inserted;