fteqw/engine/client/m_script.c
Spoike a97007ae5a dpp7: Treat 'dropped' c2s packets as choked when using dpp7 protocols. This is because the protocol provides no way to disambiguate, and I don't like false reports of packetloss (only reliables loss can be detected, and that's not frequent enough to be meaningful). Pings can still be determined with dpp7, for those few packets which are acked.
package manager: reworked to enable/disable plugins when downloaded, which can also be present-but-disabled.
package manager: display a confirmation prompt before applying changes. do not allow other changes to be made while applying. prompt may be skipped with 'pkg apply' in dedicated servers.
sv: downloads are no longer forced to lower case.
sv: added sv_demoAutoCompress cvar. set to 1 to directly record to *.mvd.gz
cl: properly support directly playing .mvd.gz files
menus: reworked to separate mouse and keyboard focus. mouse focus becomes keyboard focus only on mouse clicks. tooltips follow mouse cursors.
menus: cleaned up menu heirachy a little. now simpler.
server browser: changed 'hide *' filters to 'show *' instead. I felt it was more logical.
deluxmapping: changed to disabled, load, generate, like r_loadlit is.
render targets api now supports negative formats to mean nearest filtering, where filtering is part of texture state.
drawrotpic fixed, now batches and interacts with drawpic correctly.
drawline fixed, no interacts with draw* correctly, but still does not batch.
fixed saving games.
provide proper userinfo to nq clients, where supported.
qcc: catch string table overflows safely, giving errors instead of crashes. switch to 32bit statements if some over-sized function requires it.
qtv: some bigcoords support tweaks

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5073 fc73d0e0-1445-4013-8a0c-d673dee63da5
2017-03-21 05:27:07 +00:00

455 lines
9.7 KiB
C

//read menu.h
#include "quakedef.h"
#include "shader.h"
#ifndef NOBUILTINMENUS
int selectitem;
menu_t *menu_script;
void M_Script_Option (menu_t *menu, char *optionvalue, qboolean isexplicit)
{
menuoption_t *mo;
char *scriptname = menu->data;
char buf[8192];
//FIXME: not sure about these, as the user typically can't see what they'll do.
int expandlevel = RESTRICT_SERVER;
int execlevel = RESTRICT_LOCAL;
Cbuf_AddText("wait\n", execlevel);
if (!*scriptname)
{
if (isexplicit)
Cbuf_AddText(va("%s\n", optionvalue), execlevel);
return;
}
//update the option
Cbuf_AddText(va("set option %s\n", COM_QuotedString(optionvalue, buf, sizeof(buf), false)), execlevel);
//expand private arguments
for (mo = menu->options, *buf = 0; mo; mo = mo->common.next)
{
if (mo->common.type == mt_edit)
{
if (strlen(buf) + strlen(mo->edit.text) + 2 >= sizeof(buf))
break;
memmove(buf+strlen(mo->edit.text)+1, buf, strlen(buf)+1);
memcpy(buf, mo->edit.text, strlen(mo->edit.text));
buf[strlen(mo->edit.text)] = ' ';
}
}
Cmd_TokenizeString(buf, false, false);
Cmd_ExpandString(scriptname, buf, sizeof(buf), &expandlevel, true, true);
//and execute it as-is
Cbuf_AddText(buf, execlevel);
Cbuf_AddText("\n", execlevel);
}
void M_Script_Remove (menu_t *menu)
{
if (menu == menu_script)
menu_script = NULL;
M_Script_Option(menu, "cancel", false);
}
qboolean M_Script_Key (int key, menu_t *menu)
{
if (menu->selecteditem && menu->selecteditem->common.type == mt_edit)
return false;
if (key >= '0' && key <= '9' && menu->data)
{
if (key == '0') //specal case so that "hello" < "0"... (plus matches common impulses)
M_Script_Option(menu, "10", false);
else
M_Script_Option(menu, va("%i", key-'0'), false);
return true;
}
return false;
}
void M_MenuS_Callback_f (void)
{
if (menu_script)
{
M_Script_Option(menu_script, Cmd_Argv(1), true);
}
}
void M_MenuS_Clear_f (void)
{
if (menu_script)
{
M_RemoveMenu(menu_script);
}
}
void M_MenuS_Script_f (void) //create a menu.
{
extern menu_t *topmenu;
int items;
menu_t *oldmenu;
char *alias = Cmd_Argv(1);
Key_Dest_Add(kdm_emenu);
m_state = m_complex;
selectitem = 0;
items=0;
if (menu_script)
{
menuoption_t *option;
for (option = menu_script->options; option; option = option->common.next)
{
if (option->common.type == mt_button)
{
if (menu_script->selecteditem == option)
selectitem = items;
items++;
}
}
selectitem = items - selectitem-1;
M_MenuS_Clear_f();
}
oldmenu = topmenu;
menu_script = M_CreateMenu(0);
if (oldmenu)
{
M_HideMenu(oldmenu); //bring to front
M_AddMenu(oldmenu);
}
menu_script->remove = M_Script_Remove;
menu_script->key = M_Script_Key;
Key_Dest_Remove(kdm_console);
if (Cmd_Argc() == 1)
menu_script->data = Cmd_ParseMultiline(true);
else
menu_script->data = Z_StrDup(alias);
}
void M_MenuS_Box_f (void)
{
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
int width = atoi(Cmd_Argv(3));
int height = atoi(Cmd_Argv(4));
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
MC_AddBox(menu_script, x, y, width/8, height/8);
}
void M_MenuS_CheckBox_f (void)
{
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *text = Cmd_Argv(3);
char *cvarname = Cmd_Argv(4);
int bitmask = atoi(Cmd_Argv(5));
cvar_t *cvar;
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
cvar = Cvar_Get(cvarname, text, 0, "User variables");
if (!cvar)
return;
MC_AddCheckBox(menu_script, x, x+160, y, text, cvar, bitmask);
}
void M_MenuS_Slider_f (void)
{
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *text = Cmd_Argv(3);
char *cvarname = Cmd_Argv(4);
float min = atof(Cmd_Argv(5));
float max = atof(Cmd_Argv(6));
cvar_t *cvar;
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
cvar = Cvar_Get(cvarname, text, 0, "User variables");
if (!cvar)
return;
MC_AddSlider(menu_script, x, x+160, y, text, cvar, min, max, 0);
}
void M_MenuS_Picture_f (void)
{
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *picname = Cmd_Argv(3);
mpic_t *p;
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
p = R2D_SafeCachePic(picname);
if (!p)
return;
if (!strcmp(Cmd_Argv(1), "-"))
MC_AddCenterPicture(menu_script, y, p->height, picname);
else
MC_AddPicture(menu_script, x, y, p->width, p->height, picname);
}
void M_MenuS_Edit_f (void)
{
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *text = Cmd_Argv(3);
char *def = Cmd_Argv(4);
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
MC_AddEditCvar(menu_script, x, x+160, y, text, def, false);
}
void M_MenuS_EditPriv_f (void)
{
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *text = Cmd_Argv(3);
char *def = Cmd_Argv(4);
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
MC_AddEdit(menu_script, x, x+160, y, text, def);
}
void M_MenuS_Text_f (void)
{
menuoption_t *option;
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *text = Cmd_Argv(3);
char *command = Cmd_Argv(4);
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
if (Cmd_Argc() == 4)
MC_AddBufferedText(menu_script, x, 0, y, text, false, false);
else
{
option = (menuoption_t *)MC_AddConsoleCommand(menu_script, x, 0, y, text, va("menucallback \"%s\"\n", command));
if (selectitem-- == 0)
menu_script->selecteditem = option;
}
}
void M_MenuS_TextBig_f (void)
{
menuoption_t *option;
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *text = Cmd_Argv(3);
char *command = Cmd_Argv(4);
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
if (!*command)
MC_AddConsoleCommandQBigFont(menu_script, x, y, text, command);
else
{
option = (menuoption_t *)MC_AddConsoleCommandQBigFont(menu_script, x, y, text, va("menucallback %s\n", command));
if (selectitem-- == 0)
menu_script->selecteditem = option;
}
}
void M_MenuS_Bind_f (void)
{
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *caption = Cmd_Argv(3);
char *command = Cmd_Argv(4);
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
if (!*caption)
caption = command;
MC_AddBind(menu_script, x, x+160, y, command, caption, NULL);
}
void M_MenuS_Comboi_f (void)
{
int opt;
char *opts[64];
char *values[64];
char valuesb[64][8];
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *caption = Cmd_Argv(3);
char *command = Cmd_Argv(4);
char *line;
cvar_t *var;
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
var = Cvar_Get(command, "0", 0, "custom cvars");
if (!var)
return;
if (!*caption)
caption = command;
for (opt = 0; opt < sizeof(opts)/sizeof(opts[0])-2 && *(line=Cmd_Argv(5+opt)); opt++)
{
opts[opt] = line;
Q_snprintfz(valuesb[opt], sizeof(valuesb[opt]), "%i", opt);
values[opt] = valuesb[opt];
}
opts[opt] = NULL;
MC_AddCvarCombo(menu_script, x, x+160, y, caption, var, (const char **)opts, (const char **)values);
}
char *Hunk_TempString(char *s)
{
char *h;
h = Hunk_TempAllocMore(strlen(s)+1);
strcpy(h, s);
return h;
}
void M_MenuS_Combos_f (void)
{
int opt;
char *opts[64];
char *values[64];
int x = atoi(Cmd_Argv(1));
int y = atoi(Cmd_Argv(2));
char *caption = Cmd_Argv(3);
char *command = Cmd_Argv(4);
char *line;
cvar_t *var;
if (!menu_script)
{
Con_Printf("%s with no active menu\n", Cmd_Argv(0));
return;
}
var = Cvar_Get(command, "0", 0, "custom cvars");
if (!var)
return;
if (!*caption)
caption = command;
line = Cmd_Argv(5);
if (!*line)
{
line = Cbuf_GetNext(Cmd_ExecLevel, true);
if (*line != '{')
Cbuf_InsertText(line, Cmd_ExecLevel, true); //whoops. Stick the trimmed string back in to the cbuf.
else
line = "{";
}
if (!strcmp(line, "{"))
{
char *line;
Hunk_TempAlloc(4);
for (opt = 0; opt < sizeof(opts)/sizeof(opts[0])-2; opt++)
{
line = Cbuf_GetNext(Cmd_ExecLevel, true);
line = COM_Parse(line);
if (!strcmp(com_token, "}"))
break;
opts[opt] = Hunk_TempString(com_token);
line = COM_Parse(line);
values[opt] = Hunk_TempString(com_token);
}
}
else
{
for (opt = 0; opt < sizeof(opts)/sizeof(opts[0])-2; opt++)
{
line = Cmd_Argv(5+opt*2);
if (!*line)
break;
opts[opt] = line;
values[opt] = Cmd_Argv(5+opt*2 + 1);
}
}
opts[opt] = NULL;
MC_AddCvarCombo(menu_script, x, x+160, y, caption, var, (const char **)opts, (const char **)values);
}
/*
menuclear
conmenu menucallback
menubox 0 0 320 8
menutext 0 0 "GO GO GO!!!" "radio21"
menutext 0 8 "Fall back" "radio22"
menutext 0 8 "Stick together" "radio23"
menutext 0 16 "Get in position" "radio24"
menutext 0 24 "Storm the front" "radio25"
menutext 0 24 "Report in" "radio26"
menutext 0 24 "Cancel"
*/
void M_Script_Init(void)
{
Cmd_AddCommandD("menuclear", M_MenuS_Clear_f, "Pop the currently scripted menu.");
Cmd_AddCommandD("menucallback", M_MenuS_Callback_f, "Explicitly invoke the active script menu's callback function with the given option set.");
Cmd_AddCommand("conmenu", M_MenuS_Script_f);
Cmd_AddCommand("menubox", M_MenuS_Box_f);
Cmd_AddCommand("menuedit", M_MenuS_Edit_f);
Cmd_AddCommand("menueditpriv", M_MenuS_EditPriv_f);
Cmd_AddCommand("menutext", M_MenuS_Text_f);
Cmd_AddCommand("menutextbig", M_MenuS_TextBig_f);
Cmd_AddCommand("menupic", M_MenuS_Picture_f);
Cmd_AddCommand("menucheck", M_MenuS_CheckBox_f);
Cmd_AddCommand("menuslider", M_MenuS_Slider_f);
Cmd_AddCommand("menubind", M_MenuS_Bind_f);
Cmd_AddCommand("menucomboi", M_MenuS_Comboi_f);
Cmd_AddCommand("menucombos", M_MenuS_Combos_f);
}
#endif