--- deliantra/server/common/object.C 2007/01/18 16:19:34 1.117 +++ deliantra/server/common/object.C 2007/02/10 01:52:25 1.130 @@ -491,7 +491,7 @@ SET_FLAG (dst, FLAG_REMOVED); if (speed < 0) - dst->speed_left = speed_left - RANDOM () % 200 / 100.0; + dst->speed_left = speed_left - rndm (); /* Copy over key_values, if any. */ if (key_values) @@ -672,6 +672,8 @@ object::~object () { + unlink (); + free_key_values (this); } @@ -689,7 +691,9 @@ void object::unlink () { - assert (index);//D + if (!index) + return; + objects.erase (this); refcnt_dec (); } @@ -773,6 +777,7 @@ if (!drop_to_ground || !map || map->in_memory != MAP_IN_MEMORY + || map->nodrop || ms ().move_block == MOVE_ALL) { while (inv) @@ -816,7 +821,15 @@ remove_button_link (this); if (flag [FLAG_FRIENDLY]) - remove_friendly_object (this); + { + remove_friendly_object (this); + + if (type == GOLEM + && owner + && owner->type == PLAYER + && owner->contr->ranges[range_golem] == this) + owner->contr->ranges[range_golem] = 0; + } if (!flag [FLAG_REMOVED]) remove (); @@ -898,10 +911,9 @@ * object will have no environment. If the object previously had an * environment, the x and y coordinates will be updated to * the previous environment. - * Beware: This function is called from the editor as well! */ void -object::remove_slow () +object::do_remove () { object *tmp, *last = 0; object *otmp; @@ -954,6 +966,12 @@ { if (type == PLAYER) { + // leaving a spot always closes any open container on the ground + if (container && !container->env) + // this causes spurious floorbox updates, but it ensures + // that the CLOSE event is being sent. + close_container (); + --map->players; map->touch (); } @@ -1748,7 +1766,7 @@ { float - diff = tmp->move_slow_penalty * FABS (op->speed); + diff = tmp->move_slow_penalty * fabs (op->speed); if (op->type == PLAYER) if ((QUERY_FLAG (tmp, FLAG_IS_HILLY) && find_skill_by_number (op, SK_CLIMBING)) || @@ -1965,7 +1983,7 @@ if (!index) return -1; - return altern[RANDOM () % index]; + return altern [rndm (index)]; } /* @@ -1996,7 +2014,7 @@ end -= begin; while (--end) - swap (arr [end], arr [RANDOM () % (end + 1)]); + swap (arr [end], arr [rndm (end + 1)]); } /* new function to make monster searching more efficient, and effective! @@ -2568,7 +2586,7 @@ char info2[256 * 4]; char *p = info; - p += snprintf (p, 512, "{cnt:%d,uuid:<1,%" PRIx64 ">,name:\"%s\"%s%s,flags:[%s],type:%d}", + p += snprintf (p, 512, "{cnt:%d,uuid:<1.%" PRIx64 ">,name:\"%s\"%s%s,flags:[%s],type:%d}", count, uuid.seq, &name, title ? "\",title:\"" : "", @@ -2598,3 +2616,75 @@ return debug_desc (info); } +struct region * +object::region () const +{ + return map ? map->region (x, y) + : region::default_region (); +} + +const materialtype_t * +object::dominant_material () const +{ + if (materialtype_t *mat = name_to_material (materialname)) + return mat; + + // omfg this is slow, this has to be temporary :) + shstr unknown ("unknown"); + + return name_to_material (unknown); +} + +void +object::open_container (object *new_container) +{ + if (container == new_container) + return; + + if (object *old_container = container) + { + if (INVOKE_OBJECT (CLOSE, old_container, ARG_OBJECT (this))) + return; + +#if 0 + // remove the "Close old_container" object. + if (object *closer = old_container->inv) + if (closer->type == CLOSE_CON) + closer->destroy (); +#endif + + old_container->flag [FLAG_APPLIED] = 0; + container = 0; + + esrv_update_item (UPD_FLAGS, this, old_container); + new_draw_info_format (NDI_UNIQUE, 0, this, "You close %s.", query_name (old_container)); + } + + if (new_container) + { + if (INVOKE_OBJECT (OPEN, new_container, ARG_OBJECT (this))) + return; + + // TODO: this does not seem to serve any purpose anymore? +#if 0 + // insert the "Close Container" object. + if (archetype *closer = new_container->other_arch) + { + object *closer = arch_to_object (new_container->other_arch); + closer->flag [FLAG_NO_MAP_SAVE] = 1; + new_container->insert (closer); + } +#endif + + new_container->flag [FLAG_APPLIED] = 1; + container = new_container; + + esrv_update_item (UPD_FLAGS, this, new_container); + new_draw_info_format (NDI_UNIQUE, 0, this, "You open %s.", query_name (new_container)); + } + + if (contr && contr->ns) + contr->ns->floorbox_update (); +} + +