/* -*- LPC -*- */
/*
* $Locker: $
* $Id: id.c,v 1.18 2002/03/15 21:59:19 tannah Exp $
*/
/**
* This class keeps track of all the aliases, names and adjectives
* which are used to match the object.
* @see /global/player->add_command()
* @see /std/basic/desc.c
*/
#include <parse_command.h>
inherit "/std/basic/id_match";
class Id {
string name;
string *alias;
string *faux_alias;
string *unique_faux_alias;
string *adjectives;
string *faux_adjectives;
string *unique_faux_adjectives;
string *plural_adjectives;
string *plurals;
}
private nosave class Id _id;
int id_adjective(string);
int id_plural(string str);
int faux_id_allowed();
private void setup_id_class() {
if (_id) {
return ;
}
_id = new( class Id );
_id->alias = ({ });
_id->faux_alias = ({ });
_id->unique_faux_alias = ({ });
_id->plurals = ({ });
_id->adjectives = ({ });
_id->faux_adjectives = ({ });
_id->unique_faux_adjectives = ({ });
_id->plural_adjectives = ({ });
_id->name = "object";
} /* setup_id_class() */
/* name handling stuff */
/**
* This method sets the name of the object. The name is the basic handle
* used to reference the object. It should not have any spaces
* in it.
* @example
* set_name("rabbit");
* @param str the name
* @see query_name()
* @see add_alias()
* @see add_adjective()
*/
void set_name(string str) {
_id->name = str;
}
/**
* This method returns the name of the object.
* @return the name of the object
* @see set_name()
* @see add_alias()
* @see add_adjective()
*/
string query_name() {
if (!_id) {
return 0;
}
return _id->name;
}
/**
* This method returns the capitalized name. It calls the function
* capitalize() on the name
* @see query_name()
* @see set_name()
* @see efun::capitalize()
*/
string query_cap_name() {
if (!_id->name) {
return "Someone";
}
return capitalize(_id->name);
}
void create() {
setup_id_class();
}
/* alias stuff */
/**
* This method sets the entire alias array. It overrides any current alias
* definitions and sets the alias arry. This should be used carefully
* if at all. Use add_alias instead.
* @param str the new alias array
*/
void set_aliases(string *str) {
_id->alias = str;
}
/**
* This method adds an alias to the object. An alias for the object is the
* part used as the main noun for the object. ie in the case of a "green
* bath tub", "bathtub" might be an alias for the object. and "green"
* and "bath" would be adjectives. The value set with add_alias is also
* used with present. This means you can make up an alias for an object
* that players cannot normaly access but you can
* get a handle on with present. For an exmple of this look at the money
* object.
* <p>
* The function takes an array or a string as an argument. If an array
* is passed in each element of the array is added to the alias
* array, if it is a string then the string elemnt is added to the
* array.
* @param str the alias(s) to add
* @see set_name()
* @see remove_alias()
* @see set_aliases()
* @see query_alias()
* @example
* set_name("tub");
* set_short("green bath tub");
* add_alias("bathtub");
* add_adjective("green");
* add_adjective("bath");
*/
void add_alias(mixed str) {
if (pointerp(str)) {
_id->alias += str;
return;
}
if (member_array(str, _id->alias) == -1) {
_id->alias += ({ str });
}
}
/**
* This method removes an alias from the object.
* @see add_alias()
* @see query_alias()
* @param str the alias to remove
* @return 1 if the alias is found, 0 if not
*/
int remove_alias(string str) {
int i;
i = member_array(str, _id->alias);
if (i == -1) {
return 0;
}
_id->alias = _id->alias[0..i - 1] + _id->alias[i + 1..];
return 1;
}
/**
* This method returns the current list of aliases. If faux aliases are
* allowed, they are included, unless the optional parameter is passed.
* @param no_faux 1 to ignore faux aliases (optional)
* @see add_alias()
* @see add_faux_alias()
* @see query_faux_alias()
* @see query_unique_faux_alias()
* @see remove_alias()
* @return the array of aliases (array of strings)
*/
varargs string *query_alias( int no_faux ) {
if( no_faux ||
!sizeof( _id->unique_faux_alias ) ||
!faux_id_allowed() )
return _id->alias;
else
return _id->alias + _id->unique_faux_alias;
}
/**
* This method adds a faux alias to the object. Faux aliases are
* ignored by objects that ignore identifiers.
* <p>
* The function takes an array or a string as an argument. If an array
* is passed in each element of the array is added to the faux alias
* array, if it is a string then the string element is added to the
* array. Elements that are already real aliases of the object are ignored.
* Duplication in this list is allowed; a separate list without duplicates
* is maintained to improve performance.
* @param str the alias(s) to add
* @see query_faux_alias()
* @see query_unique_faux_alias()
* @see add_alias()
* @see add_faux_adjective()
* @see remove_faux_alias()
* @see ignore_identifiers()
* @see parse_command_id_list()
* @example
*/
void add_faux_alias(mixed str) {
if (pointerp(str)) {
foreach( string aka in str )
add_faux_alias( aka );
return;
}
// don't duplicate real aliases
if( member_array( str, _id->alias ) != -1 )
return;
// allowed duplication in the _faux_alias list is intentional
_id->faux_alias += ({ str });
// no duplication allowed in the unique list
_id->unique_faux_alias = _id->unique_faux_alias | ({ str });
}
/**
* This method removes a faux alias from the object. Note that, if the
* alias has been added more than once, only one instance is removed
* from the array. If the last instance of an alias is removed from the
* list, it is also removed from the unique list.
* @see add_faux_alias()
* @see add_faux_adjective()
* @see query_alias()
* @see query_unique_faux_alias()
* @param str the faux alias to remove
* @return 1 if the alias is found, 0 if not
*/
int remove_faux_alias(string str) {
int i;
i = member_array(str, _id->faux_alias);
if (i == -1) {
return 0;
}
// only remove one instance from the faux list
_id->faux_alias = _id->faux_alias[0..i - 1] +
_id->faux_alias[i + 1..];
// only remove it from the unique list if there are no more instances
// of it in the faux list.
if( member_array(str, _id->faux_alias) == -1 ) {
_id->unique_faux_alias -= ({ str });
}
return 1;
}
/**
* This method returns the current list of faux aliases, with duplicates
* included.
* @see add_faux_alias()
* @see remove_faux_alias()
* @see query_unique_faux_alias()
* @return the array of faux aliases (array of strings)
*/
string *query_faux_alias() {
return _id->faux_alias;
}
/**
* This method returns the unique list of faux aliases. It is this list
* that id() uses.
* @see query_faux_alias()
* @see id()
* @return the array of faux aliases (array of strings) without duplication
*/
string *query_unique_faux_alias() {
return _id->unique_faux_alias;
}
/**
* This method is used by the id function. It determines whether or
* not an object in the calling list ignores identifiers.
* If none do, then faux aliases may be used.
* @return 1 if faux ids may be used
* @see add_faux_alias
* @see add_faux_adjective
* @see ignore_identifiers
*/
int faux_id_allowed() {
foreach( object ob in previous_object(-1) ) {
if( objectp(ob) && ob->ignore_identifier() )
return 0;
}
return 1;
}
/**
* This method is used by the present efun. It determines if the
* passed in string is an alias or the name of the object.
* @param str the value to check
* @return 1 if the name matches
*/
int id(string str) {
return (str == _id->name ||
(member_array(str, query_alias()) != -1) );
}
/** @ignore yes */
int full_id(string str) {
string *words;
string name;
string adjective;
words = explode(str, " ") - ({ "" });
name = words[<1];
words = words[0.. < 2];
if (!id(name)) {
if (!id_plural(name)) {
return 0;
}
}
foreach(adjective in words) {
if (!id_adjective(adjective)) {
return 0;
}
}
return 1;
}
/* plural stuff */
/**
* This method sets the compete array of plurals. This shod
* not be used, use add_plural and remove_plural instead.
* @see add_plural()
* @see remove_plural()
* @see query_plurals()
*/
void set_plurals(string *str) {
_id->plurals = str;
}
/**
* This method adds a plural onto the object. The plurals will be
* used in plural name matching by thje find_match simul_efun
* @see /secure/simul_efun->find_match()
* @see set_plurals()
* @see remove_plural()
* @see query_plurals()
* @see add_plurals()
*/
void add_plural(mixed str) {
if (pointerp(str)) {
_id->plurals += str;
} else if (_id->plurals) {
if (member_array(str, _id->plurals) == -1) {
_id->plurals += ({ str });
}
} else {
_id->plurals = ({ str });
}
}
/**
* This method removes a plural from the object.
* @param str the plural to remove
* @see add_plural()
* @see query_plurals()
* @see set_plurals()
*/
void remove_plural(string str) {
int i;
i = member_array(str, _id->plurals);
if (i != -1) {
_id->plurals = _id->plurals[0..i - 1] + _id->plurals[i + 1..];
}
}
/**
* This method adds multiple plurals to the object.
* @param str the array of plurals to add
* @see add_plural()
* @see remove_plural()
* @see query_plurals()
*/
void add_plurals(string *str) {
_id->plurals += str;
}
/**
* This method returns the complete list of plurals for the
* object.
* @return the complete array of plurals
*/
string *query_plurals() {
return _id->plurals;
}
/**
* This method is similar to the id function, except this will check the
* plural names instead of the aliases and the name.
* @param str the name to check
* @return 1 if the name matches one of the plurals, 0 otherwise
* @see id()
* @see id_adjective()
*/
int id_plural(string str) {
return (member_array(str, _id->plurals) != -1);
}
/**
* This method sets all the adjectives for the object. This method
* should not be used, please use add_adjective instead.
* @see add_adjective()
* @see remove_adjective()
* @see query_adjectives()
* @param str the array of adjectives
*/
void set_adjectives(string *str) {
_id->adjectives = str;
}
/**
* This method adds an adjective to the object. The adjectives are used
* for the object matching routines. For example, if you have a "green
* bath tun" then "green" and "bath" are adjectives.
* @see add_alias()
* @see remove_adjective()
* @see query_adjectives()
* @see set_adjectives()
*/
void add_adjective(mixed str) {
int i;
if (pointerp(str)) {
for (i = 0; i < sizeof(str); i++) {
add_adjective(str[i]);
}
return;
}
if (stringp(str)) {
str = explode(str, " ");
}
for (i = 0; i < sizeof(str); i++) {
if (member_array(str[i], _id->adjectives) == -1) {
_id->adjectives += ({ str[i] });
}
}
}
/**
* This method will remove an adjective from the object.
* @see add_alias()
* @see add_adjective()
* @see query_adjectives()
* @param str the adective(s) to remove
*/
void remove_adjective(mixed str) {
int i;
if (pointerp(str)) {
for (i = 0; i < sizeof(str); i++) {
remove_adjective(str[i]);
}
} else {
if ((i = member_array(str, _id->adjectives)) != -1) {
_id->adjectives = delete(_id->adjectives, i, 1);
}
}
}
/**
* This method adds a faux adjective to the object. Faux adjectives are
* ignored by objects that ignore identifiers.
* <p>
* The function takes an array or a string as an argument. If an array
* is passed in each element of the array is added to the faux adjective
* array, if it is a string then each word in the string element is added
* to the array. Elements that are already real adjectives of the object
* are ignored.
* @see add_adjective()
* @see remove_faux_adjective()
* @see ignore_identifiers()
*/
void add_faux_adjective(mixed str) {
if (pointerp(str)) {
foreach( string adj in str )
add_faux_adjective( adj );
return;
}
if( stringp( str ) ) {
str = explode(str, " ");
}
// don't duplicate real adjectives
str -= _id->adjectives;
foreach( string adj in str ) {
// duplication desired in faux list...
_id->faux_adjectives += ({ adj });
// ...but not in unique list.
_id->unique_faux_adjectives = _id->unique_faux_adjectives |
({ adj });
}
}
/**
* This method will remove a faux adjective from the object. Note that,
* if the adjective has been added more than once, only one instance is
* removed from the array.
* @see add_faux_alias()
* @see add_faux_adjective()
* @see query_adjectives()
* @param str the adective(s) to remove
*/
void remove_faux_adjective(mixed str) {
int i;
if (pointerp(str)) {
foreach( string adj in str )
remove_faux_adjective( adj );
return;
}
i = member_array(str, _id->faux_adjectives);
if( i == -1 )
return;
_id->faux_adjectives = _id->faux_adjectives[0..i-1] +
_id->faux_adjectives[i+1..];
// if it's the last instance of this adjective, remove it from the
// unique list, too.
if( ( i = member_array( str, _id->faux_adjectives ) ) == -1 )
_id->unique_faux_adjectives -= ({ str });
}
/**
* This method returns the current list of faux adjectives, including
* duplicates.
* @see add_faux_adjective()
* @see remove_faux_adjective()
* @see query_adjectives()
* @see query_unique_faux_adjectives()
* @return the array of faux adjectives (array of strings)
*/
string *query_faux_adjectives() {
return _id->faux_adjectives;
}
/**
* This method returns a unique list of faux adjectives.
* @see query_adjectives()
* @see id_adjective()
* @see remove_faux_adjective()
* @return the array of faux adjectives (array of strings)
*/
string *query_unique_faux_adjectives() {
return _id->unique_faux_adjectives;
}
/**
* This method returns the current list of adjectives associated with
* this object. If faux ids are allowed, then faux adjectives are
* included if the optional parameter is not 1.
* @param no_faux 1 to ignore faux adjectives
* @return the complete list of adjectives
*/
varargs string *query_adjectives( int no_faux ) {
if( no_faux ||
!sizeof( _id->unique_faux_adjectives ) ||
!faux_id_allowed() )
return _id->adjectives;
else
return _id->adjectives + _id->unique_faux_adjectives;
}
/**
* This method is similar to the id function, except this will check the
* adjectives instead of the aliases and the name.
* @param str the adjective to check
* @return 1 if the name matches one of the adjectives, 0 otherwise
* @see id()
* @see id_plural()
*/
int id_adjective(string word) {
return (member_array(word, query_adjectives()) != -1);
}
/**
* This method sets all the plural adjectives for the object. This method
* should not be used, please use add_plural_adjective instead.
* @see add_plural_adjective()
* @see remove_plural_adjective()
* @see query_plural_adjectives()
* @param str the array of plural adjectives
*/
void set_plural_adjectives(string *str) {
_id->plural_adjectives = str;
}
/**
* This method adds an plural adjective to the object. The plural
* adjectives are used for the
* object matching routines. Plural adjectives should be used very rarely,
* they are used in cases where the plural of a name is determined by the
* adjective rather than it's alias. For example: pair of shoes, pairs
* of shoes.
* @see add_alias()
* @see remove_plural_adjective()
* @see query_plural_adjectives()
* @see set_plural_adjectives()
*/
void add_plural_adjective(mixed str) {
int i;
if (pointerp(str)) {
for (i = 0; i < sizeof(str); i++) {
add_plural_adjective(str[i]);
}
return;
}
if (stringp(str)) {
str = explode(str, " ");
}
for (i = 0; i < sizeof(str); i++) {
if (member_array(str[i], _id->plural_adjectives) == -1) {
_id->plural_adjectives += ({ str[i] });
}
}
}
/**
* This method will remove an plural adjective from the object.
* @see add_alias()
* @see add_plural_adjective()
* @see query_plural_adjectives()
* @param str the adective(s) to remove
*/
void remove_plural_adjective(mixed str) {
int i;
if (pointerp(str)) {
for (i = 0; i < sizeof(str); i++) {
remove_plural_adjective(str[i]);
}
} else {
if ((i = member_array(str, _id->plural_adjectives)) != -1) {
_id->plural_adjectives = delete(_id->plural_adjectives, i, 1);
}
}
}
/**
* This method returns the current list of plural adjectives associated with
* this object.
* @return the complete list of plural adjectives
*/
string *query_plural_adjectives() {
return _id->plural_adjectives;
}
/**
* This method is similar to the id function, except this will check the
* plural adjectives instead of the aliases and the name.
* @param str the name to check
* @return 1 if the name matches one of the plurals, 0 otherwise
* @see id()
* @see id_plural()
*/
int id_plural_adjective(string word) {
return (member_array(word, _id->plural_adjectives) != -1);
}
/* ok parse command stuff */
/** @ignore yes */
string *parse_command_id_list() {
return ({ _id->name, file_name(this_object()) }) + query_alias();
}
/** @ignore yes */
string *parse_command_plural_id_list() {
return query_plurals();
}
/** @ignore yes */
string *parse_command_adjectiv_id_list() {
return query_adjectives();
}
/** @ignore yes */
string *parse_command_plural_adjectiv_id_list() {
return query_plural_adjectives();
}
/** @ignore yes */
object query_parse_id(mixed *arr) {
if (arr[P_THING] == 0) {
return this_object();
}
if (arr[P_THING] < 0) { /* specific object case */
arr[P_THING]++;
if (arr[P_THING] != 0) {
return 0;
}
arr[P_THING] = -10321;
return this_object();
}
arr[P_THING]--; /* lots of objects case */
if (arr[P_THING] != 0) {
return this_object();
}
arr[P_THING] = -10101;
return this_object();
}
/** @ignore yes */
object query_frac_parse_id(mixed *arr) {
if (arr[P_THING] < 0) {
arr[P_THING]++;
if (arr[P_THING] != 0) {
return 0;
}
arr[P_THING] = -10235;
return 0; /* it refered to me and I am pretty
* depressed about it.
* I want to break free!
*/
}
if (arr[P_THING] == 0) {
if ((arr[P_MAX_NUM] * arr[P_TOP]) / arr[P_BOT] > arr[P_CUR_NUM]++) {
return this_object();
} else {
return 0;
}
}
if ((arr[P_THING] * arr[P_TOP]) / arr[P_BOT] > arr[P_CUR_NUM]++) {
return this_object();
}
return 0;
}