gamerulespanel.cpp
1 //------------------------------------------------------------------------------
2 // gamerulespanel.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program 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
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; 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 <climits>
32 
33 DClass<GameRulesPanel> : public Ui::GameRulesPanel
34 {
35 public:
36  class GameLimitWidget
37  {
38  public:
39  QWidget* label;
40  QSpinBox* spinBox;
41  GameCVar limit;
42  };
43 
44  const EnginePlugin *engine;
45  QList<GameCVar> gameModifiers;
46  QList<GameLimitWidget*> limitWidgets;
47  QMap<QString, QMap<QString, int> > memorizedLimits;
48  QVariant memorizedDifficulty;
49 };
50 
51 DPointered(GameRulesPanel)
52 
53 GameRulesPanel::GameRulesPanel(QWidget *parent)
54 : QWidget(parent)
55 {
56  d->setupUi(this);
57  d->engine = NULL;
58 }
59 
60 GameRulesPanel::~GameRulesPanel()
61 {
62  qDeleteAll(d->limitWidgets);
63 }
64 
65 void GameRulesPanel::fillInParams(GameCreateParams &params)
66 {
67  params.setSkill(d->cboDifficulty->currentIndex());
68  params.setMaxClients(d->spinMaxClients->value());
69  params.setMaxPlayers(d->spinMaxPlayers->value());
70 
71  fillInLimits(params);
72  fillInModifiers(params);
73 
74  d->mapListPanel->fillInParams(params);
75 }
76 
77 void GameRulesPanel::fillInLimits(GameCreateParams &params)
78 {
79  foreach(PrivData<GameRulesPanel>::GameLimitWidget* p, d->limitWidgets)
80  {
81  p->limit.setValue(p->spinBox->value());
82  params.cvars() << p->limit;
83  }
84 }
85 
86 void GameRulesPanel::fillInModifiers(GameCreateParams &params)
87 {
88  int modIndex = d->cboModifier->currentIndex();
89  if (modIndex > 0) // Index zero is always "< NONE >"
90  {
91  --modIndex;
92  d->gameModifiers[modIndex].setValue(1);
93  params.cvars() << d->gameModifiers[modIndex];
94  }
95 }
96 
97 MapListPanel *GameRulesPanel::mapListPanel()
98 {
99  return d->mapListPanel;
100 }
101 
102 void GameRulesPanel::memorizeLimits()
103 {
104  if (d->engine != NULL)
105  {
106  if (!d->memorizedLimits.contains(d->engine->nameCanonical()))
107  {
108  d->memorizedLimits[d->engine->nameCanonical()] = QMap<QString, int>();
109  }
110  QMap<QString, int> &limits = d->memorizedLimits[d->engine->nameCanonical()];
111  foreach (const PrivData<GameRulesPanel>::GameLimitWidget *limitWidget, d->limitWidgets)
112  {
113  limits[limitWidget->limit.command()] = limitWidget->spinBox->value();
114  }
115  }
116 }
117 
118 void GameRulesPanel::loadMemorizedLimits(const EnginePlugin *engine)
119 {
120  if (d->memorizedLimits.contains(engine->nameCanonical()))
121  {
122  QMap<QString, int> &limits = d->memorizedLimits[engine->nameCanonical()];
123  foreach (const PrivData<GameRulesPanel>::GameLimitWidget *limitWidget, d->limitWidgets)
124  {
125  if (limits.contains(limitWidget->limit.command()))
126  {
127  limitWidget->spinBox->setValue(limits[limitWidget->limit.command()]);
128  }
129  }
130  }
131 }
132 
133 void GameRulesPanel::loadConfig(Ini &config)
134 {
135  IniSection section = config.section("Rules");
136 
137  d->cboDifficulty->setCurrentIndex(section["difficulty"]);
138  d->cboModifier->setCurrentIndex(section["modifier"]);
139  d->spinMaxClients->setValue(section["maxClients"]);
140  d->spinMaxPlayers->setValue(section["maxPlayers"]);
141  foreach (PrivData<GameRulesPanel>::GameLimitWidget* widget, d->limitWidgets)
142  {
143  widget->spinBox->setValue(section[widget->limit.command()]);
144  }
145 
146  d->mapListPanel->loadConfig(config);
147 }
148 
149 void GameRulesPanel::saveConfig(Ini &config)
150 {
151  IniSection section = config.section("Rules");
152 
153  section["difficulty"] = d->cboDifficulty->currentIndex();
154  section["modifier"] = d->cboModifier->currentIndex();
155  section["maxClients"] = d->spinMaxClients->value();
156  section["maxPlayers"] = d->spinMaxPlayers->value();
157  foreach (PrivData<GameRulesPanel>::GameLimitWidget *widget, d->limitWidgets)
158  {
159  section[widget->limit.command()] = widget->spinBox->value();
160  }
161 
162  d->mapListPanel->saveConfig(config);
163 }
164 
165 void GameRulesPanel::setCreateServerDialog(CreateServerDialog *dialog)
166 {
167  d->mapListPanel->setCreateServerDialog(dialog);
168 }
169 
170 void GameRulesPanel::setupForEngine(const EnginePlugin *engine, const GameMode &gameMode)
171 {
172  setupDifficulty(engine);
173  setupModifiers(engine);
174 
175  d->mapListBox->setVisible(engine->data()->hasMapList);
176  d->mapListPanel->setupForEngine(engine);
177 
178  d->labelMaxClients->setVisible(engine->data()->allowsClientSlots);
179  d->spinMaxClients->setVisible(engine->data()->allowsClientSlots);
180 
181  d->labelMaxPlayers->setVisible(engine->data()->allowsPlayerSlots);
182  d->spinMaxPlayers->setVisible(engine->data()->allowsPlayerSlots);
183 
184  setupLimitWidgets(engine, gameMode);
185  d->engine = engine;
186 }
187 
188 void GameRulesPanel::setupForRemoteGame()
189 {
190  QWidget *disableControls[] =
191  {
192  d->spinMaxClients, d->spinMaxPlayers, NULL
193  };
194  for (int i = 0; disableControls[i]; ++i)
195  disableControls[i]->setDisabled(true);
196 }
197 
198 void GameRulesPanel::setupDifficulty(const EnginePlugin *engine)
199 {
200  QVariant oldLevel = d->cboDifficulty->itemData(d->cboDifficulty->currentIndex());
201  if (oldLevel.isValid())
202  {
203  d->memorizedDifficulty = oldLevel;
204  }
205  d->cboDifficulty->clear();
206 
207  QList<GameCVar> levels = engine->data()->difficulty->get(QVariant());
208  d->labelDifficulty->setVisible(!levels.isEmpty());
209  d->cboDifficulty->setVisible(!levels.isEmpty());
210  foreach (const GameCVar &level, levels)
211  {
212  d->cboDifficulty->addItem(level.name(), level.value());
213  if (level.value() == d->memorizedDifficulty)
214  {
215  d->cboDifficulty->setCurrentIndex(d->cboDifficulty->count() - 1);
216  }
217  }
218 }
219 
220 void GameRulesPanel::setupModifiers(const EnginePlugin *engine)
221 {
222  d->cboModifier->clear();
223  d->gameModifiers.clear();
224 
225  QList<GameCVar> modifiers = engine->gameModifiers();
226 
227  if (!modifiers.isEmpty())
228  {
229  d->cboModifier->show();
230  d->labelModifiers->show();
231 
232  d->cboModifier->addItem(tr("< NONE >"));
233 
234  foreach (const GameCVar &cvar, modifiers)
235  {
236  d->cboModifier->addItem(cvar.name());
237  d->gameModifiers << cvar;
238  }
239  }
240  else
241  {
242  d->cboModifier->hide();
243  d->labelModifiers->hide();
244  }
245 }
246 
247 void GameRulesPanel::removeLimitWidgets()
248 {
249  foreach (PrivData<GameRulesPanel>::GameLimitWidget *widget, d->limitWidgets)
250  {
251  delete widget->label;
252  delete widget->spinBox;
253  delete widget;
254  }
255 
256  d->limitWidgets.clear();
257 }
258 
259 void GameRulesPanel::setupLimitWidgets(const EnginePlugin *engine, const GameMode &gameMode)
260 {
261  memorizeLimits();
262  removeLimitWidgets();
263  QList<GameCVar> limits = engine->limits(gameMode);
264 
265  foreach (const GameCVar &limit, limits)
266  {
267  QLabel* label = new QLabel(this);
268  label->setText(limit.name());
269  QSpinBox* spinBox = new QSpinBox(this);
270  spinBox->setMaximum(INT_MAX);
271  spinBox->setMinimum(INT_MIN);
272  spinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
273  spinBox->setValue(limit.value().toInt());
274 
275  d->limitsLayout->addRow(label, spinBox);
276 
278  glw->label = label;
279  glw->spinBox = spinBox;
280  glw->limit = limit;
281  d->limitWidgets << glw;
282  }
283 
284  loadMemorizedLimits(engine);
285 }
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
QSharedPointer< GameCVarProvider > difficulty
Difficulty levels provider for this game.
Definition: engineplugin.h:289
Dialog window allowing user to host 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:91
virtual QList< GameCVar > limits(const GameMode &mode) const
Returns a list of limits (like fraglimit) supported by passed gamemode.
Definition: engineplugin.h:389
QString nameCanonical() const
Derived from actual plugin name.
A general game setting or variable (like fraglimit).