diff --git a/lib/world/mob/1.mob b/lib/world/mob/1.mob index 66a05f4..3bd895f 100644 --- a/lib/world/mob/1.mob +++ b/lib/world/mob/1.mob @@ -1,5 +1,6 @@ #100 -tall burly human soldier guard~ +John~ +soldier tall burly human guard~ the tall, burly human soldier~ A tall, burly human soldier stands here at the gate. ~ @@ -30,6 +31,7 @@ L 15 117 1 L 16 117 1 L 17 127 1 #101 +Sally~ slim lanky human soldier guard~ a slim, lanky human soldier~ A slim, lanky human soldier stands here eyeing passerbys. @@ -60,6 +62,7 @@ L 6 110 1 L 5 131 1 L 3 118 1 #102 +Baldy~ barkeep stocky bald~ a stocky, bald barkeep~ A stocky, bald barkeep stands behind the bar here. @@ -77,6 +80,7 @@ E L 14 113 1 L 9 112 1 #103 +Lanky~ woman lanky scarred~ the lanky, scarred woman~ The lanky, scarred woman is leaning against a wall here. diff --git a/src/db.c b/src/db.c index 7844074..5286d80 100644 --- a/src/db.c +++ b/src/db.c @@ -1754,7 +1754,7 @@ void parse_mobile(FILE *mob_f, int nr) static int i = 0; int j, t[10], retval; char line[READ_SIZE], *tmpptr, letter; - char f1[128], f2[128], f3[128], f4[128], f5[128], f6[128], f7[128], f8[128], buf2[128]; + char f1[128], f2[128], f3[128], f4[128], f5[128], f6[128], f7[128], f8[128], buf1[128], buf2[128]; mob_index[i].vnum = nr; mob_index[i].number = 0; @@ -1769,7 +1769,8 @@ void parse_mobile(FILE *mob_f, int nr) sprintf(buf2, "mob vnum %d", nr); /* sprintf: OK (for 'buf2 >= 19') */ /* String data */ - mob_proto[i].player.name = fread_string(mob_f, buf2); + mob_proto[i].player.name = fread_string(mob_f, buf1); + mob_proto[i].player.keywords = fread_string(mob_f, buf2); tmpptr = mob_proto[i].player.short_descr = fread_string(mob_f, buf2); if (tmpptr && *tmpptr) if (!str_cmp(fname(tmpptr), "a") || !str_cmp(fname(tmpptr), "an") || diff --git a/src/genmob.c b/src/genmob.c index 1b500fc..b986b68 100644 --- a/src/genmob.c +++ b/src/genmob.c @@ -401,9 +401,11 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd) "%s%c\n" "%s%c\n" "%s%c\n" + "%s%c\n" "%s%c\n", mvnum, - GET_ALIAS(mob), STRING_TERMINATOR, + GET_NAME(mob), STRING_TERMINATOR, + GET_KEYWORDS(mob), STRING_TERMINATOR, GET_SDESC(mob), STRING_TERMINATOR, ldesc, STRING_TERMINATOR, ddesc, STRING_TERMINATOR); @@ -474,10 +476,11 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd) void check_mobile_strings(struct char_data *mob) { mob_vnum mvnum = mob_index[mob->nr].vnum; + check_mobile_string(mvnum, &GET_NAME(mob), "npc name"); + check_mobile_string(mvnum, &GET_KEYWORDS(mob), "alias list"); + check_mobile_string(mvnum, &GET_SDESC(mob), "short description"); check_mobile_string(mvnum, &GET_LDESC(mob), "long description"); check_mobile_string(mvnum, &GET_DDESC(mob), "detailed description"); - check_mobile_string(mvnum, &GET_ALIAS(mob), "alias list"); - check_mobile_string(mvnum, &GET_SDESC(mob), "short description"); } void check_mobile_string(mob_vnum i, char **string, const char *desc) diff --git a/src/genmob.h b/src/genmob.h index db747d0..971fbaa 100644 --- a/src/genmob.h +++ b/src/genmob.h @@ -31,7 +31,6 @@ int write_mobile_mobprog(mob_vnum mvnum, struct char_data *mob, FILE *fd); #endif /* Handy macros. */ -#define GET_ALIAS(mob) ((mob)->player.name) #define GET_SDESC(mob) ((mob)->player.short_descr) #define GET_LDESC(mob) ((mob)->player.long_descr) #define GET_DDESC(mob) ((mob)->player.description) diff --git a/src/genolc.c b/src/genolc.c index 7b24ffa..66a4249 100644 --- a/src/genolc.c +++ b/src/genolc.c @@ -606,7 +606,7 @@ static int export_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd) "%s%c\n" "%s%c\n", mvnum%100, - GET_ALIAS(mob), STRING_TERMINATOR, + GET_KEYWORDS(mob), STRING_TERMINATOR, GET_SDESC(mob), STRING_TERMINATOR, ldesc, STRING_TERMINATOR, ddesc, STRING_TERMINATOR diff --git a/src/handler.c b/src/handler.c index 401c5cd..234bd88 100644 --- a/src/handler.c +++ b/src/handler.c @@ -1084,11 +1084,27 @@ struct char_data *get_char_room_vis(struct char_data *ch, char *name, int *numbe if (*number == 0) return (get_player_vis(ch, name, NULL, FIND_CHAR_ROOM)); - for (i = world[IN_ROOM(ch)].people; i && *number; i = i->next_in_room) - if (isname(name, i->player.name)) - if (CAN_SEE(ch, i)) - if (--(*number) == 0) - return (i); + for (i = world[IN_ROOM(ch)].people; i && *number; i = i->next_in_room) { + const char *namelist = NULL; + bool match = FALSE; + + if (IS_NPC(i)) { + /* NPCs match either keywords or their name */ + const char *keywords = GET_KEYWORDS(i); + const char *proper = GET_NAME(i); + if ((keywords && isname(name, keywords)) || (proper && isname(name, proper))) + match = TRUE; + } else { + /* PCs match only their name */ + namelist = GET_NAME(i); + if (namelist && isname(name, namelist)) + match = TRUE; + } + + if (match && CAN_SEE(ch, i)) + if (--(*number) == 0) + return (i); + } return (NULL); } @@ -1103,16 +1119,32 @@ struct char_data *get_char_world_vis(struct char_data *ch, char *name, int *numb num = get_number(&name); } + /* First, try to find character in the same room */ if ((i = get_char_room_vis(ch, name, number)) != NULL) return (i); + /* 0. means PC with name */ if (*number == 0) return get_player_vis(ch, name, NULL, 0); for (i = character_list; i && *number; i = i->next) { if (IN_ROOM(ch) == IN_ROOM(i)) continue; - if (!isname(name, i->player.name)) + + bool match = FALSE; + + if (IS_NPC(i)) { + const char *keywords = GET_KEYWORDS(i); + const char *proper = GET_NAME(i); + if ((keywords && isname(name, keywords)) || (proper && isname(name, proper))) + match = TRUE; + } else { + const char *namelist = GET_NAME(i); + if (namelist && isname(name, namelist)) + match = TRUE; + } + + if (!match) continue; if (!CAN_SEE(ch, i)) continue; @@ -1121,6 +1153,7 @@ struct char_data *get_char_world_vis(struct char_data *ch, char *name, int *numb return (i); } + return (NULL); } diff --git a/src/medit.c b/src/medit.c index 511b740..f8537b9 100644 --- a/src/medit.c +++ b/src/medit.c @@ -186,9 +186,10 @@ static void medit_setup_new(struct descriptor_data *d) GET_MOB_RNUM(mob) = NOBODY; /* Set up some default strings. */ - GET_ALIAS(mob) = strdup("mob unfinished"); - GET_SDESC(mob) = strdup("the unfinished mob"); - GET_LDESC(mob) = strdup("An unfinished mob stands here.\r\n"); + GET_NAME(mob) = strdup("NPC"); + GET_KEYWORDS(mob) = strdup("unfinished npc"); + GET_SDESC(mob) = strdup("the unfinished npc"); + GET_LDESC(mob) = strdup("An unfinished npc stands here.\r\n"); GET_DDESC(mob) = strdup("It looks unfinished.\r\n"); SCRIPT(mob) = NULL; mob->proto_script = OLC_SCRIPT(d) = NULL; @@ -417,15 +418,18 @@ static void medit_disp_menu(struct descriptor_data *d) clear_screen(d); write_to_output(d, - "-- Mob Number: [%s%d%s]\r\n" - "%s1%s) Sex: %s%-7.7s%s %s2%s) Keywords: %s%s\r\n" - "%s3%s) S-Desc: %s%s\r\n" - "%s4%s) L-Desc:-\r\n%s%s\r\n" - "%s5%s) D-Desc:-\r\n%s%s\r\n", + "-- Mob Number: [%s%d%s]\r\n" + "%s1%s) Name: %s%s\r\n" + "%s2%s) Keywords: %s%s\r\n" + "%s3%s) Sex: %s%-7.7s%s\r\n" + "%s4%s) S-Desc: %s%s\r\n" + "%s5%s) L-Desc:-\r\n%s%s\r\n" + "%s6%s) D-Desc:-\r\n%s%s\r\n", cyn, OLC_NUM(d), nrm, + grn, nrm, yel, GET_NAME(mob), + grn, nrm, yel, GET_KEYWORDS(mob), grn, nrm, yel, genders[(int)GET_SEX(mob)], nrm, - grn, nrm, yel, GET_ALIAS(mob), grn, nrm, yel, GET_SDESC(mob), grn, nrm, yel, GET_LDESC(mob), grn, nrm, yel, GET_DDESC(mob) @@ -434,15 +438,15 @@ static void medit_disp_menu(struct descriptor_data *d) sprintbitarray(MOB_FLAGS(mob), action_bits, AF_ARRAY_MAX, flags); sprintbitarray(AFF_FLAGS(mob), affected_bits, AF_ARRAY_MAX, flag2); write_to_output(d, - "%s6%s) Position : %s%s\r\n" - "%s7%s) Default : %s%s\r\n" - "%s8%s) Attack : %s%s\r\n" - "%s9%s) Stats Menu...\r\n" - "%s0%s) Skills Menu...\r\n" + "%s7%s) Position : %s%s\r\n" + "%s8%s) Default : %s%s\r\n" + "%s9%s) Attack : %s%s\r\n" + "%s0%s) Stats Menu...\r\n" + "%s-%s) Skills Menu...\r\n" "%sA%s) NPC Flags : %s%s\r\n" "%sB%s) AFF Flags : %s%s\r\n" - "%sS%s) Script : %s%s\r\n" - "%sW%s) Copy mob\r\n" + "%sS%s) Script : %s%s\r\n" + "%sW%s) Copy mob\r\n" "%sX%s) Delete mob\r\n" "%sQ%s) Quit\r\n" "Enter choice : ", @@ -622,22 +626,26 @@ void medit_parse(struct descriptor_data *d, char *arg) cleanup_olc(d, CLEANUP_ALL); return; case '1': - OLC_MODE(d) = MEDIT_SEX; - medit_disp_sex(d); - return; + OLC_MODE(d) = MEDIT_NAME; + i--; + break; case '2': OLC_MODE(d) = MEDIT_KEYWORD; i--; break; case '3': + OLC_MODE(d) = MEDIT_SEX; + medit_disp_sex(d); + return; + case '4': OLC_MODE(d) = MEDIT_S_DESC; i--; break; - case '4': + case '5': OLC_MODE(d) = MEDIT_L_DESC; i--; break; - case '5': + case '6': OLC_MODE(d) = MEDIT_D_DESC; send_editor_help(d); write_to_output(d, "Enter mob description:\r\n\r\n"); @@ -648,23 +656,23 @@ void medit_parse(struct descriptor_data *d, char *arg) string_write(d, &OLC_MOB(d)->player.description, MAX_MOB_DESC, 0, oldtext); OLC_VAL(d) = 1; return; - case '6': + case '7': OLC_MODE(d) = MEDIT_POS; medit_disp_positions(d); return; - case '7': + case '8': OLC_MODE(d) = MEDIT_DEFAULT_POS; medit_disp_positions(d); return; - case '8': + case '9': OLC_MODE(d) = MEDIT_ATTACK; medit_disp_attack_types(d); return; - case '9': + case '0': OLC_MODE(d) = MEDIT_STATS_MENU; medit_disp_stats_menu(d); return; - case '0': /* Enter skill sub-menu */ + case '-': /* Enter skill sub-menu */ OLC_MODE(d) = MEDIT_SKILL_MENU; medit_disp_skill_menu(d); return; @@ -943,11 +951,18 @@ void medit_parse(struct descriptor_data *d, char *arg) if (dg_script_edit_parse(d, arg)) return; break; + case MEDIT_NAME: + smash_tilde(arg); + if (GET_NAME(OLC_MOB(d))) + free(GET_NAME(OLC_MOB(d))); + GET_NAME(OLC_MOB(d)) = str_udup(arg); + break; + case MEDIT_KEYWORD: smash_tilde(arg); - if (GET_ALIAS(OLC_MOB(d))) - free(GET_ALIAS(OLC_MOB(d))); - GET_ALIAS(OLC_MOB(d)) = str_udup(arg); + if (GET_KEYWORDS(OLC_MOB(d))) + free(GET_KEYWORDS(OLC_MOB(d))); + GET_KEYWORDS(OLC_MOB(d)) = str_udup(arg); break; case MEDIT_S_DESC: @@ -971,9 +986,6 @@ void medit_parse(struct descriptor_data *d, char *arg) break; case MEDIT_D_DESC: - /* - * We should never get here. - */ cleanup_olc(d, CLEANUP_ALL); mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: medit_parse(): Reached D_DESC case!"); write_to_output(d, "Oops...\r\n"); diff --git a/src/oasis.h b/src/oasis.h index 143c431..c7a21fd 100644 --- a/src/oasis.h +++ b/src/oasis.h @@ -253,42 +253,43 @@ extern const char *nrm, *grn, *cyn, *yel; /* Submodes of MEDIT connectedness. */ #define MEDIT_MAIN_MENU 0 -#define MEDIT_KEYWORD 1 -#define MEDIT_S_DESC 2 -#define MEDIT_L_DESC 3 -#define MEDIT_D_DESC 4 -#define MEDIT_NPC_FLAGS 5 -#define MEDIT_AFF_FLAGS 6 -#define MEDIT_CONFIRM_SAVESTRING 7 -#define MEDIT_STATS_MENU 8 -#define MEDIT_SKILL_MENU 9 -#define MEDIT_SKILL_EDIT 10 +#define MEDIT_NAME 1 +#define MEDIT_KEYWORD 2 +#define MEDIT_S_DESC 3 +#define MEDIT_L_DESC 4 +#define MEDIT_D_DESC 5 +#define MEDIT_NPC_FLAGS 6 +#define MEDIT_AFF_FLAGS 7 +#define MEDIT_CONFIRM_SAVESTRING 8 +#define MEDIT_STATS_MENU 9 +#define MEDIT_SKILL_MENU 10 +#define MEDIT_SKILL_EDIT 11 /* Numerical responses. */ -#define MEDIT_NUMERICAL_RESPONSE 11 -#define MEDIT_SEX 12 -#define MEDIT_NUM_HP_DICE 13 -#define MEDIT_SIZE_HP_DICE 14 -#define MEDIT_ADD_HP 15 -#define MEDIT_POS 16 -#define MEDIT_DEFAULT_POS 17 -#define MEDIT_ATTACK 18 -#define MEDIT_LEVEL 19 -#define MEDIT_ALIGNMENT 20 -#define MEDIT_DELETE 21 -#define MEDIT_COPY 22 -#define MEDIT_STR 23 -#define MEDIT_INT 24 -#define MEDIT_WIS 25 -#define MEDIT_DEX 26 -#define MEDIT_CON 27 -#define MEDIT_CHA 28 -#define MEDIT_SAVE_STR 29 -#define MEDIT_SAVE_DEX 30 -#define MEDIT_SAVE_CON 31 -#define MEDIT_SAVE_INT 32 -#define MEDIT_SAVE_WIS 33 -#define MEDIT_SAVE_CHA 34 +#define MEDIT_NUMERICAL_RESPONSE 12 +#define MEDIT_SEX 13 +#define MEDIT_NUM_HP_DICE 14 +#define MEDIT_SIZE_HP_DICE 15 +#define MEDIT_ADD_HP 16 +#define MEDIT_POS 17 +#define MEDIT_DEFAULT_POS 18 +#define MEDIT_ATTACK 19 +#define MEDIT_LEVEL 20 +#define MEDIT_ALIGNMENT 21 +#define MEDIT_DELETE 22 +#define MEDIT_COPY 23 +#define MEDIT_STR 24 +#define MEDIT_INT 25 +#define MEDIT_WIS 26 +#define MEDIT_DEX 27 +#define MEDIT_CON 28 +#define MEDIT_CHA 29 +#define MEDIT_SAVE_STR 30 +#define MEDIT_SAVE_DEX 31 +#define MEDIT_SAVE_CON 32 +#define MEDIT_SAVE_INT 33 +#define MEDIT_SAVE_WIS 34 +#define MEDIT_SAVE_CHA 35 /* Submodes of SEDIT connectedness. */ #define SEDIT_MAIN_MENU 0 diff --git a/src/structs.h b/src/structs.h index b60fa86..c18882f 100644 --- a/src/structs.h +++ b/src/structs.h @@ -876,7 +876,8 @@ struct pclean_criteria_data struct char_player_data { char passwd[MAX_PWD_LENGTH+1]; /**< PC's password */ - char *name; /**< PC / NPC name */ + char *name; /**< Display name (PC/NPC personal name) */ + char *keywords; /**< Parsing keywords (for NPCs and parsing lookup) */ char *short_descr; /**< NPC 'actions' */ char *long_descr; /**< PC / NPC look description */ char *description; /**< NPC Extra descriptions */ @@ -889,6 +890,7 @@ struct char_player_data ubyte height; /**< PC / NPC height */ }; + /** Character abilities. Different instances of this structure are used for * both inherent and current ability scores (like when poison affects the * player strength). */ diff --git a/src/utils.h b/src/utils.h index bfef996..056ed01 100644 --- a/src/utils.h +++ b/src/utils.h @@ -506,11 +506,28 @@ do \ /** How old is PC/NPC, at last recorded time? */ #define GET_AGE(ch) (age(ch)->year) -/** Name of PC. */ -#define GET_PC_NAME(ch) ((ch)->player.name) -/** Name of PC or short_descr of NPC. */ -#define GET_NAME(ch) (IS_NPC(ch) ? \ - (ch)->player.short_descr : GET_PC_NAME(ch)) +/** Proper name for PCs and NPCs. */ +#define GET_NAME(ch) ((ch)->player.name) + +/** Player-only convenience. */ +#define GET_PC_NAME(ch) ((ch)->player.name) + +/** Parsing keywords for matching. */ +#define GET_KEYWORDS(ch) ((ch)->player.keywords) + +/** Appearance-based description for displays (e.g. short look text). */ +#define GET_SHORT_DESC(ch) ((ch)->player.short_descr) + +/** Safe name for room messages. */ +#define GET_DISPLAY_NAME(ch) (GET_NAME(ch) && *GET_NAME(ch) ? GET_NAME(ch) : "someone") + +/* + * Wrapper around isname() that checks GET_KEYWORDS for NPCs and GET_NAME for PCs. + * Use this instead of calling isname() directly when matching character names. + */ +#define IS_NAME_MATCH(str, ch) \ + (isname((str), IS_NPC(ch) ? GET_KEYWORDS(ch) : GET_NAME(ch))) + /** Title of PC */ #define GET_TITLE(ch) ((ch)->player.title) /** Level of PC or NPC. */ @@ -867,8 +884,15 @@ do \ (CAN_WEAR((obj), ITEM_WEAR_TAKE) && CAN_CARRY_OBJ((ch),(obj)) && \ CAN_SEE_OBJ((ch),(obj))) -/** If vict can see ch, return ch name, else return "someone". */ -#define PERS(ch, vict) (CAN_SEE(vict, ch) ? GET_NAME(ch) : (GET_LEVEL(ch) > LVL_IMMORT ? "an immortal" : "someone")) +/** + * If vict can see ch, return visible name. + * For NPCs: use short_descr (e.g. "a burly guard"). + * For PCs: use proper name. + */ +#define PERS(ch, vict) \ + (CAN_SEE((vict), (ch)) ? \ + (IS_NPC(ch) ? GET_SHORT_DESC(ch) : GET_NAME(ch)) : \ + ((GET_LEVEL(ch) > LVL_IMMORT) ? "an immortal" : "someone")) /** If vict can see obj, return obj short description, else return * "something". */