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