// ===============================================
// menu_cmd (menu command) - menu/command/menu_cmd.qc
// ===============================================
+alias menu_showwelcomedialog "menu_cmd directmenu Welcome"
alias menu_showteamselect "menu_cmd directmenu TeamSelect"
alias menu_showhudexit "menu_cmd directmenu HUDExit"
alias menu_showhudoptions "menu_cmd directpanelhudmenu ${* ?}"
alias team_blue "cmd selectteam blue; cmd join"
alias team_pink "cmd selectteam pink; cmd join"
alias team_yellow "cmd selectteam yellow; cmd join"
-alias team_auto "cmd selectteam auto; cmd join"
+alias team_auto "togglemenu 0; cmd selectteam auto; cmd join"
alias spec "spectate ${* ?}"
COLOR_DIALOG_MODEL '1 1 1'
COLOR_DIALOG_CROSSHAIR '1 1 1'
COLOR_DIALOG_HUD '1 1 1'
-COLOR_DIALOG_SCREENSHOTVIEWER '1 1 1'
COLOR_DIALOG_SERVERINFO '1 1 1'
+COLOR_DIALOG_SCREENSHOTVIEWER '1 1 1'
COLOR_DIALOG_FIRSTRUN '1 1 1'
+COLOR_DIALOG_WELCOME '1 1 1'
COLOR_DIALOG_CVARS '1 0.2 0.15'
COLOR_DIALOG_HUDCONFIRM '1 0.2 0.15'
COLOR_DIALOG_HUD '1 1 1'
COLOR_DIALOG_SERVERINFO '1 1 1'
COLOR_DIALOG_SCREENSHOTVIEWER '1 1 1'
+COLOR_DIALOG_FIRSTRUN '1 1 1'
+COLOR_DIALOG_WELCOME '1 1 1'
COLOR_DIALOG_CVARS '1 0 0'
COLOR_DIALOG_HUDCONFIRM '1 0 0'
COLOR_DIALOG_HUD '1 1 1'
COLOR_DIALOG_SERVERINFO '1 1 1'
COLOR_DIALOG_SCREENSHOTVIEWER '1 1 1'
+COLOR_DIALOG_FIRSTRUN '1 1 1'
+COLOR_DIALOG_WELCOME '1 1 1'
COLOR_DIALOG_CVARS '1 0 0'
COLOR_DIALOG_HUDCONFIRM '1 0 0'
COLOR_DIALOG_HUD '1 1 1'
COLOR_DIALOG_SERVERINFO '1 1 1'
COLOR_DIALOG_SCREENSHOTVIEWER '1 1 1'
+COLOR_DIALOG_FIRSTRUN '1 1 1'
+COLOR_DIALOG_WELCOME '1 1 1'
COLOR_DIALOG_CVARS '1 0 0'
COLOR_DIALOG_HUDCONFIRM '1 0 0'
}
}
+NET_HANDLE(TE_CSQC_SERVERINFO, bool isNew)
+{
+ bool force_centerprint = ReadByte();
+ string hostname = ReadString();
+ string ver = ReadString();
+ string modifications = ReadString();
+ string cache_mutatormsg = ReadString();
+ string mutator_msg = ReadString();
+ string motd = ReadString();
+
+ string msg = "";
+ msg = strcat(msg, ver);
+ msg = strcat(msg, "^8\n\n", _("match type is "), " ^1", MapInfo_Type_ToText(gametype), "^8\n");
+ if(modifications != "")
+ msg = strcat(msg, "^8\n", _("active modifications:"), " ^3", modifications, "^8\n");
+ if (cache_mutatormsg != "")
+ msg = strcat(msg, "\n\n^8", _("special gameplay tips:"), " ^7", cache_mutatormsg);
+ msg = strcat(msg, mutator_msg); // trust that the mutator will do proper formatting
+ if (motd != "")
+ msg = strcat(msg, "\n\n^8", _("MOTD:"), " ^7", motd);
+
+ if (!force_centerprint && !isdemo() && cvar("_menu_welcome_dialog_available") && autocvar_cl_welcome_in_menu_dialog)
+ {
+ string welcomedialog_args;
+ welcomedialog_args = strcat("HOSTNAME \"", hostname, "\"");
+ msg = MakeConsoleSafe(strreplace("\n", "\\n", msg));
+ welcomedialog_args = strcat(welcomedialog_args, " WELCOME \"", msg, "\"");
+ localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n");
+ }
+ else
+ centerprint_Add(ORDINAL(CPID_MOTD), strcat(hostname, "\n\n\n", msg), -1, 0);
+ return true;
+}
+
string _getcommandkey(string cmd_name, string command, bool forcename)
{
string keys;
bool autocvar_developer_csqcentities;
bool autocvar_cl_race_cptimes_onlyself; // TODO: move to race gamemode
bool autocvar_cl_race_cptimes_showself = false;
+bool autocvar_cl_welcome_in_menu_dialog = true;
// Map coordinate base calculations need these
vector mi_center;
REGISTER_NET_TEMP(TE_CSQC_TEAMNAGGER)
REGISTER_NET_TEMP(TE_CSQC_PINGPLREPORT)
REGISTER_NET_TEMP(TE_CSQC_WEAPONCOMPLAIN)
+REGISTER_NET_TEMP(TE_CSQC_SERVERINFO)
REGISTER_NET_TEMP(TE_CSQC_VEHICLESETUP)
const int RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
#include <common/command/_mod.qh>
+.void(entity me, int argsbuf) readInputArgs;
.entity firstChild, nextSibling;
string _dumptree_space;
}
else if (argc == 2 && !isdemo()) // don't allow this command in demos
{
+ if (argv(1) == "Welcome" && cvar("g_campaign"))
+ return;
m_play_click_sound(MENU_SOUND_OPEN);
m_goto(strcat(filter, argv(1))); // switch to a menu item
}
+ else if(argc > 2 && !isdemo())
+ {
+ entity e = NULL;
+ float argsbuf = 0;
+ string s = strzone(argv(1)); // dialog name
+ for(int i = 0; (e = nextent(e)); )
+ if(e.classname != "vtbl" && e.name == strcat(filter, s))
+ {
+ argsbuf = buf_create();
+ if(argsbuf >= 0)
+ if(e.readInputArgs)
+ {
+ for(i = 2; i < argc; ++i)
+ bufstr_add(argsbuf, argv(i), 1);
+ e.readInputArgs(e, argsbuf);
+ m_goto(strcat(filter, s));
+ }
+ if(argsbuf >= 0)
+ buf_del(argsbuf);
+ }
+ }
return;
}
SKINVECTOR(COLOR_DIALOG_CROSSHAIR, '1 0.7 0.7');
SKINVECTOR(COLOR_DIALOG_HUD, '1 0.7 0.7');
SKINVECTOR(COLOR_DIALOG_SERVERINFO, '0.7 0.7 1');
+ SKINVECTOR(COLOR_DIALOG_WELCOME, '1 0.7 0.7');
SKINVECTOR(COLOR_DIALOG_CVARS, '1 0 0');
SKINVECTOR(COLOR_DIALOG_SCREENSHOTVIEWER, '0.7 0.7 1');
SKINVECTOR(COLOR_DIALOG_HUDCONFIRM, '1 0 0');
#include <menu/xonotic/dialog_teamselect.qc>
#include <menu/xonotic/dialog_termsofservice.qc>
#include <menu/xonotic/dialog_uid2name.qc>
+#include <menu/xonotic/dialog_welcome.qc>
#include <menu/xonotic/gametypelist.qc>
#include <menu/xonotic/hudskinlist.qc>
#include <menu/xonotic/image.qc>
#include <menu/xonotic/dialog_teamselect.qh>
#include <menu/xonotic/dialog_termsofservice.qh>
#include <menu/xonotic/dialog_uid2name.qh>
+#include <menu/xonotic/dialog_welcome.qh>
#include <menu/xonotic/gametypelist.qh>
#include <menu/xonotic/hudskinlist.qh>
#include <menu/xonotic/image.qh>
--- /dev/null
+#include "dialog_welcome.qh"
+
+#include "image.qh"
+#include "textlabel.qh"
+#include "textbox.qh"
+#include "radiobutton.qh"
+#include "commandbutton.qh"
+#include "slider.qh"
+
+void welcomeDialog_resetStrings(entity me)
+{
+ strcpy(me.serverinfo_name, "<NO HOSTNAME>");
+ strcpy(me.serverinfo_MOTD, "<NO WELCOME MESSAGE>");
+}
+
+float XonoticWelcomeDialog_keyDown(entity me, float key, float ascii, float shift)
+{
+ switch(key)
+ {
+ case K_KP_ENTER:
+ case K_ENTER:
+ case K_SPACE:
+ me.close(me);
+ return true;
+ default:
+ return SUPER(XonoticWelcomeDialog).keyDown(me, key, ascii, shift);
+ }
+}
+
+void XonoticWelcomeDialog_configureDialog(entity me)
+{
+ welcomeDialog_resetStrings(me);
+ SUPER(XonoticWelcomeDialog).configureDialog(me);
+ registercvar("_menu_welcome_dialog_available", "0", 0);
+ cvar_set("_menu_welcome_dialog_available", "1");
+}
+
+void XonoticWelcomeDialog_destroy(entity me)
+{
+ cvar_set("_menu_welcome_dialog_available", "0");
+}
+
+void XonoticWelcomeDialog_readInputArgs(entity me, int argsbuf)
+{
+ int i = 0;
+ string s;
+ welcomeDialog_resetStrings(me);
+ if(argsbuf >= 0)
+ while((s = bufstr_get(argsbuf, i)) != "")
+ {
+ if(s == "HOSTNAME")
+ strcpy(me.serverinfo_name, bufstr_get(argsbuf, ++i));
+ else if(s == "WELCOME")
+ strcpy(me.serverinfo_MOTD, bufstr_get(argsbuf, ++i));
+ ++i;
+ }
+ //me.serverinfo_name_ent.setText(me.serverinfo_name_ent, me.serverinfo_name);
+ me.serverinfo_MOTD_ent.setText(me.serverinfo_MOTD_ent, me.serverinfo_MOTD);
+ me.frame.setText(me.frame, me.serverinfo_name);
+}
+
+void XonoticWelcomeDialog_fill(entity me)
+{
+ entity e;
+
+ me.TR(me);
+ me.TD(me, me.rows - 1, me.columns, me.serverinfo_MOTD_ent = makeXonoticTextBox());
+ me.serverinfo_MOTD_ent.align = 0.5;
+ me.serverinfo_MOTD_ent.allowColors = true;
+ me.serverinfo_MOTD_ent.escapedNewLines = true;
+ me.gotoRC(me, me.rows - 1, 0);
+ me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0'));
+ e.onClick = Dialog_Close;
+ e.onClickEntity = me;
+ e.preferredFocusPriority = 1;
+}
--- /dev/null
+#pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticWelcomeDialog, XonoticRootDialog)
+ METHOD(XonoticWelcomeDialog, fill, void(entity));
+ ATTRIB(XonoticWelcomeDialog, title, string, _("Welcome"));
+ ATTRIB(XonoticWelcomeDialog, color, vector, SKINCOLOR_DIALOG_WELCOME);
+ ATTRIB(XonoticWelcomeDialog, intendedWidth, float, 0.8);
+ ATTRIB(XonoticWelcomeDialog, rows, float, 12);
+ ATTRIB(XonoticWelcomeDialog, columns, float, 4);
+ ATTRIB(XonoticWelcomeDialog, name, string, "Welcome");
+
+ METHOD(XonoticWelcomeDialog, keyDown, float(entity, float, float, float));
+ METHOD(XonoticWelcomeDialog, configureDialog, void(entity));
+ METHOD(XonoticWelcomeDialog, destroy, void(entity));
+ METHOD(XonoticWelcomeDialog, readInputArgs, void(entity, int));
+ ATTRIB(XonoticWelcomeDialog, serverinfo_name, string, string_null);
+ //ATTRIB(XonoticWelcomeDialog, serverinfo_name_ent, entity, world);
+ ATTRIB(XonoticWelcomeDialog, serverinfo_MOTD, string, string_null);
+ ATTRIB(XonoticWelcomeDialog, serverinfo_MOTD_ent, entity, world);
+ENDCLASS(XonoticWelcomeDialog)
#include "dialog_multiplayer_create_mutators.qh"
#include "dialog_sandboxtools.qh"
#include "dialog_monstertools.qh"
+#include "dialog_welcome.qh"
#include "dialog_teamselect.qh"
#include "dialog_uid2name.qh"
#include "dialog_singleplayer.qh"
i.configureDialog(i);
me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+ i = NEW(XonoticWelcomeDialog);
+ i.configureDialog(i);
+ me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+
// hud_configure dialogs
i = NEW(XonoticHUDExitDialog);
string t;
buf = buf_create();
- for (int i = 0, n = tokenizebyseparator(text, "\n"); i < n; ++i)
+ string separator = (me.escapedNewLines) ? "\\n" : "\n";
+ for (int i = 0, n = tokenizebyseparator(text, separator); i < n; ++i)
{
t = substring(argv(i), 0, -1);
getWrappedLine_remaining = t;
while (getWrappedLine_remaining)
{
- t = getWrappedLine(1, me.realFontSize, draw_TextWidth_WithColors);
+ t = getWrappedLine(1, me.realFontSize, (me.allowColors) ? draw_TextWidth_WithColors : draw_TextWidth_WithoutColors);
bufstr_set(buf, line, t);
line++;
}
void XonoticTextBox_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
{
string s = me.getTextBoxLine(me, i);
- draw_Text(vec2(0, 0), s, me.realFontSize, me.colorL, me.alpha, true);
+ vector color = (me.allowColors) ? '1 1 1' : me.colorL;
+ if (me.align == 0.5)
+ draw_CenterText(0.5 * eX, s, me.realFontSize, color, 1, me.allowColors);
+ else
+ draw_Text(vec2(0, 0), s, me.realFontSize, color, me.alpha, me.allowColors);
}
METHOD(XonoticTextBox, resizeNotify, void(entity, vector, vector, vector, vector));
METHOD(XonoticTextBox, drawListBoxItem, void(entity, int, vector, bool, bool));
ATTRIB(XonoticTextBox, allowFocusSound, float, 0);
+ ATTRIB(XonoticTextBox, align, float, 0);
+ ATTRIB(XonoticTextBox, allowColors, bool, false);
+ ATTRIB(XonoticTextBox, escapedNewLines, bool, false);
ATTRIB(XonoticTextBox, alpha, float, SKINALPHA_TEXT);
ATTRIB(XonoticTextBox, fontSize, float, SKINFONTSIZE_NORMAL);
ATTRIB(XonoticTextBox, realFontSize, vector, '0 0 0');
cvar_settemp("g_dm", "0");
cvar_settemp("skill", ftos(baseskill));
cvar_settemp("bot_number", ftos(campaign_bots[0]));
+ cvar_settemp("cl_welcome_in_menu_dialog", "0");
MapInfo_SwitchGameType(MapInfo_Type_FromString(campaign_gametype[0], false));
}
}
-string getwelcomemessage(entity this)
+void SendWelcomemessage(entity this, bool force_centerprint)
{
+ msg_entity = this;
+ WriteHeader(MSG_ONE, TE_CSQC_SERVERINFO);
+ WriteByte(MSG_ONE, force_centerprint);
+ WriteString(MSG_ONE, autocvar_hostname);
+ WriteString(MSG_ONE, GetClientVersionMessage(this));
+
MUTATOR_CALLHOOK(BuildMutatorsPrettyString, "");
string modifications = M_ARGV(0, string);
modifications = strcat(modifications, ", Jet pack");
modifications = substring(modifications, 2, strlen(modifications) - 2);
- string versionmessage = GetClientVersionMessage(this);
- string s = strcat(versionmessage, "^8\n^8\nserver is ^9", autocvar_hostname, "^8\n");
-
- s = strcat(s, "^8\nmatch type is ^1", gamemode_name, "^8\n");
-
- if(modifications != "")
- s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
+ WriteString(MSG_ONE, modifications);
if(cache_lastmutatormsg != autocvar_g_mutatormsg)
{
strcpy(cache_mutatormsg, cache_lastmutatormsg);
}
- if (cache_mutatormsg != "") {
- s = strcat(s, "\n\n^8special gameplay tips: ^7", cache_mutatormsg);
- }
+ WriteString(MSG_ONE, cache_mutatormsg);
string mutator_msg = "";
MUTATOR_CALLHOOK(BuildGameplayTipsString, mutator_msg);
mutator_msg = M_ARGV(0, string);
- s = strcat(s, mutator_msg); // trust that the mutator will do proper formatting
+ WriteString(MSG_ONE, mutator_msg); // trust that the mutator will do proper formatting
+ WriteString(MSG_ONE, strreplace("\\n", "\n", autocvar_sv_motd));
+}
- string motd = autocvar_sv_motd;
- if (motd != "") {
- s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd));
- }
- return s;
+void SendWelcomemessage_onConnection_think(entity this)
+{
+ SendWelcomemessage(this, false);
+}
+
+void SendWelcomemessage_onConnection(entity this)
+{
+ // give the client time to sent its version
+ defer(this, 0.5, SendWelcomemessage_onConnection_think);
}
/**
CS(this).model_randomizer = random();
if (IS_REAL_CLIENT(this))
+ {
+ if (!autocvar_g_campaign)
+ SendWelcomemessage_onConnection(this);
sv_notice_join(this);
+ }
this.move_qcphysics = autocvar_sv_qcphysics;
MUTATOR_CALLHOOK(ClientConnect, this);
- if (IS_REAL_CLIENT(this))
- {
- if (!autocvar_g_campaign && !IS_PLAYER(this))
- {
- CS(this).motd_actived_time = -1;
- Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, getwelcomemessage(this));
- }
- }
+ if (IS_REAL_CLIENT(this) && !IS_PLAYER(this) && !autocvar_g_campaign)
+ CS(this).motd_actived_time = -1; // the welcome message is shown by the client
}
/*
=============
} else {
if (PHYS_INPUT_BUTTON_INFO(this)) {
CS(this).motd_actived_time = time;
- Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, getwelcomemessage(this));
+ SendWelcomemessage(this, true);
}
}
}
cl_particles_forcetraileffects 1
alias dropweapon "impulse 17"
-alias +show_info +button7
-alias -show_info -button7
+
+alias +show_info0 "+button7"
+alias -show_info0 "-button7"
+alias +show_info1 "menu_showwelcomedialog"
+alias -show_info1 ""
+
+seta cl_welcome_in_menu_dialog 1 "1: show the welcome message in a dedicated menu dialog; 0: show it as a centerprint message"
+alias +show_info +show_info$cl_welcome_in_menu_dialog
+alias -show_info -show_info$cl_welcome_in_menu_dialog
// merge lightmaps up to 2048x2048 textures
mod_q3bsp_lightmapmergepower 4