gamerulespanel.cpp
1 //------------------------------------------------------------------------------
2 // gamerulespanel.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2014 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "gamerulespanel.h"
24 #include "ui_gamerulespanel.h"
25 
26 #include "ini/ini.h"
27 #include "plugins/engineplugin.h"
28 #include "serverapi/gamecreateparams.h"
30 
31 #include <QVariant>
32 #include <climits>
33 
34 DClass<GameRulesPanel> : public Ui::GameRulesPanel
35 {
36 public:
37  class GameLimitWidget
38  {
39  public:
40  QWidget* label;
41  QSpinBox* spinBox;
42  GameCVar limit;
43  };
44 
45  bool anythingAvailable;
46  const EnginePlugin *engine;
47  QList<GameCVar> gameModifiers;
48  QList<GameLimitWidget*> limitWidgets;
49  QMap<QString, QMap<QString, int> > memorizedLimits;
50 };
51 
52 DPointered(GameRulesPanel)
53 
54 GameRulesPanel::GameRulesPanel(QWidget *parent)
55 : QWidget(parent)
56 {
57  d->setupUi(this);
58  d->anythingAvailable = true;
59  d->engine = NULL;
60 }
61 
62 GameRulesPanel::~GameRulesPanel()
63 {
64  qDeleteAll(d->limitWidgets);
65 }
66 
67 void GameRulesPanel::fillInParams(GameCreateParams &params)
68 {
69  params.setMaxClients(d->spinMaxClients->value());
70  params.setMaxPlayers(d->spinMaxPlayers->value());
71 
72  fillInLimits(params);
73  fillInModifiers(params);
74 
75  d->mapListPanel->fillInParams(params);
76 }
77 
78 void GameRulesPanel::fillInLimits(GameCreateParams &params)
79 {
80  foreach(PrivData<GameRulesPanel>::GameLimitWidget* p, d->limitWidgets)
81  {
82  p->limit.setValue(p->spinBox->value());
83  params.cvars() << p->limit;
84  }
85 }
86 
87 void GameRulesPanel::fillInModifiers(GameCreateParams &params)
88 {
89  int modIndex = d->cboModifier->currentIndex();
90  if (modIndex > 0) // Index zero is always "< NONE >"
91  {
92  --modIndex;
93  d->gameModifiers[modIndex].setValue(1);
94  params.cvars() << d->gameModifiers[modIndex];
95  }
96 }
97 
98 bool GameRulesPanel::isAnythingAvailable() const
99 {
100  return d->anythingAvailable;
101 }
102 
103 MapListPanel *GameRulesPanel::mapListPanel()
104 {
105  return d->mapListPanel;
106 }
107 
108 void GameRulesPanel::memorizeLimits()
109 {
110  if (d->engine != NULL)
111  {
112  if (!d->memorizedLimits.contains(d->engine->nameCanonical()))
113  {
114  d->memorizedLimits[d->engine->nameCanonical()] = QMap<QString, int>();
115  }
116  QMap<QString, int> &limits = d->memorizedLimits[d->engine->nameCanonical()];
117  foreach (const PrivData<GameRulesPanel>::GameLimitWidget *limitWidget, d->limitWidgets)
118  {
119  limits[limitWidget->limit.command()] = limitWidget->spinBox->value();
120  }
121  }
122 }
123 
124 void GameRulesPanel::loadMemorizedLimits(const EnginePlugin *engine)
125 {
126  if (d->memorizedLimits.contains(engine->nameCanonical()))
127  {
128  QMap<QString, int> &limits = d->memorizedLimits[engine->nameCanonical()];
129  foreach (const PrivData<GameRulesPanel>::GameLimitWidget *limitWidget, d->limitWidgets)
130  {
131  if (limits.contains(limitWidget->limit.command()))
132  {
133  limitWidget->spinBox->setValue(limits[limitWidget->limit.command()]);
134  }
135  }
136  }
137 }
138 
139 void GameRulesPanel::loadConfig(Ini &config)
140 {
141  IniSection section = config.section("Rules");
142 
143  d->cboModifier->setCurrentIndex(section["modifier"]);
144  d->spinMaxClients->setValue(section["maxClients"]);
145  d->spinMaxPlayers->setValue(section["maxPlayers"]);
146  foreach (PrivData<GameRulesPanel>::GameLimitWidget* widget, d->limitWidgets)
147  {
148  widget->spinBox->setValue(section[widget->limit.command()]);
149  }
150 
151  d->mapListPanel->loadConfig(config);
152 }
153 
154 void GameRulesPanel::saveConfig(Ini &config)
155 {
156  IniSection section = config.section("Rules");
157 
158  section["modifier"] = d->cboModifier->currentIndex();
159  section["maxClients"] = d->spinMaxClients->value();
160  section["maxPlayers"] = d->spinMaxPlayers->value();
161  foreach (PrivData<GameRulesPanel>::GameLimitWidget *widget, d->limitWidgets)
162  {
163  section[widget->limit.command()] = widget->spinBox->value();
164  }
165 
166  d->mapListPanel->saveConfig(config);
167 }
168 
169 void GameRulesPanel::setCreateServerDialog(CreateServerDialog *dialog)
170 {
171  d->mapListPanel->setCreateServerDialog(dialog);
172 }
173 
174 void GameRulesPanel::setupForEngine(const EnginePlugin *engine, const GameMode &gameMode)
175 {
176  d->anythingAvailable = false;
177  setupModifiers(engine);
178 
179  d->mapListBox->setVisible(engine->data()->hasMapList);
180  d->mapListPanel->setupForEngine(engine);
181  d->anythingAvailable = engine->data()->hasMapList || d->anythingAvailable;
182 
183  d->labelMaxClients->setVisible(engine->data()->allowsClientSlots);
184  d->spinMaxClients->setVisible(engine->data()->allowsClientSlots);
185  d->anythingAvailable = engine->data()->allowsClientSlots || d->anythingAvailable;
186 
187  d->labelMaxPlayers->setVisible(engine->data()->allowsPlayerSlots);
188  d->spinMaxPlayers->setVisible(engine->data()->allowsPlayerSlots);
189  d->anythingAvailable = engine->data()->allowsPlayerSlots || d->anythingAvailable;
190 
191  setupLimitWidgets(engine, gameMode);
192  d->anythingAvailable = !d->limitWidgets.isEmpty() || d->anythingAvailable;
193 
194  d->engine = engine;
195 }
196 
197 void GameRulesPanel::setupForRemoteGame()
198 {
199  QWidget *disableControls[] =
200  {
201  d->spinMaxClients, d->spinMaxPlayers, NULL
202  };
203  for (int i = 0; disableControls[i]; ++i)
204  disableControls[i]->setDisabled(true);
205 }
206 
207 void GameRulesPanel::setupModifiers(const EnginePlugin *engine)
208 {
209  QString selectedModifier = d->cboModifier->currentText();
210  d->cboModifier->clear();
211  d->gameModifiers.clear();
212 
213  QList<GameCVar> modifiers = engine->gameModifiers();
214 
215  if (!modifiers.isEmpty())
216  {
217  d->cboModifier->show();
218  d->labelModifiers->show();
219 
220  d->cboModifier->addItem(tr("< NONE >"));
221 
222  foreach (const GameCVar &cvar, modifiers)
223  {
224  d->cboModifier->addItem(cvar.name());
225  d->gameModifiers << cvar;
226  }
227  if (!selectedModifier.isEmpty())
228  {
229  int modifierIndex = d->cboModifier->findText(selectedModifier);
230  if (modifierIndex >= 0)
231  d->cboModifier->setCurrentIndex(modifierIndex);
232  }
233  }
234  else
235  {
236  d->cboModifier->hide();
237  d->labelModifiers->hide();
238  }
239 }
240 
241 void GameRulesPanel::removeLimitWidgets()
242 {
243  foreach (PrivData<GameRulesPanel>::GameLimitWidget *widget, d->limitWidgets)
244  {
245  delete widget->label;
246  delete widget->spinBox;
247  delete widget;
248  }
249 
250  d->limitWidgets.clear();
251 }
252 
253 void GameRulesPanel::setupLimitWidgets(const EnginePlugin *engine, const GameMode &gameMode)
254 {
255  memorizeLimits();
256  removeLimitWidgets();
257  QList<GameCVar> limits = engine->limits(gameMode);
258 
259  foreach (const GameCVar &limit, limits)
260  {
261  QLabel* label = new QLabel(this);
262  label->setText(limit.name());
263  QSpinBox* spinBox = new QSpinBox(this);
264  spinBox->setMaximum(INT_MAX);
265  spinBox->setMinimum(INT_MIN);
266  spinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
267  spinBox->setValue(limit.value().toInt());
268 
269  d->limitsLayout->addRow(label, spinBox);
270 
272  glw->label = label;
273  glw->spinBox = spinBox;
274  glw->limit = limit;
275  d->limitWidgets << glw;
276  }
277 
278  loadMemorizedLimits(engine);
279 }
const QString & name() const
Nice name to display to user in Create Game dialog and in other widgets.
Game parametrization data used when creating new games.
const QVariant & value() const
Passed as the second argument, following command().
QVariant value(const QString &key) const
Retrieves a variable directly; omits the IniVariable system.
Definition: inisection.cpp:164
Dialog window allowing user to create a game.
Game mode representation.
Configuration handler.
Definition: ini.h:69
Definition: dptr.h:31
void setValue(const QString &key, const QVariant &value)
Sets a variable directly. Omits the IniVariable system.
Definition: inisection.cpp:154
virtual QList< GameCVar > gameModifiers() const
Modifier that apply to all game modes (ex. instagib).
QList< GameCVar > & cvars()
Contents of this list will be passed as "+consoleCommand value" to the command line.
INI section representation.
Definition: inisection.h:40
IniSection section(const QString &name)
Access configuration file section.
Definition: ini.cpp:95
virtual QList< GameCVar > limits(const GameMode &mode) const
Returns a list of limits (like fraglimit) supported by passed gamemode.
Definition: engineplugin.h:428
QString nameCanonical() const
Either specified explicitly by plugin or derived from the actual plugin name.
A general game setting or variable (like fraglimit).