/**
* The basic object. This pulls together all the bits needed to create
* a basic object.
*
* @author Pinkfish
* @change many any many times
* @see /std/room.c
*/
#include <cmr.h>
inherit "/std/basic/extra_look";
inherit "/std/basic/enchant";
inherit "/std/basic/id";
inherit "/std/basic/misc";
inherit "/std/basic/property";
inherit "/std/basic/read_desc";
inherit "/std/basic/auto_load";
inherit "/std/basic/help_files";
inherit "/std/basic/theft_callback";
inherit "/std/basic/effects";
#define AUTO_LOAD_TAG "basic.object";
nosave int do_setup;
nosave string create_me;
nosave string colour;
private string* _materials;
nosave object player;
void create() {
_materials = ({ });
extra_look::create();
id::create();
misc::create();
property::create();
read_desc::create();
effects::create();
seteuid( (string)"/secure/master"->
creator_file( file_name( this_object() ) ) );
if ( this_player() ) {
create_me = (string)this_player()->query_name();
} else {
create_me = "who knows";
}
if ( !do_setup ) {
this_object()->setup();
}
} /* create() */
/**
* Gives the object a name. Sets the name to the word and makes it the
* short description and attempts to create the pural short description
* from it.
* @param name the name to use
*/
void set_name( string word ) {
if ( query_name() && ( query_name() != "object" ) ) {
::set_name(word);
return;
}
::set_name(word);
if ( !short_d ) {
short_d = word;
}
add_plural( pluralize( word ) );
} /* set_name() */
/** @ignore yes */
string query_long_details(string arg, int dark, object looker) {
string stuff;
stuff = "";
if ( this_player()->query_see_octarine() ) {
stuff += enchant_string();
}
if ( sizeof( query_read_mess() ) ) {
stuff += "It appears to have something written on it.\n";
}
return stuff;
} /* query_long_details() */
/**
* This method replaces any colours of materials in the given string
* with the appropriate ccolours or materials for this object.
* @param player the player attempting to check the colour/material.
* @param text the text to replace
* @return a new string with the dollar identities expanded.
*/
string replace_long_dollars(object player, string text) {
if ( colour ) {
text = replace( text, "$colour$",
(string)CMR_HANDLER->identify_colour( colour, player ) );
}
if ( sizeof(_materials) ) {
text = replace( text, "$material$",
(string)CMR_HANDLER->identify_material( _materials[0], player, 1 ) );
}
return text;
} /* replace_long_dollars() */
/**
* The description of an object when someone looks at it. This handles
* the extra code for messages, colour and material.
* @param word the word it was matched on
* @param dark is it dark from the player's perspecitive
* @return the long description
*/
string long( string word, int dark ) {
string stuff;
stuff = ::long( word, dark );
stuff += calc_extra_look();
stuff += query_long_details(word, dark, this_player());
stuff = replace_long_dollars( this_player(), stuff );
return stuff;
} /* long() */
/**
* The colour of the object.
* @return the colour of the objecy
*/
string query_colour() { return colour; }
/**
* Sets the colour of the object.
* @param word the colour to make the object
*/
void set_colour( string word ) { colour = word; }
/**
* The material of the object.
* @return the name of the material
*/
string query_material() {
if (sizeof(_materials)) {
return _materials[0];
}
return 0;
}
/**
* This returns all of the materials of the object.
* @return all the materials
*/
string* query_materials() {
string *new_materials;
// We need this for the moment, because a silly mistake was made
// which was storing lots of arrays in arrays instead of just
// an array of strings.
new_materials = ({ });
if(!_materials) _materials=({ });
foreach( mixed bit in _materials ) {
if ( stringp( bit ) ) {
new_materials += ({ bit });
}
else {
if ( arrayp( bit ) ) {
foreach( mixed inner_bit in bit ) {
if( stringp( inner_bit ) ) {
new_materials += ({ inner_bit });
}
}
}
}
}
return new_materials;
} /* query_materials() */
/**
* Sets the material of the object, this adds this material to the
* front of the material list.
* @param word the material to set it to
*/
void set_material( mixed word ) {
if (!arrayp(word)) {
word = ({ word });
}
// NB: It is _already_ an array so we don't need to put it in
// brackets! This puts an array in an array ...eek.
if (sizeof (word)) {
_materials = word + _materials;
add_adjective(word);
}
}
/**
* This method adds a material to the list of current materials.
* @param material the material to add
*/
void add_material(mixed material) {
if (pointerp(material)) {
_materials |= material;
} else if (stringp(material)) {
_materials += ({ material });
}
add_adjective(material);
} /* add_material() */
/**
* The pronoun of the object.
* @return always returns "it"
*/
string query_pronoun() { return "it"; }
/**
* The possessive of the object.
* @return always returns "its"
*/
string query_possessive() { return "its"; }
/**
* The objective of the object.
* @return always returns "it"
*/
string query_objective() { return "it"; }
/**
* Who cloned the object. Used for security reasoin to trace who have
* been cloning up objects for players.
* @return the person who cloned the object
*/
string query_cloned_by() { return create_me; }
/**
* This method sets the quality of the object. All objects are by
* default 'normal' quality.
* @param quality the quality of the object
*/
void set_quality(int quality) {
add_property("quality", quality);
} /* set_qualist() */
/**
* This method returns the quality of the object. The quality is used
* in the crafts system, amongst other things.
*/
int query_quality() {
return query_property("quality");
} /* query_quality() */
/**
* @ignore yes
*/
mixed *stats() {
if(!_materials) _materials=({ });
return ({
({ "name" , query_name(), }),
({ "short", short( 0 ), }),
({ "plural", query_plural(0), }),
({ "weight", (int)this_object()->query_weight(), }),
({ "enchantment", query_enchant(), }),
({ "colour", colour, }),
({ "material", query_multiple_short(_materials), }),
({ "cloned by", create_me, }),
({ "length", (int)this_object()->query_length(), }),
({ "width", (int)this_object()->query_width(), }),
}) + property::stats() + misc::stats() + effects::stats();
} /* stats() */
/**
* @ignore yes
*/
mapping int_query_static_auto_load() {
return ([
"name" : query_name(),
"short" : short_d,
"main plural" : plural_d,
"long" : long_d,
"alias" : query_alias(1), // not faux ones
"adjective" : query_adjectives(1), // not faux ones
"plural adjective" : query_plural_adjectives(),
"plural" : query_plurals(),
"value" : value,
"value info" : value_info + ([ ]),
"weight" : weight,
"colour" : colour,
"length" : length,
"width" : width,
]);
} /* int_query_static_auto_load() */
/**
* @ignore yes
*/
mapping query_static_auto_load() {
if ( !query_name() || ( query_name() == "object" ) ) {
return 0;
}
if ( explode( file_name( this_object() ), "#" )[ 0 ] != "/std/object" ) {
return ([ ]);
}
return int_query_static_auto_load();
} /* query_static_auto_load() */
/**
* @ignore yes
*/
mapping query_dynamic_auto_load() {
mapping map;
if ( !query_name() || ( query_name() == "object" ) ) {
return 0;
}
if ( query_enchant() > this_object()->query_max_enchant() ) {
set_enchant(this_object()->query_max_enchant());
}
map = ([
"read mess" : ::query_read_mess(),
"degrade enchantment" : query_degrade_enchant(),
"enchantment" : query_real_enchant(),
"enchantment time" : query_enchant_set_time(),
"light" : query_my_light(),
"materials" : query_materials(),
"cloned by" : create_me,
]);
if ( map_prop ) {
map[ "properties" ] = copy( map_prop );
}
if ( timed_properties ) {
save_player_properties();
map[ "timed properties" ] = copy(timed_properties);
}
if ( sizeof(query_effs() ) ) {
effect_freeze();
effects_saving();
map += ([
"effects" : ({
(mixed *)query_effs(),
(int *)query_eeq()
})
]);
effect_unfreeze();
}
if ( this_object()->query_special() ) {
map[ "special" ] = (mapping)this_object()->query_special_info();
}
if ( query_deity() ) {
map[ "consecrated" ] = query_deity();
}
return map;
} /* query_dynamic_auto_load() */
/**
* @ignore yes
*/
void init_static_arg( mapping map ) {
if ( !mapp( map ) ) {
return;
}
if ( !undefinedp( map[ "name" ] ) ) {
set_name(map[ "name" ]);
}
if ( !undefinedp( map[ "short" ] ) ) {
set_short( map[ "short" ] );
}
if ( !undefinedp( map[ "main plural" ] ) ) {
set_main_plural( map[ "main plural" ] );
}
if ( !undefinedp( map[ "long" ] ) ) {
set_long( map[ "long" ] );
}
if ( map[ "alias" ] ) {
set_aliases( map[ "alias" ] );
}
if ( map[ "adjective" ] ) {
set_adjectives( map[ "adjective" ] );
}
if ( map[ "plural adjective" ] ) {
set_plural_adjectives( map[ "plural adjective" ] );
}
if ( map[ "plural" ] ) {
set_plurals( map[ "plural" ] );
}
if ( !undefinedp( map[ "value" ] ) ) {
set_value( map[ "value" ] );
}
if ( !undefinedp( map[ "value info" ] ) ) {
value_info = map[ "value info" ];
}
if ( !undefinedp( map[ "weight" ] ) ) {
set_weight( map[ "weight" ] );
}
if ( !undefinedp( map[ "colour" ] ) ) {
set_colour( map[ "colour" ] );
}
if ( !undefinedp( map[ "material" ] ) ) {
set_material( map[ "material" ] );
}
if ( !undefinedp( map[ "length" ] ) ) {
set_length( map[ "length" ] );
}
if ( !undefinedp( map[ "width" ] ) ) {
set_width( map[ "width" ] );
}
} /* init_static_arg() */
/**
* Sets the player associated with the object. This is used during the
* autoload sequence.
*
* @param thing the player object we belong to
* @see /global/auto_load.c
*/
void set_player( object thing ) { player = thing; }
/**
* @ignore yes
*/
void init_dynamic_arg( mapping map, object ) {
int recycle;
if ( !mapp( map ) )
return;
/*
* Because recycling is needs to be preserved into new objects from
* olds ones (generally speaking).
*/
recycle = query_property("no recycling");
if ( map[ "properties" ] )
map_prop = map[ "properties" ];
if (recycle)
add_property("no recycling", recycle);
if ( map[ "timed properties" ] ) {
timed_properties = map[ "timed properties" ];
reload_player_properties();
}
if ( sizeof( map[ "read mess" ] ) )
set_read_mess( map[ "read mess" ] );
if ( !undefinedp( map[ "materials" ] ) ) {
_materials = map["materials"];
}
set_enchant(map["enchantment"]);
set_degrade_enchant(map["degrade enchantment"]);
if (map["enchantment time"]) {
set_enchant_set_time(map["enchantment time"]);
}
set_light( map[ "light" ] );
create_me = map[ "cloned by" ];
if( map[ "effects" ] ) {
set_effs( map[ "effects" ][ 0 ] );
set_eeq( map[ "effects" ][ 1 ] );
if ( environment() && shadow( this_object(), 0 ) )
move_object( environment() );
}
init_after_save();
if ( map[ "special" ] ) {
clone_object( "/std/shadows/object/special_item" )->
setup_shadow( this_object(), player );
this_object()->set_special_info( map[ "special" ] );
}
if ( map[ "consecrated" ] ) {
set_deity( map[ "consecrated" ] );
}
} /* init_dynamic_arg() */
/** @ignore yes */
string query_readable_message(object player, int ignore_labels) {
string ret;
string bing;
object *labels;
object ob;
int *enums;
object store;
ret = ::query_readable_message(player);
if (!ignore_labels) {
enums = (int *)this_object()->effects_matching( "object.label" );
if ( !sizeof( enums ) ) {
labels = ({ });
} else {
store = (object)this_object()->arg_of( enums[ 0 ] )[ 0 ];
if ( !objectp( store ) ) {
labels = ({ });
} else {
labels = (object *)store->find_inv_match( "" );
}
}
if (sizeof(labels) && !ret) {
ret = "";
}
foreach (ob in labels) {
ret += "On " + ob->the_short() + " is written:\n";
bing = ob->query_readable_message(player, 0);
if (bing) {
ret += bing;
} else {
ret += "Nothing.\n";
}
}
}
return ret;
} /* query_readable_message() */
/** @ignore yes */
string query_read_short(object player, int ignore_labels) {
string ret;
object *labels;
int *enums;
object store;
ret = ::query_read_short(player);
if (!ignore_labels) {
enums = (int *)this_object()->effects_matching( "object.label" );
if ( !sizeof( enums ) ) {
labels = ({ });
} else {
store = (object)this_object()->arg_of( enums[ 0 ] );
if ( !objectp( store ) ) {
labels = ({ });
} else {
labels = (object *)store->find_inv_match( "" );
}
}
if (sizeof(labels)) {
if (ret) {
ret += " and " + query_multiple_short(labels, "the") +
" stuck on $name$";
} else {
ret = query_multiple_short(labels, "the") +
" stuck on $name$";
}
}
}
return ret;
} /* query_read_short() */
/** @ignore yes */
string query_help_file_directory() {
return "/doc/object/";
} /* query_help_file_directory() */
int clean_up(int inherited) {
if(inherited) {
log_file("CLEANUP", "%s %s cleaned up.\n", ctime(time()),
file_name(this_object()));
move("/room/rubbish");
}
return 1;
}
void dest_me() {
effects_desting();
::dest_me();
}