--- deliantra/server/common/object.C 2008/04/21 07:01:40 1.210 +++ deliantra/server/common/object.C 2008/04/22 23:50:23 1.216 @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -333,6 +332,41 @@ return 1; } +// find player who can see this object +object * +object::visible_to () const +{ + if (!flag [FLAG_REMOVED]) + { + // see if we are in a container of sorts + if (env) + { + // the player inventory itself is always visible + if (env->type == PLAYER) + return env; + + // else a player could have our env open + 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 (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 + // this will catch the case where "this" is a player + if (object *pl = ms ().player ()) + return pl; + } + } + + return 0; +} + // adjust weight per container type ("of holding") static sint32 weight_adjust (object *op, sint32 weight) @@ -353,7 +387,15 @@ { weight = weight_adjust (op, weight); + if (!weight) + return; + op->carrying += weight; + + if (object *pl = op->visible_to ()) + if (pl != op) // player is handled lazily + esrv_update_item (UPD_WEIGHT, pl, op); + op = op->env; } } @@ -376,7 +418,16 @@ sum += op->total_weight (); } - carrying = weight_adjust (this, sum); + sum = weight_adjust (this, sum); + + if (sum != carrying) + { + carrying = sum; + + if (object *pl = visible_to ()) + if (pl != this) // player is handled lazily + esrv_update_item (UPD_WEIGHT, pl, this); + } } /* @@ -918,16 +969,15 @@ void object::do_destroy () { - attachable::do_destroy (); - if (flag [FLAG_IS_LINKED]) remove_button_link (this); if (flag [FLAG_FRIENDLY]) remove_friendly_object (this); - if (!flag [FLAG_REMOVED]) - remove (); + remove (); + + attachable::do_destroy (); destroy_inv (true); @@ -1005,12 +1055,16 @@ object *tmp, *last = 0; object *otmp; - if (QUERY_FLAG (this, FLAG_REMOVED)) + if (flag [FLAG_REMOVED]) return; - SET_FLAG (this, FLAG_REMOVED); INVOKE_OBJECT (REMOVE, this); + if (object *pl = visible_to ()) + esrv_del_item (pl->contr, count); + + flag [FLAG_REMOVED] = true; + if (more) more->remove (); @@ -1154,20 +1208,20 @@ ; for (; top; top = top->below) - { - if (top == op) - continue; + if (object::can_merge (op, top)) + { + top->nrof += op->nrof; - if (object::can_merge (op, top)) - { - top->nrof += op->nrof; + if (object *pl = top->visible_to ()) + esrv_update_item (UPD_NROF, pl, top); -/* CLEAR_FLAG(top,FLAG_STARTEQUIP);*/ - op->weight = 0; /* Don't want any adjustements now */ - op->destroy (); - return top; - } - } + op->weight = 0; // cancel the addition above + op->carrying = 0; // must be 0 already + + op->destroy (1); + + return top; + } return 0; } @@ -1479,40 +1533,6 @@ return where->map->insert (this, where->x, where->y, originator, flags); } -// find player who can see this object -static object * -visible_to (object *op) -{ - if (!op->flag [FLAG_REMOVED]) - { - // see if we are in a container of sorts - if (object *env = op->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 (); - - // 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) - return pl; - } - else - { - // maybe there is a player standing on the same mapspace - if (object *pl = env->ms ().player ()) - return pl; - } - } - - return 0; -} - /* * decrease(object, number) decreases a specified number from * the amount of an object. If the amount reaches 0, the object @@ -1523,31 +1543,26 @@ bool 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; } } @@ -1560,9 +1575,11 @@ object * object::split (sint32 nr) { - if (nrof < nr) + int have = number_of (); + + if (have < nr) return 0; - else if (nrof == nr) + else if (have == nr) { remove (); return this; @@ -1625,6 +1642,10 @@ /* return the original object and remove inserted object (client needs the original object) */ tmp->nrof += op->nrof; + + if (object *pl = tmp->visible_to ()) + esrv_update_item (UPD_NROF, pl, tmp); + adjust_weight (this, op->total_weight ()); op->destroy (1); @@ -1648,6 +1669,9 @@ op->flag [FLAG_REMOVED] = 0; + if (object *pl = op->visible_to ()) + esrv_send_item (pl, op); + adjust_weight (this, op->total_weight ()); inserted: @@ -1655,9 +1679,9 @@ if (op->glow_radius && map && map->darkness) update_all_los (map, x, y); - if (object *otmp = in_player ()) - if (otmp->contr && !QUERY_FLAG (otmp, FLAG_NO_FIX_PLAYER)) - otmp->update_stats (); + // if this is a player's inventory, update stats + if (type == PLAYER && !flag [FLAG_NO_FIX_PLAYER]) + update_stats (); INVOKE_OBJECT (INSERT, this); @@ -2597,7 +2621,7 @@ closer->destroy (); #endif - old_container->flag [FLAG_APPLIED] = 0; + old_container->flag [FLAG_APPLIED] = false; container = 0; esrv_update_item (UPD_FLAGS, this, old_container); @@ -2623,7 +2647,7 @@ new_draw_info_format (NDI_UNIQUE, 0, this, "You open %s.", query_name (new_container)); - new_container->flag [FLAG_APPLIED] = 1; + new_container->flag [FLAG_APPLIED] = true; container = new_container; esrv_update_item (UPD_FLAGS, this, new_container);