/* Do not remove the headers from this file! see /USAGE for more info. */
//Fluid objects act differently from the typical
//mud object. Properly, fluid should not be able to
//be handled at all except using a container.
//Coded by Uae of Zork. 9/20/97
inherit OBJ;
inherit M_GETTABLE;
inherit M_MESSAGES;
int evap_amount = 6 ;
int evap_time = 20;
void remove_puddle_func();
void evaporate_puddle_func();
string puddle_id = "puddle"; // This could be changed, for some things, to pile...
string puddle_name;
mixed pour_action = "$N $vpour $o $o1 $o2.";
mixed taste_action = "It tastes rather bland.";
mixed evaporate_action = 0;
function evaporate_puddle = (: evaporate_puddle_func :);
private string default_container;
string short();
int ob_state();
//:FUNCTION set_default_container
// Defines container into which fluid will be put by a vendor selling it
void set_default_container(string def){ default_container = def; }
//:FUNCTION query_default_container
// Returns container into which fluid will be put by a vendor selling it
string query_default_container(){ return default_container; }
//:FUNCTION set_puddle_name
//void set_puddle_name( string x )
//'x' is set as the proper name
//of this object when it is outside
//of a container. Defaults to
//'the <puddle_id> of <primary_name>'
void set_puddle_name( string x ){
puddle_name = x;
}
//:FUNCTION set_puddle_id
//void set_puddle_id( x )
//adds id 'x' when the fluid is
//outside of a container.
void set_puddle_id( string x ){
puddle_id = x;
}
string query_puddle_name(){
if (!puddle_name) return "the " + puddle_id + " of " + query_primary_name();
return puddle_name;
}
//:FUNCTION set_evaporate_action
//set_evaporate_action( mixed x )
//'x' is optional.
//Calling this function with no arguments
//will cause the fluid to evaporate when
//outside of a container.
//x can be a string that is output to the
//environment as the fluid evaporate_puddle
//function is called.
//x as a function will be evaluated when
//the fluid is moved outside of a container.
//Do not call this function if the fluid
//is not to evaporate.
varargs void set_evaporate_action( mixed x ){
if (!x) evaporate_action = "The $o dwindles in size.";
else evaporate_action = x;
}
//:FUNCTION set_pour_action
//void set_pour_action( mixed x )
//'x' is a simple action string or
//a function that is evaluated whenever
//this fluid is poured. x may contain
//$o to represent the fluid itself.
void set_pour_action( mixed x ){
pour_action = x;
}
void create(){
::create();
add_id( "fluid", "liquid", "watery" );// watery can be used to exclude fluids that are not viscous.
set_quantity( 1 );
}
varargs void set_fluid_level( int x, string y ){
#ifdef USE_SIZE
set_size( x );
#endif
#ifdef USE_MASS
set_mass( x );
#endif
if ( y ) set_quantity( y );
else set_quantity( x );
}
varargs int add_fluid( object fluid){
if (!fluid) return 0;
#ifdef USE_SIZE
set_fluid_level( query_size() + (fluid -> query_size()) );
#endif
#ifdef USE_MASS
set_fluid_level( query_mass() + (fluid -> query_mass()) );
#endif
fluid -> remove();
return 1;
}
int do_mix( object fluid ){ //This is meant to be overridden.
add_fluid( fluid );
return 1;
}
varargs object fluid_already( string x, object env ){
object ob;
if (!env) env = environment( this_body() );
if (!x) x = query_primary_id();
ob = present( x, env );
if (!ob) return 0;
if ( !ob -> id("fluid") ) return 0;
return ob;
}
varargs void pour( string how, mixed ob2, mixed from ){
string where;
if ( how == "from" || how == "out" ) ob2 = environment( this_body() );
if ( ob2 == environment( this_body() ) )
{
how = "onto";
where = "the ground";
}
else where = ob2 -> the_short();
if ( ob2 == environment( this_body() ) )
{
if (functionp( pour_action ) ) evaluate( pour_action, how, ob2 ); else
this_body() -> simple_action ( pour_action, this_object(), how, where );
if ( add_fluid( fluid_already() )) return;
if (evaporate_action)
{
remove_call_out( 0 );
if (functionp(evaporate_action)) evaluate( evaporate_action);
else call_out( evaporate_puddle , evap_amount );
};
move( ob2 );
remove_adj( query_primary_adj() );// This avoids strange bugs.
set_proper_name( query_puddle_name() );
add_id( puddle_id );
}
else if ( ob2 -> part_fill_with( this_object() ))
{
if (functionp( pour_action ) ) evaluate( pour_action ); else
this_body() -> simple_action ( pour_action, this_object(), how, where );
};
}
int will_fit( object bottle ){
int fluid_size;
int room_left;
#ifdef USE_SIZE
fluid_size = query_size();
#endif
#ifdef USE_MASS
fluid_size = query_mass();
#endif
room_left =
bottle -> query_max_capacity()
- bottle -> query_capacity() ;
return (fluid_size <= room_left);
}
mixed move_fluid ( object bottle ){
if (!will_fit( bottle )) return 0;
move( bottle );
return 1;
}
void remove_puddle(){
remove_call_out( 0 );
simple_action("The $o dwindles to nothing.", this_object() );
remove();
}
void evaporate_puddle_func(){
#ifdef USE_SIZE
set_size( query_size() -1 );
if( query_size() <= 0 ) {remove_puddle(); return;};
#endif
#ifdef USE_MASS
set_mass( query_mass() -1 );
if( query_mass() <= 0 ) {remove_puddle(); return;};
#endif
this_object() -> simple_action
( evaporate_action, this_object() );
call_out( evaporate_puddle, evap_time );
}
mixed drop(){
mixed msg;
msg = ::drop();
if (msg)
{
add_id( puddle_id );
add_fluid( fluid_already() );
};
return msg;
}
mixed get(){
mixed msg;
msg = ::get();
if (msg)
{
remove_id( puddle_id );
add_fluid( fluid_already( 0, this_body() ) );
};
return msg;
}
//By default, fluids are not drinkable.
void drink_it(){
this_body() -> my_action( "It is not a good idea to drink $o.", short() );
}
//:FUNCTION fill_action
//fill_action(container)
//This function is called by the container
//in the fluid just before it fills the container.
//The container passes itself as an argument.
//This function must return a 1 for the filling
//to continue. This gives the fluid itself
//an opportunity to halt the filling action.
int fill_action( object vessel ){ return 1; }
int have_fluid(){
if (environment( environment( this_object() ) ) == this_body() )
return 1;
return 0;
}
int direct_pour_obj(){
return have_fluid();
}
int direct_pour_obj_out(){
return have_fluid();
}
int direct_pour_obj_wrd_obj(){
return have_fluid();
}
int indirect_fill_obj_with_obj() {
return 1;
}
mixed direct_drink_obj(){ return 1;}
mixed direct_drink_obj_from_obj(){
return 1;
}