mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2025-01-16 22:51:07 +00:00
Extend map name text matching code into a function
This commit is contained in:
parent
3cdfb6327a
commit
7e389f4062
3 changed files with 206 additions and 84 deletions
|
@ -2180,25 +2180,6 @@ 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
|
||||
|
@ -2229,16 +2210,10 @@ static void Command_Map_f(void)
|
|||
boolean usemapcode = false;
|
||||
|
||||
INT32 newmapnum;
|
||||
INT32 apromapnum = 0;
|
||||
|
||||
const char *mapname;
|
||||
size_t mapnamelen;
|
||||
char *realmapname = NULL;
|
||||
char *apromapname = NULL;
|
||||
|
||||
/* Keyword matching */
|
||||
UINT8 *freq;
|
||||
UINT8 freqc;
|
||||
|
||||
INT32 newgametype = gametype;
|
||||
|
||||
|
@ -2336,65 +2311,7 @@ static void Command_Map_f(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
freq = ZZ_Calloc(NUMMAPS * sizeof (UINT8));
|
||||
|
||||
for (i = 0, newmapnum = 1; i < NUMMAPS; ++i, ++newmapnum)
|
||||
if (mapheaderinfo[i])
|
||||
{
|
||||
if (!( realmapname = G_BuildMapTitle(newmapnum) ))
|
||||
continue;
|
||||
|
||||
/* Now that we found a perfect match no need to fucking guess. */
|
||||
if (strnicmp(realmapname, mapname, mapnamelen) == 0)
|
||||
{
|
||||
Z_Free(apromapname);
|
||||
break;
|
||||
}
|
||||
|
||||
if (apromapnum == 0)
|
||||
{
|
||||
/* LEVEL 1--match keywords verbatim */
|
||||
if (strcasestr(realmapname, mapname))
|
||||
{
|
||||
apromapnum = newmapnum;
|
||||
apromapname = realmapname;
|
||||
realmapname = 0;
|
||||
}
|
||||
else/* ...match individual keywords */
|
||||
{
|
||||
freq[i] += measurekeywords(realmapname, mapname);
|
||||
freq[i] += measurekeywords(mapheaderinfo[i]->keyword,
|
||||
mapname);
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(realmapname);/* leftover old name */
|
||||
}
|
||||
|
||||
if (newmapnum == NUMMAPS+1)/* no perfect match--try a substring */
|
||||
{
|
||||
newmapnum = apromapnum;
|
||||
realmapname = apromapname;
|
||||
}
|
||||
|
||||
if (newmapnum == 0)/* calculate most queries met! */
|
||||
{
|
||||
freqc = 0;
|
||||
for (i = 0; i < NUMMAPS; ++i)
|
||||
{
|
||||
if (freq[i] > freqc)
|
||||
{
|
||||
freqc = freq[i];
|
||||
newmapnum = i + 1;
|
||||
}
|
||||
}
|
||||
if (newmapnum)
|
||||
{
|
||||
realmapname = G_BuildMapTitle(newmapnum);
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(freq);
|
||||
newmapnum = G_FindMap(mapname, &realmapname, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
184
src/g_game.c
184
src/g_game.c
|
@ -4486,6 +4486,190 @@ char *G_BuildMapTitle(INT32 mapnum)
|
|||
return title;
|
||||
}
|
||||
|
||||
static void measurekeywords(mapsearchfreq_t *fr,
|
||||
struct searchdim **dimp, UINT8 *cuntp,
|
||||
const char *s, const char *q, boolean wanttable)
|
||||
{
|
||||
char *qp;
|
||||
char *sp;
|
||||
if (wanttable)
|
||||
(*dimp) = Z_Realloc((*dimp), 255 * sizeof (struct searchdim),
|
||||
PU_STATIC, NULL);
|
||||
for (qp = strtok(va("%s", q), " ");
|
||||
qp && fr->total < 255;
|
||||
qp = strtok(0, " "))
|
||||
{
|
||||
if (( sp = strcasestr(s, qp) ))
|
||||
{
|
||||
if (wanttable)
|
||||
{
|
||||
(*dimp)[(*cuntp)].pos = sp - s;
|
||||
(*dimp)[(*cuntp)].siz = strlen(qp);
|
||||
}
|
||||
(*cuntp)++;
|
||||
fr->total++;
|
||||
}
|
||||
}
|
||||
if (wanttable)
|
||||
(*dimp) = Z_Realloc((*dimp), (*cuntp) * sizeof (struct searchdim),
|
||||
PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
void writesimplefreq(mapsearchfreq_t *fr, INT32 *frc,
|
||||
INT32 mapnum, UINT8 pos, UINT8 siz)
|
||||
{
|
||||
fr[(*frc)].mapnum = mapnum;
|
||||
fr[(*frc)].matchd = ZZ_Alloc(sizeof (struct searchdim));
|
||||
fr[(*frc)].matchd[0].pos = pos;
|
||||
fr[(*frc)].matchd[0].siz = siz;
|
||||
fr[(*frc)].matchc = 1;
|
||||
fr[(*frc)].total = 1;
|
||||
(*frc)++;
|
||||
}
|
||||
|
||||
INT32 G_FindMap(const char *mapname, char **foundmapnamep,
|
||||
mapsearchfreq_t **freqp, INT32 *freqcp)
|
||||
{
|
||||
INT32 newmapnum = 0;
|
||||
INT32 mapnum;
|
||||
INT32 apromapnum = 0;
|
||||
|
||||
size_t mapnamelen;
|
||||
char *realmapname = NULL;
|
||||
char *newmapname = NULL;
|
||||
char *apromapname = NULL;
|
||||
char *aprop = NULL;
|
||||
|
||||
mapsearchfreq_t *freq;
|
||||
boolean wanttable;
|
||||
INT32 freqc;
|
||||
UINT8 frequ;
|
||||
|
||||
INT32 i;
|
||||
|
||||
mapnamelen = strlen(mapname);
|
||||
|
||||
/* Count available maps; how ugly. */
|
||||
for (i = 0, freqc = 0; i < NUMMAPS; ++i)
|
||||
{
|
||||
if (mapheaderinfo[i])
|
||||
freqc++;
|
||||
}
|
||||
|
||||
freq = ZZ_Calloc(freqc * sizeof (mapsearchfreq_t));
|
||||
|
||||
wanttable = !!( freqp );
|
||||
|
||||
freqc = 0;
|
||||
for (i = 0, mapnum = 1; i < NUMMAPS; ++i, ++mapnum)
|
||||
if (mapheaderinfo[i])
|
||||
{
|
||||
if (!( realmapname = G_BuildMapTitle(mapnum) ))
|
||||
continue;
|
||||
|
||||
aprop = realmapname;
|
||||
|
||||
/* Now that we found a perfect match no need to fucking guess. */
|
||||
if (strnicmp(realmapname, mapname, mapnamelen) == 0)
|
||||
{
|
||||
if (wanttable)
|
||||
{
|
||||
writesimplefreq(freq, &freqc, mapnum, 0, mapnamelen);
|
||||
}
|
||||
if (newmapnum == 0)
|
||||
{
|
||||
newmapnum = mapnum;
|
||||
newmapname = realmapname;
|
||||
realmapname = 0;
|
||||
Z_Free(apromapname);
|
||||
if (!wanttable)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (apromapnum == 0 || wanttable)
|
||||
{
|
||||
/* LEVEL 1--match keywords verbatim */
|
||||
if (( aprop = strcasestr(realmapname, mapname) ))
|
||||
{
|
||||
if (wanttable)
|
||||
{
|
||||
writesimplefreq(freq, &freqc,
|
||||
mapnum, aprop - realmapname, mapnamelen);
|
||||
}
|
||||
if (apromapnum == 0)
|
||||
{
|
||||
apromapnum = mapnum;
|
||||
apromapname = realmapname;
|
||||
realmapname = 0;
|
||||
}
|
||||
}
|
||||
else/* ...match individual keywords */
|
||||
{
|
||||
freq[freqc].mapnum = mapnum;
|
||||
measurekeywords(&freq[freqc],
|
||||
&freq[freqc].matchd, &freq[freqc].matchc,
|
||||
realmapname, mapname, wanttable);
|
||||
measurekeywords(&freq[freqc],
|
||||
&freq[freqc].keywhd, &freq[freqc].keywhc,
|
||||
mapheaderinfo[i]->keyword, mapname, wanttable);
|
||||
if (freq[freqc].total)
|
||||
freqc++;
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(realmapname);/* leftover old name */
|
||||
}
|
||||
|
||||
if (newmapnum == 0)/* no perfect match--try a substring */
|
||||
{
|
||||
newmapnum = apromapnum;
|
||||
newmapname = apromapname;
|
||||
}
|
||||
|
||||
if (newmapnum == 0)/* calculate most queries met! */
|
||||
{
|
||||
frequ = 0;
|
||||
for (i = 0; i < freqc; ++i)
|
||||
{
|
||||
if (freq[i].total > frequ)
|
||||
{
|
||||
frequ = freq[i].total;
|
||||
newmapnum = freq[i].mapnum;
|
||||
}
|
||||
}
|
||||
if (newmapnum)
|
||||
{
|
||||
newmapname = G_BuildMapTitle(newmapnum);
|
||||
}
|
||||
}
|
||||
|
||||
if (freqp)
|
||||
(*freqp) = freq;
|
||||
else
|
||||
Z_Free(freq);
|
||||
|
||||
if (freqcp)
|
||||
(*freqcp) = freqc;
|
||||
|
||||
if (foundmapnamep)
|
||||
(*foundmapnamep) = newmapname;
|
||||
else
|
||||
Z_Free(newmapname);
|
||||
|
||||
return newmapnum;
|
||||
}
|
||||
|
||||
void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < freqc; ++i)
|
||||
{
|
||||
Z_Free(freq[i].matchd);
|
||||
}
|
||||
Z_Free(freq);
|
||||
}
|
||||
|
||||
//
|
||||
// DEMO RECORDING
|
||||
//
|
||||
|
|
21
src/g_game.h
21
src/g_game.h
|
@ -115,6 +115,27 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer,
|
|||
boolean skipprecutscene);
|
||||
char *G_BuildMapTitle(INT32 mapnum);
|
||||
|
||||
struct searchdim
|
||||
{
|
||||
UINT8 pos;
|
||||
UINT8 siz;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT16 mapnum;
|
||||
UINT8 matchc;
|
||||
struct searchdim *matchd;/* offset that a pattern was matched */
|
||||
UINT8 keywhc;
|
||||
struct searchdim *keywhd;/* ...in KEYWORD */
|
||||
UINT8 total;/* total hits */
|
||||
}
|
||||
mapsearchfreq_t;
|
||||
|
||||
INT32 G_FindMap(const char *query, char **foundmapnamep,
|
||||
mapsearchfreq_t **freqp, INT32 *freqc);
|
||||
void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc);
|
||||
|
||||
// XMOD spawning
|
||||
mapthing_t *G_FindCTFStart(INT32 playernum);
|
||||
mapthing_t *G_FindMatchStart(INT32 playernum);
|
||||
|
|
Loading…
Reference in a new issue