85e0e9e69887bdf5bf5064de494eb46cbb4cfe64
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / xonotic / dialog_multiplayer_create.qc
1 #include "dialog_multiplayer_create.qh"
2
3 #include "dialog_multiplayer_create_mapinfo.qh"
4 #include "dialog_multiplayer_create_mutators.qh"
5
6 #include "gametypelist.qh"
7 #include "maplist.qh"
8 #include <common/mapinfo.qh>
9
10 #include "image.qh"
11 #include "textslider.qh"
12 #include "textlabel.qh"
13 #include "slider.qh"
14 #include "mainwindow.qh"
15 #include "button.qh"
16 #include "inputbox.qh"
17
18 void GameType_ConfigureSliders(entity me, string pLabel, float pMin, float pMax, float pStep, string pCvar, string tCvar, string pTooltip)
19 {
20         int i;
21         entity e = me.sliderFraglimit;
22         entity l = me.labelFraglimit;
23         e.configureXonoticTextSlider(e, pCvar, pTooltip);
24         e.disabled = l.disabled = !pCvar;
25         l.setText(l, pLabel);
26
27         // clear old values
28         for(i = 0; i < e.nValues; ++i);
29         {
30                 if(e.(valueStrings[i]))
31                 {
32                         strunzone(e.(valueStrings[i]));
33                         e.(valueStrings[i]) = string_null;
34                 }
35                 if(e.(valueIdentifiers[i]))
36                 {
37                         strunzone(e.(valueIdentifiers[i]));
38                         e.(valueIdentifiers[i]) = string_null;
39                 }
40         }
41         e.clearValues(e);
42
43         if(pCvar != "")
44         {
45                 // set new values
46                 e.addValue(e, strzone(_("Default")), strzone("-1"));
47                 for(i = pMin; i <= pMax; i += pStep) { e.addValue(e, strzone(ftos(i)), strzone(ftos(i))); }
48                 e.addValue(e, strzone(_("Unlimited")), strzone("0"));
49         }
50         e.configureXonoticTextSliderValues(e);
51
52
53         entity t = me.sliderTeams;
54         entity tl = me.labelTeams;
55         t.configureXonoticTextSlider(t, tCvar, string_null);
56         tl.disabled = t.disabled = !tCvar;
57         t.nValues = (tCvar == "") ? 0 : 4; // instead of clearing / readding the very same values
58         t.configureXonoticTextSliderValues(t);
59 }
60
61 entity makeXonoticServerCreateTab()
62 {
63         entity me;
64         me = NEW(XonoticServerCreateTab);
65         me.configureDialog(me);
66         return me;
67 }
68
69 void XonoticServerCreateTab_fill(entity me)
70 {
71         entity e, e0;
72
73         // the left half begins here
74
75         me.gotoRC(me, 0.5, 0);
76                 me.TD(me, 1, 3, makeXonoticHeaderLabel(_("Gametype")));
77         me.TR(me);
78                 me.TD(me, 10.5, 3, e = makeXonoticGametypeList());
79
80         me.gotoRC(me, 12.5, 0);
81                 me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Time limit:")));
82                 me.TD(me, 1, 2, e = makeXonoticTextSlider_T("timelimit_override",
83                         _("Timelimit in minutes that when hit, will end the match")));
84                         #define ADDVALUE_MINUTES(i) e.addValue(e, strzone(sprintf(_("%d minutes"), i)), #i)
85                         e.addValue(e, ZCTX(_("TIMLIM^Default")), "-1");
86                         e.addValue(e, _("1 minute"), "1");
87                         ADDVALUE_MINUTES(2);
88                         ADDVALUE_MINUTES(3);
89                         ADDVALUE_MINUTES(4);
90                         ADDVALUE_MINUTES(5);
91                         ADDVALUE_MINUTES(6);
92                         ADDVALUE_MINUTES(7);
93                         ADDVALUE_MINUTES(8);
94                         ADDVALUE_MINUTES(9);
95                         ADDVALUE_MINUTES(10);
96                         ADDVALUE_MINUTES(15);
97                         ADDVALUE_MINUTES(20);
98                         ADDVALUE_MINUTES(25);
99                         ADDVALUE_MINUTES(30);
100                         ADDVALUE_MINUTES(40);
101                         ADDVALUE_MINUTES(50);
102                         ADDVALUE_MINUTES(60);
103                         e.addValue(e, ZCTX(_("TIMLIM^Infinite")), "0");
104                         e.configureXonoticTextSliderValues(e);
105                         #undef ADDVALUE_MINUTES
106         me.TR(me);
107                 me.TD(me, 1, 1, me.labelFraglimit = makeXonoticTextLabel(0, _("Frag limit:")));
108                 me.TD(me, 1, 2, e = me.sliderFraglimit = makeXonoticTextSlider("fraglimit_override"));
109
110         me.gotoRC(me, 15, 0);
111                 me.TD(me, 1, 1, me.labelTeams = makeXonoticTextLabel(0, _("Teams:")));
112                 me.TD(me, 1, 2, e = me.sliderTeams = makeXonoticTextSlider(string_null));
113                         e.addValue(e, _("Default"), "0");
114                         e.addValue(e, _("2 teams"), "2");
115                         e.addValue(e, _("3 teams"), "3");
116                         e.addValue(e, _("4 teams"), "4");
117                         e.configureXonoticTextSliderValues(e);
118         me.TR(me);
119                 me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Player slots:")));
120                 me.TD(me, 1, 2, e = makeXonoticSlider_T(1, 32, 1, "menu_maxplayers",
121                         _("The maximum amount of players or bots that can be connected to your server at once")));
122         me.TR(me);
123                 me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Number of bots:")));
124                 me.TD(me, 1, 2, e = makeXonoticSlider_T(0, 9, 1, "bot_number",
125                         _("Amount of bots on your server")));
126         me.TR(me);
127                 me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Bot skill:")));
128                         setDependent(e, "bot_number", 0, -1);
129                 me.TD(me, 1, 2, e = makeXonoticTextSlider_T("skill",
130                         _("Specify how experienced the bots will be")));
131                         e.addValue(e, _("Botlike"), "0");
132                         e.addValue(e, _("Beginner"), "1");
133                         e.addValue(e, _("You will win"), "2");
134                         e.addValue(e, _("You can win"), "3");
135                         e.addValue(e, _("You might win"), "4");
136                         e.addValue(e, _("Advanced"), "5");
137                         e.addValue(e, _("Expert"), "6");
138                         e.addValue(e, _("Pro"), "7");
139                         e.addValue(e, _("Assassin"), "8");
140                         e.addValue(e, _("Unhuman"), "9");
141                         e.addValue(e, _("Godlike"), "10");
142                         e.configureXonoticTextSliderValues(e);
143                         setDependent(e, "bot_number", 0, -1);
144
145         me.gotoRC(me, me.rows - 3.8, 0);
146                 me.TD(me, 1, 3, e0 = makeXonoticTextLabel(0.5, string_null));
147                         e0.textEntity = main.mutatorsDialog;
148                         e0.allowCut = 1;
149                         //e0.allowWrap = 1;
150
151         // mapListBox is in the right column but the ref is needed for mutators dialog here
152         me.mapListBox = makeXonoticMapList();
153         // here we use the following line instead of me.TR(me) for better visual spacing;
154         // this decision was made in this poll: http://forums.xonotic.org/showthread.php?tid=5445
155         me.gotoRC(me, me.rows - 2.5, 0);
156                 me.TDempty(me, 0.5);
157                 me.TD(me, 1, 2, e = makeXonoticButton_T(_("Mutators..."), '0 0 0',
158                         _("Mutators and weapon arenas")));
159                         e.onClick = DialogOpenButton_Click;
160                         e.onClickEntity = main.mutatorsDialog;
161                         main.mutatorsDialog.refilterEntity = me.mapListBox;
162
163         // The right half begins here
164
165         me.gotoRC(me, 0.5, 3.2); me.setFirstColumn(me, me.currentColumn);
166                 // the maplistbox
167                 me.TD(me, 1, 3, e = makeXonoticHeaderLabel(_("Maplist")));
168                         makeCallback(e, me.mapListBox, me.mapListBox.refilterCallback);
169         me.TR(me);
170                 // we use 5.8 here to visually match the bottom line of the component on the left (Bot Skill)
171                 me.TD(me, me.rows - 6.8, 3, me.mapListBox);
172
173         me.gotoRC(me, me.rows - 4.5, me.firstColumn);
174                 // string filter label and box
175                 me.TD(me, 1, 0.35, e = makeXonoticTextLabel(1, _("Filter:")));
176                 me.mapListBox.stringFilterBox = makeXonoticInputBox_T(0, string_null,
177                         _("Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-Delete to clear; Enter when done."));
178                 me.TD(me, 1, me.columns - me.firstColumn - 0.35, e = me.mapListBox.stringFilterBox);
179                         e.onChange = MapList_StringFilterBox_Change;
180                         e.keyDown = MapList_StringFilterBox_keyDown;
181                         e.onChangeEntity = me.mapListBox;
182
183         me.gotoRC(me, me.rows - 3.5, me.firstColumn);
184                 // the selection buttons
185                 me.TDempty(me, 0.2);
186                 me.TD(me, 1, 1.3, e = makeXonoticButton_T(_("Add shown"), '0 0 0',
187                         _("Add the maps shown in the list to your selection")));
188                         e.onClick = MapList_Add_Shown;
189                         e.onClickEntity = me.mapListBox;
190                 me.TD(me, 1, 1.3, e = makeXonoticButton_T(_("Remove shown"), '0 0 0',
191                         _("Remove the maps shown in the list from your selection")));
192                         e.onClick = MapList_Remove_Shown;
193                         e.onClickEntity = me.mapListBox;
194         me.gotoRC(me, me.rows - 2.5, me.firstColumn);
195                 me.TDempty(me, 0.2);
196                 me.TD(me, 1, 1.3, e = makeXonoticButton_T(_("Add all"), '0 0 0',
197                         _("Add every available map to your selection")));
198                         e.onClick = MapList_Add_All;
199                         e.onClickEntity = me.mapListBox;
200                 me.TD(me, 1, 1.3, e = makeXonoticButton_T(_("Remove all"), '0 0 0',
201                         _("Remove all the maps from your selection")));
202                         e.onClick = MapList_Remove_All;
203                         e.onClickEntity = me.mapListBox;
204
205         // The big button at the bottom
206
207         me.gotoRC(me, me.rows - 1, 0);
208                 me.TD(me, 1, me.columns, e = makeXonoticButton(_("Start Multiplayer!"), '0 0 0'));
209                         e.onClick = MapList_LoadMap;
210                         e.onClickEntity = me.mapListBox;
211                         me.mapListBox.startButton = e;
212
213         me.gameTypeChangeNotify(me);
214 }
215
216 void XonoticServerCreateTab_gameTypeChangeNotify(entity me)
217 {
218         switch(MapInfo_CurrentGametype())
219         {
220                 case MAPINFO_TYPE_CA:              GameType_ConfigureSliders(me, _("Frag limit:"),      5,  100,  5, "fraglimit_override",        "g_ca_teams_override",          _("The amount of frags needed before the match will end")); break;
221                 case MAPINFO_TYPE_FREEZETAG:       GameType_ConfigureSliders(me, _("Frag limit:"),      5,  100,  5, "fraglimit_override",        "g_freezetag_teams_override",   _("The amount of frags needed before the match will end")); break;
222                 case MAPINFO_TYPE_CTF:             GameType_ConfigureSliders(me, _("Capture limit:"),   1,   20,  1, "capturelimit_override",     string_null,                    _("The amount of captures needed before the match will end")); break;
223                 case MAPINFO_TYPE_DOMINATION:      GameType_ConfigureSliders(me, _("Point limit:"),    50,  500, 10, "g_domination_point_limit",  "g_domination_teams_override",  _("The amount of points needed before the match will end")); break;
224                 case MAPINFO_TYPE_KEYHUNT:         GameType_ConfigureSliders(me, _("Point limit:"),   200, 1500, 50, "g_keyhunt_point_limit",     "g_keyhunt_teams_override",     _("The amount of points needed before the match will end")); break;
225                 case MAPINFO_TYPE_LMS:             GameType_ConfigureSliders(me, _("Lives:"),           3,   50,  1, "g_lms_lives_override",      string_null,                    string_null); break;
226                 case MAPINFO_TYPE_RACE:            GameType_ConfigureSliders(me, _("Laps:"),            1,   25,  1, "g_race_laps_limit",         string_null,                    string_null); break;
227                 case MAPINFO_TYPE_NEXBALL:         GameType_ConfigureSliders(me, _("Goals:"),           1,   50,  1, "g_nexball_goallimit",       string_null,                    _("The amount of goals needed before the match will end")); break;
228                 case MAPINFO_TYPE_ASSAULT:         GameType_ConfigureSliders(me, _("Point limit:"),    50,  500, 10, string_null,                 string_null,                    string_null); break;
229                 case MAPINFO_TYPE_ONSLAUGHT:       GameType_ConfigureSliders(me, _("Point limit:"),    50,  500, 10, string_null,                 string_null,                    string_null); break;
230                 case MAPINFO_TYPE_CTS:             GameType_ConfigureSliders(me, _("Point limit:"),    50,  500, 10, string_null,                 string_null,                    string_null); break;
231                 case MAPINFO_TYPE_INVASION:        GameType_ConfigureSliders(me, _("Point limit:"),    50,  500, 10, string_null,                 string_null,                    string_null); break;
232                 case MAPINFO_TYPE_TEAM_DEATHMATCH: GameType_ConfigureSliders(me, _("Point limit:"),     5,  100,  5, "g_tdm_point_limit",         "g_tdm_teams_override",         _("The amount of points needed before the match will end")); break;
233                 default:                           GameType_ConfigureSliders(me, _("Frag limit:"),      5,  100,  5, "fraglimit_override",        string_null,                    _("The amount of frags needed before the match will end")); break;
234         }
235
236         me.mapListBox.refilter(me.mapListBox);
237 }
238
239 void XonoticServerCreateTab_gameTypeSelectNotify(entity me)
240 {
241         me.setFocus(me, me.mapListBox);
242 }