private object environment; /* environment of this object */
private object *inventory; /* inventory of this object */
private object next_inv; /* next object in inventory */
/*
* NAME: _Q_env()
* DESCRIPTION: return the environment of this object
*/
nomask object _Q_env()
{
return environment;
}
/*
* NAME: _Q_inv()
* DESCRIPTION: return the inventory of this object
*/
nomask object *_Q_inv()
{
if (PRIVILEGED()) {
return inventory;
}
}
/*
* NAME: _F_next_inv()
* DESCRIPTION: set the next object in the inventory
*/
nomask void _F_next_inv(object next)
{
if (PRIVILEGED()) {
next_inv = next;
}
}
/*
* NAME: _Q_next_inv()
* DESCRIPTION: return the next object in the inventory
*/
nomask object _Q_next_inv()
{
return next_inv;
}
/*
* NAME: _F_rm_inv()
* DESCRIPTION: remove an object from the inventory of this object
*/
nomask void _F_rm_inv(object obj, int light)
{
if (PRIVILEGED()) {
int alive, i, sz;
object invobj;
alive = living(obj);
if (alive) {
remove_actions(obj, this_object());
}
if (living(this_object())) {
remove_actions(this_object(), obj);
}
i = member_array(obj, inventory);
if (i != 0) {
inventory[i - 1]->_F_next_inv((i == sizeof(inventory) - 1) ?
0 : inventory[i + 1]);
}
inventory -= ({ obj });
add_light(-light);
for (i = 0, sz = sizeof(inventory); i < sz; i++) {
invobj = inventory[i];
if (alive) {
remove_actions(obj, invobj);
}
if (living(invobj)) {
remove_actions(invobj, obj);
}
}
}
}
/*
* NAME: _F_add_inv()
* DESCRIPTION: add an object to the inventory of this object
*/
nomask void _F_add_inv(object obj, int light)
{
if (PRIVILEGED()) {
obj->_F_next_inv((sizeof(inventory) == 0) ? 0 : inventory[0]);
inventory = ({ obj }) + inventory;
add_light(light);
}
}
/*
* NAME: _F_move()
* DESCRIPTION: move this object somewhere
*/
nomask void _F_move(object env)
{
if (PRIVILEGED()) {
environment = env;
}
}
/*
* NAME: query_inventory()
* DESCRIPTION: return the inventory of an object
*/
private object *query_inventory(object obj)
{
object *inv;
inv = obj->_Q_inv();
return inv;
}
/*
* NAME: remove_inv()
* DESCRIPTION: remove object from inventory
*/
private void remove_inv(object obj, object from)
{
from->_F_rm_inv(obj, query_light(obj));
}
/*
* NAME: move()
* DESCRIPTION: do the move thing
*/
private void move(object obj, object from, object dest)
{
int light;
light = query_light(obj);
if (from != 0) {
from->_F_rm_inv(obj, light);
}
obj->_F_move(dest);
dest->_F_add_inv(obj, light);
}
/*
* NAME: environment()
* DESCRIPTION: return the environment of an object
*/
static varargs object environment(object obj)
{
return (obj == 0) ? environment : obj->_Q_env();
}
/*
* NAME: move_object()
* DESCRIPTION: move an object
*/
static void move_object(mixed obj, mixed dest)
{
object save_player, env, *inv, invobj;
int i, sz;
if (stringp(obj)) {
call_other(obj = ::find_object(DRIVER)->path_object(obj), "???");
obj = find_object(obj);
}
ARGCHECK(objectp(obj), move_object, 1);
if (stringp(dest)) {
call_other(dest = ::find_object(DRIVER)->path_object(dest), "???");
dest = find_object(dest);
}
ARGCHECK(objectp(dest), move_object, 2);
env = dest;
do {
if (obj == env) {
error("Can't move object inside itself.");
}
} while ((env=env->_Q_env()) != 0);
save_player = this_player();
env = obj->_Q_env();
if (env != 0 && living(obj)) {
set_this_player(obj);
env->exit(obj);
if (obj == 0) {
return;
}
}
obj->_F_reset();
dest->_F_reset();
if (obj == 0) {
error("move_object() of destructed object.");
}
if (dest == 0) {
error("move_object() to destructed object.");
}
rlimits (-1; -1) {
move(obj, env, dest);
}
if (living(obj)) {
set_this_player(obj);
dest->init();
if (obj == 0 || obj->_Q_env() != dest) {
set_this_player(save_player);
return;
}
}
inv = query_inventory(dest) - ({ obj });
for (i = 0, sz = sizeof(inv); i < sz; i++) {
invobj = inv[i];
if (invobj != 0 && living(invobj)) {
set_this_player(invobj);
obj->init();
if (obj == 0 || obj->_Q_env() != dest) {
set_this_player(save_player);
return;
}
}
if (living(obj) && invobj != 0) {
set_this_player(obj);
invobj->_F_reset();
invobj->init();
if (obj == 0 || obj->_Q_env() != dest) {
set_this_player(save_player);
return;
}
}
}
if (living(dest)) {
set_this_player(dest);
obj->init();
}
set_this_player(save_player);
}
/*
* NAME: all_inventory()
* DESCRIPTION: return an array with the inventory of an object
*/
static varargs object *all_inventory(object obj)
{
if (obj == 0) {
obj = this_object();
}
ARGCHECK(obj, all_inventory, 1);
return query_inventory(obj)[..];
}
/*
* NAME: deep_inventory()
* DESCRIPTION: return the deep inventory of an object
*/
static object *deep_inventory(object obj)
{
object *inv, *sub;
int i, sz;
ARGCHECK(obj, deep_inventory, 1);
inv = query_inventory(obj)[..];
for (i = 0, sz = sizeof(inv); i < sz; i++) {
sub = query_inventory(inv[i]);
if (sizeof(sub) != 0) {
inv += sub;
sz += sizeof(sub);
}
}
return inv;
}
/*
* NAME: first_inventory()
* DESCRIPTION: return the first item in the inventory of obj
*/
static varargs object first_inventory(mixed obj)
{
object *inv;
if (obj == 0) {
obj == this_object();
} else if (stringp(obj)) {
call_other(obj = ::find_object(DRIVER)->path_object(obj), "???");
obj = find_object(obj);
}
ARGCHECK(objectp(obj), first_inventory, 1);
inv = query_inventory(obj);
obj = (sizeof(inv) != 0) ? inv[0] : 0;
return obj;
}
/*
* NAME: next_inventory()
* DESCRIPTION: return the next object in the environment's inventory
*/
static varargs object next_inventory(object obj)
{
if (obj == 0) {
obj = this_object();
}
ARGCHECK(obj, next_inventory, 1);
return obj->_Q_next_inv();
}