/* -*- LPC -*- */ /* * $Locker: $ * $Id: furniture.c,v 1.1 2001/05/15 20:06:00 pinkfish Exp $ */ /** * This is a furniture item for making all kinds of furniture that store * things. * * If you want to make a chest just use set_max_weight() to set how much * weight it can store. * * If you want it to have drawers or shelves use the add_drawer() and * set_drawer_mess() functions to set them up. * */ #include <move_failures.h> #include <position.h> #include <tasks.h> inherit "/obj/cont_save"; inherit "/std/basic/trap"; inherit "/std/room/furniture/inherit/furniture_base"; private nosave string _drawer_mess; private nosave mixed *_drawers; private nosave int _biggest; private nosave int _drawers_inside; private nosave object *_on_top; private nosave int _has_surface; #define DEBUG void create() { do_setup++; ::create(); _drawer_mess = "a drawer in $ob_short$"; _drawers = ({ }); _on_top = ({ }); add_alias( "furniture" ); add_plural( "furniture" ); set_opaque(); if (!query_property("shop type")) add_property( "shop type", "furniture" ); do_setup--; if(!do_setup) this_object()->setup(); } /** * This method returns the message associated with the drawer. * @return the message associated with the drawer * @see set_drawer_mess() * @see query_drawers() * @see add_drawer() */ string query_drawer_mess() { return _drawer_mess; } /** * This method sets the message associated with the drawer. * @param words the message associated with the drawer * @see query_drawer_mess() * @see add_drawer() */ void set_drawer_mess( string words ) { _drawer_mess = words; } /** * This method returns all the drawers on the object. * @return all the drawers on the object * @see add_drawer() */ mixed *query_drawers() { return _drawers; } /** * This method adds a drawer onto the furniture. * * @param type the type of drawer * @param amount the amount the drawer can hold * @see query_drawers() * @see set_drawer_mess() * @see query_drawer_mess() */ void add_drawer( string type, int amount ) { if ( !type || ( type == "" ) || ( amount < 1 ) ) { return; } _drawers += ({ type, amount }); set_max_weight(query_max_weight() + amount); if ( amount > _biggest ) { _biggest = amount; } } /* add_drawer() */ int query_has_surface() { return _has_surface; } void set_has_surface(int i) { _has_surface = i; } /** * Set the drawers to be on the inside, and hence not visible when the * door is closed. */ void set_drawers_inside(int i) { _drawers_inside = i; } /** * Set the drawers to be on the inside, and hence not visible when the * door is closed. */ int query_drawers_inside() { return _drawers_inside; } /** @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; 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 (query_light_needs_inform()) { if ( from ) { inform_of_light_level_change(from); } inform_of_light_level_change(dest); } return i; } /** @ignore yes */ string long( string word, int dark ) { int i; string ret, *sizes; mapping types; ret = ::long( word, dark ); if ( sizeof( _drawers ) && !dark && (!query_closed() || !_drawers_inside)) { types = ([ ]); for ( i = 0; i < sizeof( _drawers ); i += 2 ) { types[ _drawers[ i ] ]++; } sizes = m_indices( types ); for ( i = 0; i < sizeof( sizes ); i++ ) { sizes[ i ] = query_num( types[ sizes[ i ] ] ) +" "+ sizes[ i ] + " drawer"+ ( types[ sizes[ i ] ] > 1 ? "s" : "" ); } ret += "It has "+ query_multiple_short( sizes ) +".\n"; } if(sizeof(_on_top)) ret += query_contents( "On " + the_short() + " " + (sizeof(_on_top) == 1 ? "is " : "are " ), _on_top); return ret; } varargs string query_contents( string start, object *things, int ignore_living) { if(!arrayp(things)) { things = this_object()->find_inv_match( "", this_player() ); things -= ({ this_player() }); things = filter_array( things, (: environment( $1 ) == this_object() :) ); things -= _on_top; } return ::query_contents(start, things, ignore_living); } /** * @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) { int result; mixed *stuff; result = ::test_remove(thing, flag, dest); if(result) { stuff = thing->query_property("dropped"); if(environment() && dest == this_player() && function_exists("test_occupier", environment()) && !environment()->test_occupier(this_player()->query_name()) && (!sizeof(stuff) || stuff[0] != this_player()->query_name())) { event(environment(this_player()), "theft", this_player(), this_object(), ({ thing })); } if(dest) { _on_top -= ({ thing }); thing->remove_property("_on_top"); } event(environment(), "save"); } return result; } /** @ignore yes */ int test_add( object thing, int flag ) { int i; int result; if ( flag ) return 0; if(!environment(thing)) return 1; result = ::test_add(thing, flag); if(!result) return 0; if("/cmds/living/put"->query_con() == "on" && _has_surface) { _on_top += ({ thing }); thing->add_property("_on_top", 1); } else if(sizeof(_drawers)) { if ( !_biggest ) for ( i = 0; i < sizeof( _drawers ); i+= 2 ) if ( _drawers[ i + 1 ] > _biggest ) _biggest = _drawers[ i + 1 ]; if ( (int)thing->query_complete_weight() > _biggest ) return write( (string)thing->the_short() +" is too big "+ "to fit in any of "+ the_short() +"'s drawers.\n" ); } event(environment(), "save", this_object()); return result; } /** @ignore yes */ int pick_unlock(object player) { mixed owner; if(!environment()) return ::pick_unlock(player); if(!environment() || !function_exists("query_owner", environment())) return ::pick_unlock(player); // Ok, we have two situations. Single owner (then do PK check) or // multiple owner, in which case we just check the player is a pk. owner = environment()->query_owner(); if(stringp(owner) && pk_check(player, owner, 1)) { // do the PK check write("You feel it would be wrong to try to break into "+ this_object()->query_short() + ".\n"); return 0; } return ::pick_unlock(player); } /** @ignore yes */ mapping int_query_static_auto_load() { return ([ "::" : ::int_query_static_auto_load(), "drawer mess" : _drawer_mess, "drawers" : _drawers, "allowed_positions" : query_allowed_positions(), "trap" : query_trap_data(), "trap armed": query_trap_armed(), ]); } /* query_static_auto_load() */ /** @ignore yes */ mapping query_static_auto_load() { return int_query_static_auto_load(); } /* query_static_auto_load() */ /** @ignore yes */ void init_static_arg( mapping map ) { if ( !mapp( map ) ) return; if ( map[ "::" ] ) ::init_static_arg( map[ "::" ] ); if ( !undefinedp( map[ "drawer mess" ] ) ) _drawer_mess = map[ "drawer mess" ]; if ( !undefinedp( map[ "drawers" ] ) ) _drawers = map[ "drawers" ]; if(!undefinedp(map["allowed_positions"])) set_allowed_positions( map["allowed_positions"]); if(!undefinedp(map["trap"])) setup_trap(map["trap"][0], map["trap"][1], map["trap"][2], map["trap"][3], map["trap"][4]); if(!undefinedp(map["trap armed"])) set_trap_armed(map["trap armed"]); } /* init_static_arg() */ /** @ignore yes */ void init_dynamic_arg(mapping bing) { object item; ::init_dynamic_arg(bing); foreach(item in all_inventory(this_object())) { if(item->query_property("_on_top")) _on_top += ({ item }); } } /** @ingore yes */ string query_help_file_directory() { return "/doc/furniture/"; } /* query_help_file_directory() */ /** @ignore yes */ mixed *stats() { int i; mixed *ret; ret = ::stats(); ret += ({ ({ "surface", _has_surface }) }); for ( i = 0; i < sizeof( _drawers ); i += 2 ) ret += ({ ({ _drawers[ i ] +" drawer", _drawers[ i + 1 ] }) }); return ret; } /* stats() */