/** * This inheritable contains all the code to deal with matching objects in * the parser. * @author Pinkfish. */ #include <obj_parser.h> private int _no_all; /** * This sets the no all flag. If this flag is set to true then the object * will not respond to 'all' requests and must be accessed with it's real * name. * @param no_all the no all flag value */ protected void set_no_all(int no_all) { _no_all = no_all; } /* set_no_all() */ /** * This method returns the no all flag's current value. * If this flag is set to true then the object * will not respond to 'all' requests and must be accessed with it's real * name. * @return the current value of the flag */ int query_no_all() { return _no_all; } /* query_no_all() */ /** * This method is used by upper objects that only wish to match the * ids and not mess with all the context stuff. This method will * return a combination of OBJ_PARSER_MATCH_SINGULAR and * OBJ_PARSER_MATCH_PLURAL. * @param input the input string * @param viewer the person viewing the object * @param context the contex this is to be taken in * @return the singular/plural match flags */ protected int is_matching_object(string* input, object viewer, class obj_match_context context ) { string *adj; string *padj; string *names; string *pnames; int n; int ret; /* context */ if( this_object() == context->him && input[<1] == "him" ) { ret |= OBJ_PARSER_MATCH_SINGULAR; } else if( this_object() == context->her && input[<1] == "her" ) { ret |= OBJ_PARSER_MATCH_SINGULAR; } else if( this_object() == context->it && input[<1] == "it" ) { ret |= OBJ_PARSER_MATCH_SINGULAR; } else if( context->plural && input[<1] == "them" && member_array( this_object(), context->plural ) != -1 ) { ret |= OBJ_PARSER_MATCH_PLURAL; } else if( this_object() == viewer && input[<1] == "me" ) { ret |= OBJ_PARSER_MATCH_SINGULAR; } else if (!_no_all && input[<1] == "all") { ret |= OBJ_PARSER_MATCH_PLURAL; } else if (!_no_all && (input[<1] == "things" || input[<1] == "ones")) { ret |= OBJ_PARSER_MATCH_PLURAL; } else if (!_no_all && (input[<1] == "thing" || input[<1] == "one")) { ret |= OBJ_PARSER_MATCH_SINGULAR; } if (!ret) { // // Strip off the here if it is the right place for it. // if (input[<1] == "here" && viewer != environment() && sizeof(input) > 1) { input = input[0..<2]; } // // CHeck to see if we match the noun first. // names = this_object()->parse_command_id_list(); pnames = this_object()->parse_command_plural_id_list(); if( member_array( input[<1], pnames ) != -1 ) { ret |= OBJ_PARSER_MATCH_PLURAL; } if( member_array( input[<1], names ) != -1 ) { ret |= OBJ_PARSER_MATCH_SINGULAR; } if (!ret) { return 0; } } // // Check and make sure we match all the adjectives. // adj = this_object()->parse_command_adjectiv_id_list(); padj = this_object()->parse_command_plural_adjectiv_id_list(); if( environment() == context->him ) { adj += ({ "his" }); } else if( environment() == context->her ) { adj += ({ "her" }); } else if( environment() == context->it ) { adj += ({ "its" }); } else if( environment() == viewer ) { adj += ({ "my" }); } else if( context->plural && member_array( environment(), context->plural ) != -1 ) { adj += ({ "their" }); } for( n = 0; n < sizeof( input ) - 1; n++ ) { if( member_array( input[n], adj ) == -1 ) { if (!padj || member_array(input[n], padj) == -1) { return 0; } else { ret &= ~OBJ_PARSER_MATCH_SINGULAR; ret |= OBJ_PARSER_MATCH_PLURAL; } } } return ret; } /* is_matching_object() */ /** * This method updates the context. It returns the number of the objects * we match, and you pass in the number of objects that we are. * @param context the context to update * @param num the number of objects * @param singular return from is_matching_object * @return the number of matched objects */ protected int update_parse_match_context(class obj_match_context context, int num, int singular) { if (context->ordinal) { if (context->ordinal == -1) { return 1; } if (context->ordinal > num) { context->ordinal -= num; return 0; } context->ignore_rest = 1; return 1; } else if (context->number_included) { if (context->number_included <= num) { context->ignore_rest = 1; num = context->number_included; context->number_included = 0; return num; } context->number_included -= num; return num; } else { // // Just a singular reference. // if (num > 0 && (singular & OBJ_PARSER_MATCH_SINGULAR)) { return 1; } // // All state. // return num; } } /* update_parse_match_context() */ /** * This code is for the new parser... It returns an array which contains * two elements. The first is the type of the match, plural or singular, * and the second is the object it matched. Usualy this_object() but * it can be used to swap new objects. * @param input the input string * @param viewer the person viewing the object * @param context the contex this is to be taken in * @return ({ type, ob }), 0 on failure */ mixed parse_match_object( string* input, object viewer, class obj_match_context context ) { int ret; ret = is_matching_object(input, viewer, context); if (!ret) { return 0; } // // We matched, so see if we should have. // if (!update_parse_match_context(context, 1, ret)) { return 0; } return ({ ret, ({ this_object() }) }); } /* parse_match_object() */