Tweak updates menu to allow launching package-specific maps (read: quaddicted's maps).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6017 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-08-09 23:06:41 +00:00
parent 182ff709c9
commit 6d72f7487f
5 changed files with 165 additions and 13 deletions

View File

@ -5094,6 +5094,7 @@ typedef struct {
int downloadablessequence;
char titletext[128];
char applymessage[128]; //so we can change its text to give it focus
const void *expandedpackage; //which package we're currently viewing maps for.
qboolean populated;
} dlmenu_t;
@ -5101,6 +5102,7 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
{
package_t *p;
char *n;
struct packagedep_s *dep;
if (y + 8 < 0 || y >= vid.height) //small optimisation.
return;
@ -5113,6 +5115,23 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
if (p->alternative && (p->flags & DPF_HIDDEN))
p = p->alternative;
for (dep = p->deps; dep; dep = dep->next)
if (dep->dtype == DEP_MAP)
break;
if (dep)
{ //map packages are not marked, but cached on demand.
if (p->flags & DPF_PRESENT)
{
if (p->flags & DPF_PURGE)
Draw_FunStringWidth (x, y, "DEL", 48, 2, false); //purge
else
Draw_FunStringWidth (x, y, "^&03 ", 48, 2, false); //cyan
}
else
Draw_FunStringWidth (x, y, "^&06 ", 48, 2, false); //orange
}
else
#ifdef WEBCLIENT
if (p->download)
Draw_FunStringWidth (x, y, va("%i%%", (int)p->download->qdownload.percent), 48, 2, false);
@ -5199,7 +5218,7 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
if ((p->flags & DPF_PURGE) || PM_PurgeOnDisable(p))
Draw_FunStringWidth (x, y, "DEL", 48, 2, false);
else
Draw_FunStringWidth (x, y, "REM", 48, 2, false);
Draw_FunStringWidth (x, y, "DIS", 48, 2, false);
}
}
}
@ -5233,16 +5252,42 @@ static qboolean MD_Key (struct menucustom_s *c, struct emenu_s *m, int key, unsi
qboolean ctrl = keydown[K_LCTRL] || keydown[K_RCTRL];
package_t *p, *p2;
struct packagedep_s *dep, *dep2;
dlmenu_t *info = m->data;
if (c->dint != downloadablessequence)
return false; //probably stale
p = c->dptr;
if (key == 'c' && ctrl)
Sys_SaveClipboard(CBT_CLIPBOARD, p->website);
else if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
else if (key == K_DEL || key == K_KP_DEL || key == K_BACKSPACE)
{
if (!(p->flags & DPF_MARKED))
p->flags |= DPF_PURGE; //purge it when its already not marked (ie: when pressed twice)
PM_UnmarkPackage(p, DPF_MARKED); //deactivate it
}
else if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1 || key == K_GP_A)
{
if (p->alternative && (p->flags & DPF_HIDDEN))
p = p->alternative;
if (info->expandedpackage == p)
{ //close this submenu thing...
info->expandedpackage = NULL;
//remove the following map items.
downloadablessequence++;
return true;
}
for (dep = p->deps; dep; dep = dep->next)
{
if (dep->dtype == DEP_MAP)
{
info->expandedpackage = p;
downloadablessequence++;
//add the map items after (and shift everything)
return true;
}
}
if (p->flags & DPF_ENABLED)
{
switch (p->flags & (DPF_PURGE|DPF_MARKED))
@ -5341,6 +5386,66 @@ static qboolean MD_Key (struct menucustom_s *c, struct emenu_s *m, int key, unsi
return false;
}
static void MD_MapDraw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
{
const package_t *p = c->dptr;
struct packagedep_s *map = c->dptr2;
struct packagedep_s *dep;
float besttime, fulltime, bestkills, bestsecrets;
char *package = NULL;
const char *ext;
if (y + 8 < 0 || y >= vid.height) //small optimisation.
return;
if (c->dint != downloadablessequence)
return; //probably stale
for (dep = p->deps; dep; dep = dep->next)
{
if (dep->dtype == DEP_CACHEFILE)
{
package = va("downloads/%s", dep->name);
break;
}
else if (dep->dtype == DEP_FILE && !package)
package = dep->name;
}
ext = COM_GetFileExtension(map->name, NULL);
if (package && Log_CheckMapCompletion(package, va("maps/%s%s", map->name, *ext?"":".bsp"), &besttime, &fulltime, &bestkills, &bestsecrets))
{
if (besttime != fulltime)
Draw_FunStringU8(CON_WHITEMASK, x+48+8*4, y, va("^m%s^m (%g %g in %.1f secs, fastest in %.1f)", map->name, bestkills,bestsecrets,fulltime, besttime));
else
Draw_FunStringU8(CON_WHITEMASK, x+48+8*4, y, va("^m%s^m (%g %g in %.1f secs)", map->name, bestkills,bestsecrets,fulltime));
}
else
Draw_FunStringU8(CON_WHITEMASK, x+48+8*4, y, map->name);
}
static qboolean MD_MapKey (struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
const package_t *p = c->dptr;
struct packagedep_s *map = c->dptr2;
struct packagedep_s *dep;
if (c->dint != downloadablessequence)
return false; //probably stale
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1 || key == K_GP_A)
for (dep = p->deps; dep; dep = dep->next)
{
if (dep == map)
{
char quoted[MAX_QPATH*2];
Cbuf_AddText(va("map %s\n", COM_QuotedString(va("%s:%s", p->name, map->name), quoted, sizeof(quoted), false)), RESTRICT_LOCAL);
return true;
}
}
return false;
}
#ifdef WEBCLIENT
static void MD_Source_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
{
@ -5512,7 +5617,25 @@ static qboolean MD_RevertUpdates (union menuoption_s *mo,struct emenu_s *m,int k
return false;
}
static int MD_AddItemsToDownloadMenu(emenu_t *m, int y, const char *pathprefix)
static int MD_AddMapItems(emenu_t *m, package_t *p, int y)
{
struct packagedep_s *dep;
menucustom_t *c;
for (dep = p->deps; dep; dep = dep->next)
{
if (dep->dtype != DEP_MAP)
continue;
c = MC_AddCustom(m, 0, y, p, downloadablessequence, NULL);
c->dptr2 = dep;
c->draw = MD_MapDraw;
c->key = MD_MapKey;
c->common.width = 320-16;
c->common.height = 8;
y += 8;
}
return y;
}
static int MD_AddItemsToDownloadMenu(emenu_t *m, int y, const char *pathprefix, void *selpackage)
{
char path[MAX_QPATH];
package_t *p;
@ -5521,6 +5644,7 @@ static int MD_AddItemsToDownloadMenu(emenu_t *m, int y, const char *pathprefix)
menuoption_t *mo;
int prefixlen = strlen(pathprefix);
struct packagedep_s *dep;
dlmenu_t *info = m->data;
//add all packages in this dir
for (p = availablepackages; p; p = p->next)
@ -5594,7 +5718,13 @@ static int MD_AddItemsToDownloadMenu(emenu_t *m, int y, const char *pathprefix)
c->common.height = 8;
y += 8;
if (!m->selecteditem)
if (info->expandedpackage == p)
{
m->selecteditem = (menuoption_t*)c;
y = MD_AddMapItems(m, p, y);
}
if (!m->selecteditem || p == selpackage)
m->selecteditem = (menuoption_t*)c;
}
}
@ -5627,7 +5757,7 @@ static int MD_AddItemsToDownloadMenu(emenu_t *m, int y, const char *pathprefix)
MC_AddBufferedText(m, 48, 320-16, y, path+prefixlen, false, true);
y += 8;
Q_strncatz(path, "/", sizeof(path));
y = MD_AddItemsToDownloadMenu(m, y, path);
y = MD_AddItemsToDownloadMenu(m, y, path, selpackage);
}
}
}
@ -5649,6 +5779,8 @@ static void MD_Download_UpdateStatus(struct emenu_s *m)
menucustom_t *c;
qboolean sources;
#endif
float framefrac = 0;
void *oldpackage = NULL;
if (info->downloadablessequence != downloadablessequence || !info->populated)
{
@ -5656,6 +5788,10 @@ static void MD_Download_UpdateStatus(struct emenu_s *m)
{
menuoption_t *op = m->options;
m->options = op->common.next;
if (op->common.type == mt_frameend)
framefrac = op->frame.frac;
else if (m->selecteditem == op && op->common.type == mt_custom)
oldpackage = op->custom.dptr;
if (op->common.iszone)
Z_Free(op);
}
@ -5784,11 +5920,11 @@ static void MD_Download_UpdateStatus(struct emenu_s *m)
#endif
y+=4; //small gap
MC_AddBufferedText(m, 48, 320-16, y, "Packages", false, true), y += 8;
MD_AddItemsToDownloadMenu(m, y, info->pathprefix);
MD_AddItemsToDownloadMenu(m, y, info->pathprefix, oldpackage);
if (!m->selecteditem)
m->selecteditem = (menuoption_t*)d;
m->cursoritem = (menuoption_t*)MC_AddWhiteText(m, 40, 0, m->selecteditem->common.posy, NULL, false);
MC_AddFrameEnd(m, 48);
MC_AddFrameEnd(m, 48)->frac = framefrac;
}
si = m->mouseitem;

View File

@ -240,6 +240,7 @@ typedef struct {
typedef struct menucustom_s {
menucommon_t common;
void *dptr;
void *dptr2;
int dint;
void (*draw) (int x, int y, struct menucustom_s *, struct emenu_s *);
qboolean (*key) (struct menucustom_s *, struct emenu_s *, int key, unsigned int unicode);

View File

@ -890,8 +890,10 @@ static void Log_MapsRead(void)
}
struct maplog_entry *Log_FindMap(const char *purepackage, const char *mapname)
{
const char *name = va("%s/%s", purepackage, mapname);
char name[MAX_OSPATH];
struct maplog_entry *m;
if (Q_snprintfz(name, sizeof(name), "%s/%s", purepackage, mapname))
return NULL;
Log_MapsRead();
for (m = maplog_enties; m; m = m->next)
{

View File

@ -493,6 +493,14 @@ static void SV_Map_c(int argn, const char *partial, struct xcommandargcompletion
COM_EnumerateFiles(va("maps/%s*.cm", partial), CompleteMapList, ctx);
COM_EnumerateFiles(va("maps/%s*.hmp", partial), CompleteMapList, ctx);
COM_EnumerateFiles(va("maps/%s*/*.bsp", partial), CompleteMapList, ctx);
COM_EnumerateFiles(va("maps/%s*/*.bsp.gz", partial), CompleteMapListExt, ctx);
COM_EnumerateFiles(va("maps/%s*/*.bsp.xz", partial), CompleteMapListExt, ctx);
COM_EnumerateFiles(va("maps/%s*/*.map", partial), CompleteMapListExt, ctx);
COM_EnumerateFiles(va("maps/%s*/*.map.gz", partial), CompleteMapListExt, ctx);
COM_EnumerateFiles(va("maps/%s*/*.cm", partial), CompleteMapList, ctx);
COM_EnumerateFiles(va("maps/%s*/*.hmp", partial), CompleteMapList, ctx);
#ifdef PACKAGEMANAGER
PM_EnumerateMaps(partial, ctx);
#endif
@ -552,7 +560,7 @@ void SV_Map_f (void)
char level[MAX_QPATH];
char spot[MAX_QPATH];
char expanded[MAX_QPATH+64];
char *nextserver;
char *nextserver = NULL;
qboolean preserveplayers= false;
qboolean isrestart = false; //don't hurt settings
#ifdef SAVEDGAMES
@ -570,8 +578,6 @@ void SV_Map_f (void)
int i;
char *startspot;
nextserver = 0;
#ifndef SERVERONLY
if (!Renderer_Started() && !isDedicated)
{
@ -632,7 +638,13 @@ void SV_Map_f (void)
if (sep)
{
*sep++ = 0;
PM_LoadMap(mangled, sep);
if (Cmd_FromGamecode())
{
Con_TPrintf ("switching packages via %s command is blocked from gamecode, just in case.\n", Cmd_Argv(0));
sv.mapchangelocked = false;
}
else
PM_LoadMap(mangled, sep);
return;
}
}

View File

@ -618,7 +618,7 @@ void SV_DropClient (client_t *drop)
}
*drop->uploadfn = 0;
#ifndef SERVERONLY
#ifdef HAVE_CLIENT
if (drop->netchan.remote_address.type == NA_LOOPBACK)
{
if (drop->protocol != SCP_BAD)
@ -627,6 +627,7 @@ void SV_DropClient (client_t *drop)
#pragma warningmsg("This means that we may not see the reason we kicked ourselves.")
#endif
drop->state = cs_free; //don't do zombie stuff
cls.state = ca_disconnected;
CL_BeginServerReconnect();
}
else