66
66
static dbref match_player(const dbref matcher, const char *match_name);
67
67
static dbref match_pmatch(const dbref matcher, const char *match_name);
68
68
static dbref choose_thing(const dbref match_who, const int preferred_type,
69
long int flags, dbref thing1, dbref thing2);
70
extern int check_alias(const char *command, const char *list); /* game.c */
69
long int flags, dbref thing1, dbref thing2);
70
extern int check_alias(const char *command, const char *list); /* game.c */
73
73
/** A wrapper for returning a match, AMBIGUOUS, or NOTHING.
83
83
match_result(const dbref who, const char *name, const int type,
86
86
return match_result_internal(who, name, type, flags);
101
101
noisy_match_result(const dbref who, const char *name, const int type,
104
104
return match_result_internal(who, name, type, flags | MAT_NOISY);
118
118
last_match_result(const dbref who, const char *name, const int type,
121
121
return match_result_internal(who, name, type, flags | MAT_LAST);
186
186
* e. If we got no matches, complain
189
#define MATCH_NONE 0x0 /**< No matches were found */
190
#define MATCH_EXACT 0x1 /**< At least one exact match found */
191
#define MATCH_PARTIAL 0x2 /**< At least one partial match found, no exact */
189
#define MATCH_NONE 0x0 /**< No matches were found */
190
#define MATCH_EXACT 0x1 /**< At least one exact match found */
191
#define MATCH_PARTIAL 0x2 /**< At least one partial match found, no exact */
192
192
/** Prototype for matching functions */
193
193
#define MATCH_FUNC_PROTO(fun_name) \
194
194
/* ARGSUSED */ /* try to keep lint happy */ \
270
270
if (!exact_matches_to_go)
271
271
match = exact_match;
272
272
else if (GoodObject(last_match))
273
match = last_match; /* nth exact-or-partial match, or nothing? */
273
match = last_match; /* nth exact-or-partial match, or nothing? */
274
274
/* This shouldn't happen, but just in case we have a valid match,
275
275
* and an invalid last_match in the matchnum case, fall through and
278
278
} else if (GoodObject(exact_match)) {
279
279
/* How many exact matches? */
280
280
if (exact_matches_to_go == -1)
281
match = exact_match; /* Good */
281
match = exact_match; /* Good */
282
282
else if (flags & MAT_LAST)
283
match = exact_match; /* Good enough */
283
match = exact_match; /* Good enough */
285
285
match = AMBIGUOUS;
287
287
if (!matches_to_go)
288
match = NOTHING; /* No matches */
288
match = NOTHING; /* No matches */
289
289
else if (matches_to_go == -1)
290
match = last_match; /* Good */
290
match = last_match; /* Good */
291
291
else if (flags & MAT_LAST)
292
match = last_match; /* Good enough */
292
match = last_match; /* Good enough */
294
294
match = AMBIGUOUS;
328
328
if (flags & MAT_ABSOLUTE) {
329
329
match = match_absolute(name);
330
330
if (GoodObject(match)) {
331
if (flags & MAT_CONTROL) {
332
/* Check for control */
333
if (controls(who, match) || nearby(who, match))
331
if (flags & MAT_CONTROL) {
332
/* Check for control */
333
if (controls(who, match) || nearby(who, match))
340
340
if (flags & MAT_PLAYER) {
341
341
match = match_player(who, name);
342
342
if (GoodObject(match))
345
345
if (flags & MAT_PMATCH) {
346
346
match = match_pmatch(who, name);
347
347
if (GoodObject(match))
351
351
/* We're doing a nearby match and the player doesn't have
391
391
*flags &= ~(MAT_POSSESSION | MAT_EXIT);
392
392
} else if (!strncasecmp(*name, "here ", 5)
393
|| !strncasecmp(*name, "this ", 5)) {
393
|| !strncasecmp(*name, "this ", 5)) {
396
~(MAT_POSSESSION | MAT_EXIT | MAT_REMOTE_CONTENTS | MAT_CONTAINER);
396
~(MAT_POSSESSION | MAT_EXIT | MAT_REMOTE_CONTENTS | MAT_CONTAINER);
399
399
if ((*flags & MAT_POSSESSION) && (!strncasecmp(*name, "my ", 3)
400
|| !strncasecmp(*name, "me ", 3))) {
400
|| !strncasecmp(*name, "me ", 3))) {
402
402
*flags &= ~(MAT_NEIGHBOR | MAT_EXIT | MAT_CONTAINER | MAT_REMOTE_CONTENTS);
439
439
} else if ((count > 10) && (count < 14)) {
440
440
if (strcasecmp(e, "th"))
442
442
} else if ((count % 10) == 1) {
443
443
if (strcasecmp(e, "st"))
445
445
} else if ((count % 10) == 2) {
446
446
if (strcasecmp(e, "nd"))
448
448
} else if ((count % 10) == 3) {
449
449
if (strcasecmp(e, "rd"))
451
451
} else if (strcasecmp(e, "th")) {
533
533
(*matches_to_go)--;
534
534
return MATCH_EXACT;
535
535
} else if (can_interact(first, who, INTERACT_MATCH) &&
536
(!strcasecmp(Name(first), name) ||
537
(GoodObject(alias_match) && (alias_match == first)))) {
536
(!strcasecmp(Name(first), name) ||
537
(GoodObject(alias_match) && (alias_match == first)))) {
538
538
/* An exact match, but there may be others */
539
539
(*exact_matches_to_go)--;
540
540
(*matches_to_go)--;
542
if (!(*exact_matches_to_go)) {
542
if (!(*exact_matches_to_go)) {
548
if (match_type == MATCH_EXACT)
549
*match = choose_thing(who, type, flags, *match, first);
552
match_type = MATCH_EXACT;
548
if (match_type == MATCH_EXACT)
549
*match = choose_thing(who, type, flags, *match, first);
552
match_type = MATCH_EXACT;
554
554
} else if ((match_type != MATCH_EXACT) && string_match(Name(first), name)
555
&& can_interact(first, who, INTERACT_MATCH)) {
555
&& can_interact(first, who, INTERACT_MATCH)) {
556
556
/* A partial match, and we haven't done an exact match yet */
557
557
(*matches_to_go)--;
559
if (!(*matches_to_go))
559
if (!(*matches_to_go))
561
561
} else if (match_type == MATCH_PARTIAL)
562
*match = choose_thing(who, type, flags, *match, first);
562
*match = choose_thing(who, type, flags, *match, first);
565
565
match_type = MATCH_PARTIAL;
578
578
if (flags & MAT_REMOTES) {
579
579
if (GoodObject(loc))
580
580
return match_exit_internal(who, name, type, flags, Zone(loc),
581
match, exact_matches_to_go, matches_to_go);
581
match, exact_matches_to_go, matches_to_go);
584
584
} else if (flags & MAT_GLOBAL)
585
585
return match_exit_internal(who, name, type, flags, MASTER_ROOM,
586
match, exact_matches_to_go, matches_to_go);
586
match, exact_matches_to_go, matches_to_go);
587
587
return match_exit_internal(who, name, type, flags, loc,
588
match, exact_matches_to_go, matches_to_go);
588
match, exact_matches_to_go, matches_to_go);
591
591
MATCH_FUNC(match_exit_internal)
608
608
(*matches_to_go)--;
609
609
return MATCH_EXACT;
610
610
} else if (check_alias(name, Name(exit_tmp))
611
&& (can_interact(exit_tmp, who, INTERACT_MATCH))) {
611
&& (can_interact(exit_tmp, who, INTERACT_MATCH))) {
612
612
/* Matched an exit alias, but there may be more */
613
613
(*exact_matches_to_go)--;
614
614
(*matches_to_go)--;
616
if (!(*exact_matches_to_go)) {
616
if (!(*exact_matches_to_go)) {
622
if (match_type == MATCH_EXACT)
623
*match = choose_thing(who, type, flags, *match, exit_tmp);
626
match_type = MATCH_EXACT;
622
if (match_type == MATCH_EXACT)
623
*match = choose_thing(who, type, flags, *match, exit_tmp);
626
match_type = MATCH_EXACT;
639
639
if (!GoodObject(who))
641
641
return match_list(who, name, type, flags, Contents(who), match,
642
exact_matches_to_go, matches_to_go);
642
exact_matches_to_go, matches_to_go);
645
645
MATCH_FUNC(match_container)
647
647
if (!GoodObject(who))
649
649
return match_list(who, name, type, flags, Location(who), match,
650
exact_matches_to_go, matches_to_go);
650
exact_matches_to_go, matches_to_go);
653
653
MATCH_FUNC(match_neighbor)
659
659
if (!GoodObject(loc))
661
661
return match_list(who, name, type, flags, Contents(loc), match,
662
exact_matches_to_go, matches_to_go);
662
exact_matches_to_go, matches_to_go);
667
667
choose_thing(const dbref match_who, const int preferred_type, long flags,
668
dbref thing1, dbref thing2)
668
dbref thing1, dbref thing2)
679
679
/* If a type is given, and only one thing is of that type, return it */
680
680
if (preferred_type != NOTYPE) {
681
if (Typeof(thing1) == preferred_type) {
682
if (Typeof(thing2) != preferred_type)
684
} else if (Typeof(thing2) == preferred_type)
681
if (Typeof(thing1) & preferred_type) {
682
if (!(Typeof(thing2) & preferred_type))
684
} else if (Typeof(thing2) & preferred_type)