ktron.cpp 12 KB
Newer Older
1
2
/**********************************************************************************
  This file is part of the game 'KTron'
Stephan Kulow's avatar
Stephan Kulow committed
3

4
  Copyright (C) 1998-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
Benjamin Meyer's avatar
Benjamin Meyer committed
5
  Copyright (C) 2005 Benjamin C. Meyer <ben at meyerhome dot net>
6
  Copyright (C) 2008-2009 Stas Verberkt <legolas at legolasweb dot nl>
Stephan Kulow's avatar
Stephan Kulow committed
7
8
9
10
11

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
12

Stephan Kulow's avatar
Stephan Kulow committed
13
14
15
16
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
17

Stephan Kulow's avatar
Stephan Kulow committed
18
19
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
Dirk Mueller's avatar
Dirk Mueller committed
20
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Stephan Kulow's avatar
Stephan Kulow committed
21

22
  *******************************************************************************/
Stephan Kulow's avatar
Stephan Kulow committed
23
24

#include "ktron.h"
25
#include "renderer.h"
26
27
#include "settings.h"
#include "ui_general.h"
Stephan Kulow's avatar
Stephan Kulow committed
28

29
30
31
32
33
34
#include <KConfigDialog>
#include <KLocale>
#include <KMessageBox>
#include <KAction>
#include <KActionCollection>
#include <KStandardGameAction>
Stas Verberkt's avatar
Stas Verberkt committed
35
#include <KScoreDialog>
36
37
#include <KGameThemeSelector>
#include <KGameDifficulty>
38
#include <KShortcutsDialog>
Laurent Montel's avatar
Laurent Montel committed
39
#include <KStatusBar>
40
#include <KToggleAction>
Laurent Montel's avatar
Laurent Montel committed
41
#include <KApplication>
Stas Verberkt's avatar
Stas Verberkt committed
42
43
//UI
class General : public QWidget, public Ui::General
44
45
{
public:
Stas Verberkt's avatar
Stas Verberkt committed
46
    General(QWidget *parent = 0)
47
48
49
50
51
52
        : QWidget(parent)
        {
            setupUi(this);
        }
};

53
54
/**
 * Constuctor
55
 */
Stas Verberkt's avatar
Stas Verberkt committed
56
KTron::KTron(QWidget *parent) : KXmlGuiWindow(parent, KDE_DEFAULT_WINDOWFLAGS) {
57
58
59
60
61
62
	m_tron = new Tron(this);
	connect(m_tron,SIGNAL(gameEnds()),SLOT(changeStatus()));
	connect(m_tron,SIGNAL(updatedScore()),SLOT(updateScore()));
	connect(m_tron,SIGNAL(pauseBlocked(bool)),SLOT(blockPause(bool)));
	m_tron->setMinimumSize(700,420);
	setCentralWidget(m_tron);
63

64
	// create statusbar
Laurent Montel's avatar
Laurent Montel committed
65
66
	statusBar()->insertItem(QLatin1String( "abcdefghijklmnopqrst: 0  " ),ID_STATUS_BASE + 1);
	statusBar()->insertItem(QLatin1String( "abcdefghijklmnopqrst: 0  " ),ID_STATUS_BASE + 2);
67
68
69

	// We match up keyboard events ourselves in Tron::keyPressEvent()
	// We must disable the actions, otherwise we don't get the keyPressEvent's
70

71
	m_player0Up = actionCollection()->addAction( QLatin1String( "Pl1Up" ));
72
73
74
75
76
	m_player0Up->setText(i18n("Right Player / KSnake: Up"));
	m_player0Up->setShortcut(Qt::Key_Up);
	connect(m_player0Up, SIGNAL(triggered(bool)), SLOT(triggerKey0Up(bool)));
	addAction(m_player0Up);

77
	m_player0Down = actionCollection()->addAction( QLatin1String( "Pl1Down" ));
78
79
80
81
82
	m_player0Down->setText(i18n("Right Player / KSnake: Down"));
	m_player0Down->setShortcut(Qt::Key_Down);
	connect(m_player0Down, SIGNAL(triggered(bool)), SLOT(triggerKey0Down(bool)));
	addAction(m_player0Down);

83
	m_player0Right = actionCollection()->addAction( QLatin1String( "Pl1Right" ));
84
85
86
87
88
	m_player0Right->setText(i18n("Right Player / KSnake: Right"));
	m_player0Right->setShortcut(Qt::Key_Right);
	connect(m_player0Right, SIGNAL(triggered(bool)), SLOT(triggerKey0Right(bool)));
	addAction(m_player0Right);

89
	m_player0Left = actionCollection()->addAction( QLatin1String( "Pl1Left" ));
90
91
92
93
94
	m_player0Left->setText(i18n("Right Player / KSnake: Left"));
	m_player0Left->setShortcut(Qt::Key_Left);
	connect(m_player0Left, SIGNAL(triggered(bool)), SLOT(triggerKey0Left(bool)));
	addAction(m_player0Left);

95
	m_player0Accelerate = actionCollection()->addAction( QLatin1String( "Pl1Ac" ));
96
97
98
99
100
	m_player0Accelerate->setText(i18n("Right Player: Accelerator"));
	m_player0Accelerate->setShortcut(Qt::Key_0);
	m_player0Accelerate->setEnabled(false); // Alternate handling, because of up/down events
	addAction(m_player0Accelerate);

101
	m_player1Up = actionCollection()->addAction( QLatin1String( "Pl2Up" ));
102
103
104
105
106
	m_player1Up->setText(i18n("Left Player: Up"));
	m_player1Up->setShortcut(Qt::Key_W);
	connect(m_player1Up, SIGNAL(triggered(bool)), SLOT(triggerKey1Up(bool)));
	addAction(m_player1Up);

107
	m_player1Down = actionCollection()->addAction( QLatin1String( "Pl2Down" ));
108
109
110
111
112
	m_player1Down->setText(i18n("Left Player: Down"));
	m_player1Down->setShortcut(Qt::Key_S);
	connect(m_player1Down, SIGNAL(triggered(bool)), SLOT(triggerKey1Down(bool)));
	addAction(m_player1Down);

113
	m_player1Right = actionCollection()->addAction( QLatin1String( "Pl2Right" ));;
114
115
116
117
118
	m_player1Right->setText(i18n("Left Player: Right"));
	m_player1Right->setShortcut(Qt::Key_D);
	connect(m_player1Right, SIGNAL(triggered(bool)), SLOT(triggerKey1Right(bool)));
	addAction(m_player1Right);

119
	m_player1Left = actionCollection()->addAction( QLatin1String( "Pl2Left" ));
120
121
122
123
124
	m_player1Left->setText(i18n("Left Player: Left"));
	m_player1Left->setShortcut(Qt::Key_A);
	connect(m_player1Left, SIGNAL(triggered(bool)), SLOT(triggerKey1Left(bool)));
	addAction(m_player1Left);

125
	m_player1Accelerate = actionCollection()->addAction( QLatin1String( "Pl2Ac" ));
126
127
128
129
	m_player1Accelerate->setText(i18n("Left Player: Accelerator"));
	m_player1Accelerate->setShortcut(Qt::Key_Q);
	m_player1Accelerate->setEnabled(false); // Alternate handling, because of up/down events
	addAction(m_player1Accelerate);
130
131

	// Pause
132
133
	m_pauseButton = KStandardGameAction::pause(m_tron, SLOT(togglePause()), actionCollection());
	m_pauseButton->setEnabled(false);
134
	// New
Laurent Montel's avatar
Laurent Montel committed
135
	KStandardGameAction::gameNew(m_tron, SLOT(newGame()), actionCollection());
136
	// Quit
Stas Verberkt's avatar
Stas Verberkt committed
137
	KStandardGameAction::quit(kapp, SLOT(quit()), actionCollection());
138
	// Settings
Stas Verberkt's avatar
Stas Verberkt committed
139
	KStandardAction::preferences(this, SLOT(showSettings()), actionCollection());
140
	// Configure keys
Stas Verberkt's avatar
Stas Verberkt committed
141
	KStandardAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
Stas Verberkt's avatar
Stas Verberkt committed
142
143
	// Highscores
	KStandardGameAction::highscores(this, SLOT(showHighscores()), actionCollection());
144
145

	//difficulty
146
	KGameDifficulty::init(this, m_tron, SLOT(loadSettings()));
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
	KGameDifficulty::addStandardLevel(KGameDifficulty::VeryEasy);
	KGameDifficulty::addStandardLevel(KGameDifficulty::Easy);
	KGameDifficulty::addStandardLevel(KGameDifficulty::Medium);
	KGameDifficulty::addStandardLevel(KGameDifficulty::Hard);
	KGameDifficulty::addStandardLevel(KGameDifficulty::VeryHard);
	int skill = Settings::difficulty();
	if (skill < (int)KGameDifficulty::VeryEasy || skill > (int)KGameDifficulty::VeryHard) {
		KGameDifficulty::setLevel(KGameDifficulty::Easy);
		Settings::setDifficulty((int) KGameDifficulty::Easy);
	}
	else {
		KGameDifficulty::setLevel((KGameDifficulty::standardLevel) (skill));
	}

	setupGUI( KXmlGuiWindow::Keys | StatusBar | Save | Create);
	loadSettings();
163
	m_tron->loadSettings();
164
}
Stephan Kulow's avatar
Stephan Kulow committed
165

Stas Verberkt's avatar
Stas Verberkt committed
166
167
KTron::~KTron()
{
168
	delete m_tron;
Stas Verberkt's avatar
Stas Verberkt committed
169
170
}

171
void KTron::loadSettings() {
172
	if (!Renderer::self()->loadTheme(Settings::theme()))
173
	{
174
175
		KMessageBox::error(this, i18n("Failed to load \"%1\" theme. Please check your installation.", Settings::theme()));
	}
176

177
178
179
180
181
	m_tron->getPlayer(0)->setName(Settings::namePlayer1());
	m_tron->getPlayer(1)->setName(Settings::namePlayer2());
	Settings::setNamePlayer1(m_tron->getPlayer(0)->getName());
	if (!m_tron->getPlayer(1)->isComputer()) {
		Settings::setNamePlayer2(m_tron->getPlayer(1)->getName());
182
	}
Laurent Montel's avatar
Laurent Montel committed
183

184
	updateStatusbar();
Stephan Kulow's avatar
Stephan Kulow committed
185
186
}

187
188
void KTron::updateStatusbar() {
	QString message;
Laurent Montel's avatar
Laurent Montel committed
189

190
191
	if (!m_tron->running() && m_tron->hasWinner()) {
		QString winnerName = m_tron->getPlayer(m_tron->getWinner())->getName();
Laurent Montel's avatar
Laurent Montel committed
192

193
194
		message = i18n("%1 has won!", winnerName);
	}
195
	else if (m_tron->paused()) {
196
197
198
		message = i18n("Game paused");
	}
	else {
Laurent Montel's avatar
Laurent Montel committed
199
		message = QString();
200
	}
Laurent Montel's avatar
Laurent Montel committed
201

202
203
204
205
	statusBar()->showMessage(message);

	if (Settings::gameType() == Settings::EnumGameType::Snake)
	{
Laurent Montel's avatar
Laurent Montel committed
206
		QString string = QString::fromLatin1( "%1: %2").arg(m_tron->getPlayer(0)->getName()).arg(m_tron->getPlayer(0)->getScore());
207
208
209
210
211
		statusBar()->changeItem(string, ID_STATUS_BASE + 1);
		statusBar()->changeItem(QString(), ID_STATUS_BASE + 2);
	}
	else
	{
Stas Verberkt's avatar
Stas Verberkt committed
212
		for (int i = 0; i < 2; ++i) {
213
214
			QString name = m_tron->getPlayer(1 - i)->getName();
			int score = m_tron->getPlayer(1 - i)->getScore();
Laurent Montel's avatar
Laurent Montel committed
215
216

			QString string = QString::fromLatin1( "%1: %2").arg(name).arg(score);
217
218
219
			statusBar()->changeItem(string, ID_STATUS_BASE + i + 1);
		}
	}
220
221
}

222
223
224
void KTron::blockPause(bool block)
{
	//kDebug() << "Setting pause button state to: "  << !block;
225
	m_pauseButton->setEnabled(!block);
226
227
}

Stas Verberkt's avatar
Stas Verberkt committed
228
229
230
231
232
void KTron::updateScore()
{
	updateStatusbar();
}

233
void KTron::changeStatus() {
234
	updateStatusbar();
235

236
	if (Settings::gameType() == Settings::EnumGameType::Snake)
Stas Verberkt's avatar
Stas Verberkt committed
237
238
239
	{
		KScoreDialog scoreDialog(KScoreDialog::Score | KScoreDialog::Name, this);
		scoreDialog.addLocalizedConfigGroupNames(KGameDifficulty::localizedLevelStrings());
240
		scoreDialog.setConfigGroupWeights(KGameDifficulty::levelWeights());
Stas Verberkt's avatar
Stas Verberkt committed
241
242
243
		scoreDialog.setConfigGroup(KGameDifficulty::localizedLevelString());

		KScoreDialog::FieldInfo scoreInfo;
244
245
		scoreInfo[KScoreDialog::Name] = m_tron->getPlayer(0)->getName();
		scoreInfo[KScoreDialog::Score].setNum(m_tron->getPlayer(0)->getScore());
Stas Verberkt's avatar
Stas Verberkt committed
246
247
248
		if (scoreDialog.addScore(scoreInfo) != 0)
			scoreDialog.exec();
	}
249
250
251
}

void KTron::paletteChange(const QPalette &){
252
   update();
253
254
   m_tron->updatePixmap();
   m_tron->update();
255
256
}

257
/**
258
 * Show Settings dialog.
259
 */
260
void KTron::showSettings(){
Laurent Montel's avatar
Laurent Montel committed
261
	if (KConfigDialog::showDialog(QLatin1String( "settings" )))
Stas Verberkt's avatar
Stas Verberkt committed
262
		return;
Laurent Montel's avatar
Laurent Montel committed
263

264
	m_generalConfigDialog = new General();
Stas Verberkt's avatar
Stas Verberkt committed
265
266

	if (Settings::gameType() == Settings::EnumGameType::Snake) {
267
268
		m_generalConfigDialog->namePlayer1Label->setText(i18n("Player Name:"));
		m_generalConfigDialog->namePlayer2Label->setText(i18n("Opponent:"));
Stas Verberkt's avatar
Stas Verberkt committed
269
270
	}
	else {
271
272
		m_generalConfigDialog->namePlayer1Label->setText(i18n("Right Player:"));
		m_generalConfigDialog->namePlayer2Label->setText(i18n("Left Player:"));
Stas Verberkt's avatar
Stas Verberkt committed
273
274
	}

Laurent Montel's avatar
Laurent Montel committed
275
276
277
	KConfigDialog *dialog = new KConfigDialog(this, QLatin1String( "settings" ), Settings::self());
	dialog->addPage(m_generalConfigDialog, i18n("General"), QLatin1String( "games-config-options" ));
	dialog->addPage(new KGameThemeSelector(dialog, Settings::self(), KGameThemeSelector::NewStuffEnableDownload), i18n("Theme"), QLatin1String( "games-config-theme" ));
Laurent Montel's avatar
Laurent Montel committed
278
279
	connect(dialog, SIGNAL(settingsChanged(QString)), this, SLOT(loadSettings()));
	connect(dialog, SIGNAL(settingsChanged(QString)), m_tron, SLOT(loadSettings()));
Stas Verberkt's avatar
Stas Verberkt committed
280
	dialog->show();
Stephan Kulow's avatar
Stephan Kulow committed
281
282
}

Stas Verberkt's avatar
Stas Verberkt committed
283
284
285
286
287
288
/**
 * Show highscores
 */
void KTron::showHighscores() {
	KScoreDialog scoreDialog(KScoreDialog::Score | KScoreDialog::Name, this);
	scoreDialog.addLocalizedConfigGroupNames(KGameDifficulty::localizedLevelStrings());
289
	scoreDialog.setConfigGroupWeights(KGameDifficulty::levelWeights());
Stas Verberkt's avatar
Stas Verberkt committed
290
291
292
293
	scoreDialog.setConfigGroup( KGameDifficulty::localizedLevelString() );
	scoreDialog.exec();
}

294
295
296
297
298
299
300
301
302
303
304
305
306
/**
 * Close KTron
 */
void KTron::close() {
	Settings::self()->writeConfig();
}

void KTron::closeEvent(QCloseEvent *event)
{
    close();
    event->accept();
}

307
308
309
310
311
void KTron::optionsConfigureKeys()
{
    KShortcutsDialog::configure(actionCollection());
}

312
313
314
// Key events
void KTron::keyPressEvent(QKeyEvent *e)
{
315
	if (m_player0Accelerate->shortcuts().contains(e->key()))
316
317
318
	{
		triggerKey0Accelerate(true);
	}
319
	else if (m_player1Accelerate->shortcuts().contains(e->key()))
320
321
322
323
324
325
326
	{
		triggerKey1Accelerate(true);
	}
}

void KTron::keyReleaseEvent(QKeyEvent *e)
{
327
	if (m_player0Accelerate->shortcuts().contains(e->key()))
328
329
330
	{
		triggerKey0Accelerate(false);
	}
331
	else if (m_player1Accelerate->shortcuts().contains(e->key()))
332
333
334
335
336
	{
		triggerKey1Accelerate(false);
	}
}

337
// Triggers
338
339
void KTron::triggerKey0Up(bool b)
{
340
	m_tron->triggerKey(0, KBAction::UP, b);
341
342
343
344
}

void KTron::triggerKey0Down(bool b)
{
345
	m_tron->triggerKey(0, KBAction::DOWN, b);
346
347
348
349
}

void KTron::triggerKey0Left(bool b)
{
350
	m_tron->triggerKey(0, KBAction::LEFT, b);
351
352
353
354
}

void KTron::triggerKey0Right(bool b)
{
355
	m_tron->triggerKey(0, KBAction::RIGHT, b);
356
357
358
359
}

void KTron::triggerKey0Accelerate(bool b)
{
360
	m_tron->triggerKey(0, KBAction::ACCELERATE, b);
361
362
363
364
}

void KTron::triggerKey1Up(bool b)
{
365
	m_tron->triggerKey(1, KBAction::UP, b);
366
367
368
369
}

void KTron::triggerKey1Down(bool b)
{
370
	m_tron->triggerKey(1, KBAction::DOWN, b);
371
372
373
374
}

void KTron::triggerKey1Left(bool b)
{
375
	m_tron->triggerKey(1, KBAction::LEFT, b);
376
377
378
379
}

void KTron::triggerKey1Right(bool b)
{
380
	m_tron->triggerKey(1, KBAction::RIGHT, b);
381
382
383
384
}

void KTron::triggerKey1Accelerate(bool b)
{
385
	m_tron->triggerKey(1, KBAction::ACCELERATE, b);
386
387
}

388

Waldo Bastian's avatar
Waldo Bastian committed
389
#include "ktron.moc"
390