/**
* This method handles the light changing and control.
* @author Pinkfish
*/
private nosave int _light;
private nosave int _my_light;
private nosave int _need_recalculate;
private nosave object *_inform_of_change;
void new_recalc_light();
mixed query_property( string name );
void add_property( string name, mixed value );
void remove_property( string name );
void create() {
_inform_of_change = ({ });
} /* create() */
/**
* This returns the total light level of the object. This includes the
* light levels of anything that happens to be inside us.
* @return current light level
* @see query_my_light()
* @see set_light()
*/
int query_light() {
if( _need_recalculate ) {
_need_recalculate = 0;
new_recalc_light();
}
return _light;
} /* query_light() */
int query_light_needs_inform() {
return _light || _need_recalculate;
} /* query__light_needs_inform() */
/**
* This method returns the light associated with this object. This does
* not count the light levels of anything inside us.
*/
int query_my_light() { return _my_light; }
/**
* This method forces a recalculation of the current light level in this
* object.
*/
varargs void new_recalc_light() {
object *obs;
object ob;
_need_recalculate = 0;
obs = INV(TO);
// Use the square root of the squares to make the differences
// not so wild.
_light = query_my_light() * query_my_light();
if( !TO->query_opaque() ) {
foreach( ob in obs ) {
// If it is opaque, we do not count the light of the contents.
_light += ( ob->query_opaque() ?
( ob->query_my_light() * ob->query_my_light() ) :
( ob->query_light() * ob->query_light() ) );
}
}
_light = to_int( sqrt( to_float( _light ) ) );
_inform_of_change->event_light_change( TO, 0, _light );
} /* new_recalc_light() */
/**
* This method tells us that the light levels have changed and should
* be recalculated when queried.
* @see inform_of_light_level_change()
*/
void light_level_changed() {
_need_recalculate = 1;
} /* light_level_changed() */
/**
* This method tells all our environments that the light level has
* changed.
* @param ob the object whose environment we should tell about the change
* @see light_level_changed()
*/
void inform_of_light_level_change( object ob ) {
if( ob )
ob->light_level_changed();
while( ob && !ob->query_opaque() ) {
ob->light_level_changed();
ob = ENV(ob);
}
} /* inform_of_light_level_change() */
/**
* This method adds an object to be informed of light change events.
* @param ob the object to be informed of light change events
*/
void add_inform_light_change(object ob) {
_inform_of_change += ({ ob });
} /* add_inform_lifht_change() */
/**
* This method removes an object from the current list of things to
* be informed of a light change.
* @param ob the object to remove from the inform list
*/
void remove_inform_light_change(object ob) {
_inform_of_change -= ({ ob });
} /* remove_inform_light_change() */
/**
* This method makes this object opaque. This means that light does not
* escpae from it.
* @see not_obscured_object()
* @see set_light()
*/
void set_opaque() {
add_property( "opaque", 1 );
} /* set_opaque() */
/**
* This method makes the object transparent (default). This means that the
* light from items inside does escape.
* @see set_opaque()
* @see set_light()
*/
void reset_opaque() {
remove_property( "opaque" );
} /* reset_opaque() */
/**
* This method checks to see if the object is opaque or not.
* @return 1 if it is opaque, 0 if not
*/
int query_opaque() {
return query_property("opaque");
} /* query_opaque() */
/**
* This changes the current light level.
* @param number the amount to chage it by
* @see set_light()
* @see query_my_light()
* @see query_light()
*/
int adjust_light( int number ) {
if( number ) {
_my_light += number;
inform_of_light_level_change(TO);
}
return _light;
} /* adjust_light() */
/**
* This sets the current light level. This method calls adjust_light()
* with the correct value to set the light level.
* <BR><BR>
* Light Levels:
* <BR>
* Magically Darkened Room 0-
* <BR>
* Absolutely Dark Room 0
* <BR>
* Standard Dark Room 5
* <BR>
* Dimly Lit Room 20
* <BR>
* Mine Shaft with Candles 30
* <BR>
* Partially Lit Room 50
* <BR>
* Well Lit Room 60
* <BR>
* Shaded Forest 60
* <BR>
* Brightly Lit Room 80
* <BR>
* Direct Sunlight 100
* <BR>
* Explosion or flash 200+
* <BR>
* @param number The new light level.
* @see query_my_light()
* @see query_light()
*/
int set_light(int number) {
return adjust_light( number - _my_light );
} /* set_light() */
/** @ignore yes */
mixed *stats() {
return ({
({ "light", _light, }),
({ "my light", _my_light, }),
});
} /* stats() */