You may run up against crashes with object programs. I recently added a 'put'
trigger type that will segmentation fault unless the code takes into
consideration that the object may be in a container. In many of the do_opXXX
commands you'll see:
if ( ( victim = get_char_room( NULL,
obj->in_room?obj->in_room:obj->carried_by->in_room, arg ) ) == NULL )
If you have delayed prog parsing and a character shoves the triggering object
into his pack, or have implemented a 'put' trigger of your own, the MUD will
crash. A recommendation is to allow the container that the object is in to act
as a "host" for the object:
void do_opechoat( OBJ_DATA *obj, char *argument )
...
OBJ_DATA *host;
host = find_container_or_obj(obj);
...
if ( ( victim = get_char_room( NULL,
host->in_room?host->in_room:host->carried_by->in_room, arg ) ) == NULL )
return;
act( argument, host->carried_by?host->carried_by:host->in_room->people, obj,
victim, TO_VICT );
---------
You'll have to go through all the do_opXXX functions and change certain calls to
"host" instead of "obj", but it is a trivial modification which takes
approximately 20 minutes.
Three new functions to find an object's container: (not entirely necessary):
//JH: Only find an object's container. If it's not in anything, return NULL.
OBJ_DATA *find_container(OBJ_DATA *obj)
{
OBJ_DATA *in_obj;
for (in_obj = obj; in_obj->in_obj != NULL; in_obj = in_obj->in_obj);
if (in_obj == obj)
return NULL;
else
return in_obj;
}
//JH: Find what container obj is ultimately in. If it's not in anything, it'll
just return itself.
OBJ_DATA *find_container_or_obj(OBJ_DATA *obj)
{
OBJ_DATA *in_obj;
for (in_obj = obj; in_obj->in_obj != NULL; in_obj = in_obj->in_obj);
return in_obj;
}
//JH: Find the owner of the container which obj is ultimately in. Returns NULL
if not on anyone.
CHAR_DATA *find_container_owner(OBJ_DATA *obj)
{
OBJ_DATA *in_obj;
for (in_obj = obj; in_obj->in_obj != NULL; in_obj = in_obj->in_obj);
return in_obj->carried_by;
}