#define SKILL "other.perception"
private nosave mapping _hide_invis;
void create() {
_hide_invis = ([]);
} /* create() */
/**
* This method returns the current hide/invisible states on the object.
* The mapping is of the format:\n
* <pre>
* ([ <hide type name> :
* ({
* who,
* see,
* ({ obj, method }), // Remove method
* }),
* ...
* ])
* </pre>
* @return the hide invis mapping as above
*/
mapping query_hide_invis() {
return copy( _hide_invis );
}
/**
* This method adds a hide/invis state to the object.
* @param type the name of the type of hiding
* @param who no idea
* @param see no idea
* @param gone the method and object to call when the hiding is removed
* @return 1 on success, 0 on failure
*/
int add_hide_invis( string type, object who, mixed see, string *gone ) {
if( _hide_invis[type] ) {
return 0;
}
_hide_invis[type] = ({ who, see, gone });
if( environment( this_object() ) ) {
event( environment( this_object() ), "hide_invis", 1, type, 0 );
}
return 1;
} /* add_hide_invis() */
/**
* This method removed the hiding of the specified type off the object.
* This method will call the function setup when the hiding was added
* when the hiding is removed. If you pass 1 as the second argument, it
* will send the 'quiet' flag to the callback function.
* @param type the type of hiding to remove
* @param quiet flag to pass along to the callback function
* @return 1 on success, 0 on failure
*/
varargs int remove_hide_invis( string type, int quiet ) {
mixed *gone;
if( !_hide_invis[type] ) {
return 0;
}
gone = _hide_invis[type][2];
if( sizeof( gone ) == 2 && gone[0] )
if( quiet )
call_other( gone[0], gone[1], quiet );
else
call_other( gone[0], gone[1] );
map_delete( _hide_invis, type );
if( environment( this_object() ) ) {
event( environment( this_object() ), "hide_invis", 0, type, quiet );
}
return 1;
} /* remove_hide_invis() */
/**
* This does a perception check to see if the person can be seen.
* This is variable on light level, amongst other things.
* @param thing the person doing the looking
*/
int perception_check( object thing ) {
int perception;
perception = thing->query_skill_bonus( SKILL );
if( !environment( thing ) || !perception )
return perception;
switch( thing->check_dark( (int)environment( thing )->query_light() ) ) {
case -2:
case 2:
perception /= 4;
break;
case -1:
case 1:
perception /= 2;
break;
default:
break;
}
return perception;
} /* perception_check() */
/**
* This is the method called to check to see if the person is visible or
* not.
* This is masked in /global/wiz_file_comm to handle
* creator invisibility.
* @param thing the object doing the looking
* @return 1 if visible, 0 if not
*/
int query_visible( object thing ) {
int i;
string *types;
mixed see;
if( thing == this_object() ) {
return 1;
}
if( thing->query_creator() || thing->query_property( "demon" ) ) {
return 1;
}
if( thing->query_blinded() ) {
return 0;
}
types = keys( _hide_invis );
if( !sizeof( types ) ) {
return 1;
}
for( i = 0; i < sizeof( types ); i++ ) {
if( _hide_invis[types[i]][0] == thing ) {
continue;
}
see = _hide_invis[types[i]][1];
if( intp( see ) ) {
if( perception_check( thing ) > see ) {
continue;
}
return 0;
}
if( stringp( see ) ) {
if( call_other( thing, see ) ) {
continue;
}
return 0;
}
/* Maybe other possibilities later. */
return 0;
}
return 1;
} /* query_visible() */
/**
* This method returns an extra bit to stick on the end of the players
* name to show when they are hiding and so on.
* @return the extra bit to stick after a person's name based on the state
*/
string hide_invis_string() {
int i;
string list;
string *types;
types = keys( _hide_invis );
if( !sizeof( types ) ) {
return "";
}
list = "";
for( i = 0; i < sizeof( types ); i++ ) {
list += " ("+ types[i] +")";
}
return list;
} /* hide_invis_string() */