/* -*- LPC -*- */
/*
* $Locker: $
* $Id: surface.c,v 1.17 2002/11/18 01:46:35 ceres Exp $
*
*
*/
/**
* This is a furniture item for making all kinds of furniture.
*/
#include <move_failures.h>
#include <player.h>
inherit "/std/object";
inherit "/std/basic/cute_look";
inherit "/std/basic/item_chat";
inherit "/std/room/furniture/inherit/furniture_base";
private nosave int _loc_weight, _max_weight;
private nosave string *_shadows;
private nosave object _player;
private nosave string *_aliases;
private nosave int _use_internals;
//#define DEBUG
void create() {
do_setup++;
furniture_base::create();
object::create();
add_alias( "furniture" );
add_plural( "furniture" );
set_opaque();
do_setup--;
if ( !do_setup ) {
this_object()->setup();
}
// Don't respond to 'get all'
set_no_all(1);
}
/**
* @ignore yes
*/
void init() {
string alias;
if(_aliases)
foreach(alias in _aliases) {
add_command(alias, "<indirect:object:me> {in|on|into} <indirect:object>",
(: "/cmds/living/put"->cmd($1, $3, $4) :) );
}
::init();
}
/**
* Set aliases for 'put' for this object. This allows you to setup an item
* so that things can be hung from it, or stood on it or somesuch.
*
* @param aliases aliases for the verb 'put'.
*/
void set_put_aliases(string *aliases) {
_aliases = aliases;
}
/**
* This sets the flag to say if the object will allow things on it to be
* used. This is useful for tables and so on.
* @param allow 1 if they are allowed to be used, 0- if not
*/
void set_allow_use_internals(int allow) {
_use_internals = allow;
} /* set_allow_use_internals() */
/**
* This method returns the flag to say if the object will allow things on it
* to be used.
* @return 1 if it is allowed, 0 if not
*/
int query_allow_use_internals() {
return _use_internals;
} /* query_allow_use_internals() */
/** @ignore yes */
/* Furniture is much harder to carry than just its weight, therefore we
* multiply its weight by 5 to determine if someone can carry it.
*/
varargs int move( mixed dest, string messin, string messout ) {
int i, w;
object from;
if (!move_check(dest)) {
write(the_short() + " resists being picked up and shocks you slightly.\n");
return MOVE_INVALID_DEST;
}
w = (int)this_object()->query_complete_weight() * 5;
if ( from = environment() ) {
from->add_weight( -w );
}
if(!dest) {
return MOVE_INVALID_DEST;
}
if (!( dest->add_weight( w ) ) ) {
if ( from ) {
from->add_weight( w );
}
return MOVE_TOO_HEAVY;
}
if ( stringp( dest ) ) {
dest = find_object( dest );
}
i = ::move( dest, messin, messout );
if ( i != MOVE_OK ) {
if ( from ) {
from->add_weight( w );
}
dest->add_weight( -w );
} else {
if (_use_internals) {
if (from) {
from->remove_use_internal_object(this_object());
}
dest->add_use_internal_object(this_object());
}
if (query_light_needs_inform()) {
if ( from ) {
inform_of_light_level_change(from);
}
inform_of_light_level_change(dest);
}
}
return i;
} /* move() */
/** @ignore yes
* This stops people dragging items away if they aren't allowed to.
*/
int get(mixed dest) {
if(!move_check(dest)) {
write("You feel it would be wrong to take " + the_short() + ".\n");
return 2;
}
return ::get(dest);
}
/**
* @ignore yes
* Makes sure furniture is removed from the save file
* when its removed from this room.
*/
int test_remove(object thing, int flag, mixed dest) {
mixed *stuff;
object thief;
if(environment() && this_player()) {
thief = this_player();
if(thief->query_caster())
thief = find_player(thief->query_caster());
else if(thief->query_owner())
thief = thief->query_owner();
stuff = thing->query_property("dropped");
/*
* It's theft if the item is being removed by someone other than the
* occupier and someone other than the person who dropped it.
*/
if(function_exists("test_occupier", environment()) &&
!environment()->test_occupier(thief->query_name()) &&
(!sizeof(stuff) || stuff[0] != thief->query_name()) &&
thief && environment(thief)) {
event(environment(thief), "theft", thief, this_object(), ({ thing }));
}
#ifdef DEBUG
if(base_name(environment()) != "/room/rubbish")
log_file(base_name(environment()) + ".log",
"%s %s moved from %s to %s.\n", ctime(time())[4..18],
thing->query_short(), this_object()->query_short(),
dest->query_short());
#endif
event(environment(), "save");
}
return 1;
}
/** @ignore yes */
int test_add( object thing, int flag ) {
if(environment())
event(environment(), "save");
#ifdef DEBUG
if(environment() && base_name(environment()) != "/room/rubbish")
log_file(base_name(environment()) + ".log",
"%s %s put on %s by %s.\n", ctime(time())[4..18],
thing->query_short(), this_object()->query_short(),
this_player() ? this_player()->query_name() : "Unknown");
#endif
return 1;
} /* test_add() */
void set_max_weight(int arg) { _max_weight = arg; }
int query_max_weight() { return _max_weight; }
int query_loc_weight() { return _loc_weight; }
int query_has_surface() { return 1; }
/** @ignore yes */
void update_loc_weight() {
int i;
object *contents;
_loc_weight = 0;
contents = all_inventory( this_object() );
for ( i = 0; i < sizeof( contents ); i++ )
_loc_weight += (int)contents[ i ]->query_complete_weight();
} /* update_loc_weight() */
int query_complete_weight() {
return ::query_complete_weight() + query_loc_weight();
} /* query_complete_weight() */
int add_weight( int n ) {
if ( !_max_weight ) return 1;
if ( n + _loc_weight > _max_weight ) return 0;
if ( !environment() ) {
_loc_weight += n;
return 1;
}
if ( !( environment()->add_weight( n ) ) ) return 0;
_loc_weight += n;
return 1;
} /* add_weight() */
int transfer_all_to(object dest) {
object *ob;
int i;
ob = all_inventory(this_object());
for (i=0;i<sizeof(ob);i++)
ob[i]->move(dest);
if (first_inventory(this_object())) return 0;
return 1;
} /* transfer_all_to() */
string long( string word, int dark ) {
object *things;
things = (object *)this_object()->find_inv_match( "all", this_player() );
if ( !sizeof( things ) )
return object::long( word, dark ) +"There is nothing on "+
the_short() +".\n";
return object::long( word, dark ) + query_contents( "On " +
the_short() +" "+ ( sizeof( things ) == 1 ? "is " :
"are " ), things );
} /* long() */
object *find_inv_match( string words, object looker ) {
int i;
object *things;
things = all_inventory( this_object() );
for ( i = sizeof( things ) - 1; i > -1; i-- ) {
if ( !things[ i ]->short( 0 ) ) {
things = delete( things, i, 1 );
continue;
}
if ( !looker )
continue;
if ( !things[ i ]->query_visible( looker ) )
things = delete( things, i, 1 );
}
return things;
} /* find_inv_match() */
void set_player( object thing ) { _player = thing; }
object query_player() { return _player; }
mixed stats() {
return ::stats() + ({
({ "loc_weight", query_loc_weight(), }),
({ "max_weight", query_max_weight(), }),
});
} /* stats() */
mapping int_query_static_auto_load() {
return ([
"::" : ::int_query_static_auto_load(),
"max weight" : _max_weight,
"allowed positions" : query_allowed_positions(),
]);
} /* int_query_static_auto_load() */
mapping query_dynamic_auto_load() {
mixed inventory;
// Try the main player object.
if (!inventory) {
catch(inventory = PLAYER_OB->
create_auto_load( all_inventory( this_object() ) ) );
}
return ([ "::" : ::query_dynamic_auto_load(),
"inv" : inventory,
"bonded" : query_bonded()
]);
} /* query_dynamic_auto_load() */
/**
* This method handles moving objects into the inventory from an auto
* load. This should be over ridden by things inheriting us to
* make sure that the objects can be moved into the inventory. It
* should handle the bypassing of open/close/locked etc flags.
* @param ob the object to move into ourselves
*/
int handle_restore_inventory(object ob) {
return (int)ob->move(this_object());
} /* handle_restore_inventory() */
void init_dynamic_arg( mapping bing ) {
function f;
if ( bing[ "::" ] ) {
::init_dynamic_arg( bing[ "::" ] );
}
if ( bing[ "inv" ] ) {
f = (: handle_restore_inventory($1) :);
if (_player) {
_player->load_auto_load_to_inventory( bing["inv"], this_object(),
_player, f);
} else {
PLAYER_OB->load_auto_load_to_inventory( bing["inv"], this_object(),
this_player(), f);
}
}
set_bonded(bing["bonded"]);
} /* init_dynamic_arg() */
void init_static_arg(mapping bing) {
if (bing["::"]) {
::init_static_arg(bing["::"]);
}
if (!undefinedp(bing["max weight"])) {
_max_weight = bing["max weight"];
if(!undefinedp(bing["allowed_positions"]))
set_allowed_positions(bing["allowed_positions"]);
}
} /* init_static_arg() */
/** @ignore yes */
mixed query_static_auto_load() {
if ( base_name(this_object()) + ".c" == __FILE__ )
return int_query_static_auto_load();
return ([ ]);
} /* query_static_auto_load() */
void dest_me() {
int i;
object shadow;
for ( i = 0; i < sizeof( _shadows ); i++ ) {
if ( shadow = find_object( _shadows[ i ] ) ) {
shadow->destruct_shadow( shadow );
}
}
all_inventory()->dest_me();
object::dest_me();
} /* dest_me() */
/** @ingore yes */
string query_help_file_directory() {
return "/doc/furniture/";
} /* query_help_file_directory() */