home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / tinymud2.zip / MATCH.C < prev    next >
C/C++ Source or Header  |  1990-09-02  |  5KB  |  261 lines

  1. #include "copyright.h"
  2.  
  3. /* Routines for parsing arguments */
  4. #include <ctype.h>
  5.  
  6. #include "db.h"
  7. #include "config.h"
  8. #include "match.h"
  9.  
  10. #define DOWNCASE(x) (isupper(x) ? tolower(x) : (x))
  11.  
  12. static dbref exact_match = NOTHING;    /* holds result of exact match */
  13. static int check_keys = 0;    /* if non-zero, check for keys */
  14. static dbref last_match = NOTHING;    /* holds result of last match */
  15. static int match_count;        /* holds total number of inexact matches */
  16. static dbref match_who;    /* player who is being matched around */
  17. static const char *match_name;    /* name to match */
  18. static int preferred_type = NOTYPE; /* preferred type */
  19.  
  20. void init_match(dbref player, const char *name, int type)
  21. {
  22.     exact_match = last_match = NOTHING;
  23.     match_count = 0;
  24.     match_who = player;
  25.     match_name = name;
  26.     check_keys = 0;
  27.     preferred_type = type;
  28. }
  29.  
  30. void init_match_check_keys(dbref player, const char *name, int type)
  31. {
  32.     init_match(player, name, type);
  33.     check_keys = 1;
  34. }
  35.  
  36. static dbref choose_thing(dbref thing1, dbref thing2)
  37. {
  38.     int has1;
  39.     int has2;
  40.  
  41.     if(thing1 == NOTHING) {
  42.     return thing2;
  43.     } else if(thing2 == NOTHING) {
  44.     return thing1;
  45.     }
  46.  
  47.     if(preferred_type != NOTYPE) {
  48.     if(Typeof(thing1) == preferred_type) {
  49.         if(Typeof(thing2) != preferred_type) {
  50.         return thing1;
  51.         }
  52.     } else if(Typeof(thing2) == preferred_type) {
  53.         return thing2;
  54.     }
  55.     }
  56.  
  57.     if(check_keys) {
  58.     has1 = could_doit(match_who, thing1);
  59.     has2 = could_doit(match_who, thing2);
  60.  
  61.     if(has1 && !has2) {
  62.         return thing1;
  63.     } else if (has2 && !has1) {
  64.         return thing2;
  65.     }
  66.     /* else fall through */
  67.     }
  68.  
  69.     return (random() % 2 ? thing1 : thing2);
  70. }
  71.  
  72. void match_player(void)
  73. {
  74.     dbref match;
  75.     const char *p;
  76.  
  77.     if(*match_name == LOOKUP_TOKEN) {
  78.     for(p = match_name + 1; isspace(*p); p++);
  79.     if((match = lookup_player(p)) != NOTHING) {
  80.         exact_match = match;
  81.     }
  82.     }
  83. }
  84.  
  85. /* returns nnn if name = #nnn, else NOTHING */
  86. static dbref absolute_name(void)
  87. {
  88.     dbref match;
  89.  
  90.     if(*match_name == NUMBER_TOKEN) {
  91.     match = parse_dbref(match_name+1);
  92.     if(match < 0 || match >= db_top) {
  93.         return NOTHING;
  94.     } else {
  95.         return match;
  96.     }
  97.     } else {
  98.     return NOTHING;
  99.     }
  100. }
  101.  
  102. void match_absolute(void)
  103. {
  104.     dbref match;
  105.  
  106.     if((match = absolute_name()) != NOTHING) {
  107.     exact_match = match;
  108.     }
  109. }
  110.  
  111. void match_me(void)
  112. {
  113.     if(!string_compare(match_name, "me")) {
  114.     exact_match = match_who;
  115.     }
  116. }
  117.  
  118. void match_here(void)
  119. {
  120.     if(!string_compare(match_name, "here")
  121.        && db[match_who].location != NOTHING) {
  122.     exact_match = db[match_who].location;
  123.     }
  124. }
  125.  
  126. static void match_list(dbref first)
  127. {
  128.     dbref absolute;
  129.  
  130.     absolute = absolute_name();
  131.     if(!controls(match_who, absolute)) absolute = NOTHING;
  132.  
  133.     DOLIST(first, first) {
  134.     if(first == absolute) {
  135.         exact_match = first;
  136.         return;
  137.     } else if(!string_compare(db[first].name, match_name)) {
  138.         /* if there are multiple exact matches, randomly choose one */
  139.         exact_match = choose_thing(exact_match, first);
  140.     } else if(string_match(db[first].name, match_name)) {
  141.         last_match = first;
  142.         match_count++;
  143.     }
  144.     }
  145. }
  146.     
  147. void match_possession(void)
  148. {
  149.     match_list(db[match_who].contents);
  150. }
  151.  
  152. void match_neighbor(void)
  153. {
  154.     dbref loc;
  155.  
  156.     if((loc = db[match_who].location) != NOTHING) {
  157.     match_list(db[loc].contents);
  158.     }
  159. }
  160.  
  161. void match_exit(void)
  162. {
  163.     dbref loc;
  164.     dbref exit;
  165.     dbref absolute;
  166.     const char *match;
  167.     const char *p;
  168.  
  169.     if((loc = db[match_who].location) != NOTHING) {
  170.     absolute = absolute_name();
  171.     if(!controls(match_who, absolute)) absolute = NOTHING;
  172.  
  173.     DOLIST(exit, db[loc].exits) {
  174.         if(exit == absolute) {
  175.         exact_match = exit;
  176.         } else {
  177.         match = db[exit].name;
  178.         while(*match) {
  179.             /* check out this one */
  180.             for(p = match_name;
  181.             (*p
  182.              && DOWNCASE(*p) == DOWNCASE(*match)
  183.              && *match != EXIT_DELIMITER);
  184.             p++, match++);
  185.             /* did we get it? */
  186.             if(*p == '\0') {
  187.             /* make sure there's nothing afterwards */
  188.             while(isspace(*match)) match++;
  189.             if(*match == '\0' || *match == EXIT_DELIMITER) {
  190.                 /* we got it */
  191.                 exact_match = choose_thing(exact_match, exit);
  192.                 goto next_exit;    /* got this match */
  193.             }
  194.             }
  195.             /* we didn't get it, find next match */
  196.             while(*match && *match++ != EXIT_DELIMITER);
  197.             while(isspace(*match)) match++;
  198.         }
  199.         }
  200.       next_exit:
  201.         ;
  202.     }
  203.     }
  204. }
  205.  
  206. void match_everything(void)
  207. {
  208.     match_exit();
  209.     match_neighbor();
  210.     match_possession();
  211.     match_me();
  212.     match_here();
  213.     if(Wizard(match_who)) {
  214.     match_absolute();
  215.     match_player();
  216.     }
  217. }
  218.  
  219. dbref match_result(void)
  220. {
  221.     if(exact_match != NOTHING) {
  222.     return exact_match;
  223.     } else {
  224.     switch(match_count) {
  225.       case 0:
  226.         return NOTHING;
  227.       case 1:
  228.         return last_match;
  229.       default:
  230.         return AMBIGUOUS;
  231.     }
  232.     }
  233. }
  234.        
  235. /* use this if you don't care about ambiguity */
  236. dbref last_match_result(void)
  237. {
  238.     if(exact_match != NOTHING) {
  239.     return exact_match;
  240.     } else {
  241.     return last_match;
  242.     }
  243. }
  244.  
  245. dbref noisy_match_result(void)
  246. {
  247.     dbref match;
  248.  
  249.     switch(match = match_result()) {
  250.       case NOTHING:
  251.     notify(match_who, NOMATCH_MESSAGE);
  252.     return NOTHING;
  253.       case AMBIGUOUS:
  254.     notify(match_who, AMBIGUOUS_MESSAGE);
  255.     return NOTHING;
  256.       default:
  257.     return match;
  258.     }
  259. }
  260.  
  261.