From 3cdfb6327a713ac4d58576dba6a554481d8e34ca Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 22 Feb 2019 22:25:05 -0800 Subject: [PATCH] Add support for custom keywords For now, 32 characters separated by spaces. Also fixed a SIGSEGV from an empty level title. --- src/d_netcmd.c | 39 ++++++++++++++++++++++++--------------- src/dehacked.c | 5 +++++ src/doomstat.h | 1 + src/lua_maplib.c | 2 ++ src/p_setup.c | 2 ++ 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5ed78165..d81e9d6f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2180,6 +2180,25 @@ void D_PickVote(void) SendNetXCmd(XD_PICKVOTE, &buf, 2); } +/* +Return the number of times a series of keywords, delimited by spaces, matched. +*/ +static int measurekeywords(const char *s, const char *q) +{ + int r = 0; + char *qp; + for (qp = strtok(va("%s", q), " "); + qp; + qp = strtok(0, " ")) + { + if (strcasestr(s, qp)) + { + r++; + } + } + return r; +} + /* Easy macro; declare parm_*id* and define acceptableargc; put in the parameter to match as a string as *name*. Set *argn* to the number of extra arguments @@ -2218,8 +2237,6 @@ static void Command_Map_f(void) char *apromapname = NULL; /* Keyword matching */ - char *query; - char *key; UINT8 *freq; UINT8 freqc; @@ -2319,13 +2336,13 @@ static void Command_Map_f(void) } else { - query = ZZ_Alloc(strlen(mapname)+1); freq = ZZ_Calloc(NUMMAPS * sizeof (UINT8)); for (i = 0, newmapnum = 1; i < NUMMAPS; ++i, ++newmapnum) if (mapheaderinfo[i]) { - realmapname = G_BuildMapTitle(newmapnum); + if (!( realmapname = G_BuildMapTitle(newmapnum) )) + continue; /* Now that we found a perfect match no need to fucking guess. */ if (strnicmp(realmapname, mapname, mapnamelen) == 0) @@ -2345,16 +2362,9 @@ static void Command_Map_f(void) } else/* ...match individual keywords */ { - strcpy(query, mapname); - for (key = strtok(query, " "); - key; - key = strtok(0, " ")) - { - if (strcasestr(realmapname, key)) - { - freq[i]++; - } - } + freq[i] += measurekeywords(realmapname, mapname); + freq[i] += measurekeywords(mapheaderinfo[i]->keyword, + mapname); } } @@ -2385,7 +2395,6 @@ static void Command_Map_f(void) } Z_Free(freq); - Z_Free(query); } } diff --git a/src/dehacked.c b/src/dehacked.c index 11aed24d..7dfedde5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1191,6 +1191,11 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->typeoflevel = tol; } } + else if (fastcmp(word, "KEYWORD")) + { + deh_strlcpy(mapheaderinfo[num-1]->keyword, word2, + sizeof(mapheaderinfo[num-1]->keyword), va("Level header %d: keyword", num)); + } else if (fastcmp(word, "MUSIC")) { if (fastcmp(word2, "NONE")) diff --git a/src/doomstat.h b/src/doomstat.h index 9ae2726d..43ebaf08 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -226,6 +226,7 @@ typedef struct char actnum[3]; ///< SRB2Kart: Now a 2 character long string. UINT16 typeoflevel; ///< Combination of typeoflevel flags. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. + char keyword[33]; ///< Keywords separated by space to search for. 32 characters. char musname[7]; ///< Music track to play. "" for no music. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 0bb9a99d..d7a4fdaf 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1473,6 +1473,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->typeoflevel); else if (fastcmp(field,"nextlevel")) lua_pushinteger(L, header->nextlevel); + else if (fastcmp(field,"keyword")) + lua_pushstring(L, header->keyword); else if (fastcmp(field,"musname")) lua_pushstring(L, header->musname); else if (fastcmp(field,"mustrack")) diff --git a/src/p_setup.c b/src/p_setup.c index 58e13c2e..0187788d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -188,6 +188,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->typeoflevel = 0; DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE); mapheaderinfo[num]->nextlevel = (INT16)(i + 1); + DEH_WriteUndoline("KEYWORD", mapheaderinfo[num]->keyword, UNDO_NONE); + mapheaderinfo[num]->keyword[0] = '\0'; DEH_WriteUndoline("MUSIC", mapheaderinfo[num]->musname, UNDO_NONE); snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); mapheaderinfo[num]->musname[6] = 0;