summaryrefslogtreecommitdiff
path: root/noncore/games/kpacman/referee.cpp
Unidiff
Diffstat (limited to 'noncore/games/kpacman/referee.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/kpacman/referee.cpp1426
1 files changed, 1426 insertions, 0 deletions
diff --git a/noncore/games/kpacman/referee.cpp b/noncore/games/kpacman/referee.cpp
new file mode 100644
index 0000000..567a8ed
--- a/dev/null
+++ b/noncore/games/kpacman/referee.cpp
@@ -0,0 +1,1426 @@
1
2#include "portable.h"
3
4#if defined( KDE2_PORT )
5#include <kapp.h>
6#include <kconfig.h>
7#include <kstddirs.h>
8#include <kaccel.h>
9#include <referee.h>
10#include <referee.moc>
11#elif defined( QPE_PORT )
12#include <qaccel.h>
13#include <qpe/qpeapplication.h>
14#include "config.h"
15#include "referee.h"
16#endif
17
18#include <qdatetm.h>
19#include <stdlib.h>
20#include <qtimer.h>
21#include <qevent.h>
22#include <qcolor.h>
23#include <qkeycode.h>
24#include <qfileinfo.h>
25
26#include "board.h"
27#include "pacman.h"
28#include "monster.h"
29#include "fruit.h"
30#include "painter.h"
31
32Referee::Referee( QWidget *parent, const char *name, int Scheme, int Mode, Bitfont *font)
33 : QWidget( parent, name )
34{
35 gameState.resize(12);
36 gameTimer = 0;
37 energizerTimer = 0;
38
39 focusedPause = FALSE;
40 setFocusPolicy(QWidget::StrongFocus);
41
42 initKeys();
43
44 scheme = Scheme;
45 mode = Mode;
46 confScheme();
47
48 board = new Board(BoardWidth*BoardHeight);
49
50 pix = new Painter(board, this, scheme, mode, font);
51 setFixedSize(pix->levelPix().size());
52
53 pacman = new Pacman(board);
54
55 fruit = new Fruit(board);
56
57 monsters = new QList<Monster>;
58 monsters->setAutoDelete(TRUE);
59
60 monsterRect = new QList<QRect>;
61 monsterRect->setAutoDelete(TRUE);
62
63 energizers = new QList<Energizer>;
64 energizers->setAutoDelete(TRUE);
65
66 energizerRect = new QList<QRect>;
67 energizerRect->setAutoDelete(TRUE);
68
69 pacmanRect.setRect(0, 0, 0, 0);
70 fruitRect.setRect(0, 0, 0, 0);
71
72 QTime midnight( 0, 0, 0 );
73 srand( midnight.secsTo(QTime::currentTime()) );
74
75 lifes = 0;
76 points = 0;
77
78 emit setLifes(lifes);
79 emit setPoints(points);
80
81 intro();
82}
83
84void Referee::paintEvent( QPaintEvent *e)
85{
86 if (gameState.testBit(HallOfFame))
87 return;
88
89 QRect rect = e->rect();
90
91 if (!rect.isEmpty()) {
92 QPixmap p = pix->levelPix();
93 bitBlt(this, rect.x(), rect.y(),
94 &p, rect.x(), rect.y(), rect.width(), rect.height());
95 }
96
97 if ((gameState.testBit(GameOver) || gameState.testBit(Demonstration)) &&
98 rect.intersects(pix->rect(board->position(fruithome), i18n("GAME OVER"))))
99 pix->draw(board->position(fruithome), Widget, i18n("GAME OVER"), RED);
100
101 for (Energizer *e = energizers->first(); e != 0; e = energizers->next()) {
102 if (e && e->state() == on &&
103 rect.intersects(pix->rect(e->position(), EnergizerPix)) &&
104 !(e->position() == pacman->position() && gameState.testBit(Scoring))) {
105 if (e->pix() != -1)
106 pix->draw(e->position(), Widget, EnergizerPix, e->pix());
107 }
108 }
109
110 if (!gameState.testBit(Init)) {
111
112 if (!gameState.testBit(Dying) && (fruit->pix() != -1))
113 if (fruit->state() != active) {
114 if (rect.intersects(pix->rect(fruit->position(), FruitScorePix, fruit->pix())))
115 pix->draw(fruit->position(), Widget, FruitScorePix, fruit->pix());
116 } else {
117 if (rect.intersects(pix->rect(fruit->position(), FruitPix, fruit->pix())))
118 pix->draw(fruit->position(), Widget, FruitPix, fruit->pix());
119 }
120
121 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
122 if (m && m->state() == harmless &&
123 rect.intersects(pix->rect(m->position(), MonsterPix)) &&
124 !(m->position() == pacman->position() && gameState.testBit(Scoring))) {
125 if (m->body() != -1)
126 pix->draw(m->position(), Widget, MonsterPix, m->body());
127 if (m->eyes() != -1)
128 pix->draw(m->position(), Widget, EyesPix, m->eyes());
129 }
130
131 if (!gameState.testBit(Scoring) && !gameState.testBit(LevelDone) &&
132 rect.intersects(pix->rect(pacman->position(), PacmanPix)) && pacman->pix() != -1)
133 pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix());
134
135 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
136 if (m && m->state() != harmless &&
137 rect.intersects(pix->rect(m->position(), MonsterPix)) &&
138 !(m->position() == pacman->position() && gameState.testBit(Scoring))) {
139 if (m->body() != -1)
140 pix->draw(m->position(), Widget, MonsterPix, m->body());
141 if (m->eyes() != -1)
142 pix->draw(m->position(), Widget, EyesPix, m->eyes());
143 }
144 }
145
146 if (gameState.testBit(Scoring) &&
147 rect.intersects(pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)))
148 pix->draw(pacman->position(), Widget, MonsterScorePix, monstersEaten-1);
149
150 if (gameState.testBit(Init) && gameState.testBit(Dying) &&
151 timerCount < pix->maxPixmaps(DyingPix) &&
152 rect.intersects(pix->rect(pacman->position(), PacmanPix)))
153 pix->draw(pacman->position(), Widget, DyingPix, timerCount);
154
155 if (gameState.testBit(LevelDone) &&
156 rect.intersects(pix->rect(pacman->position(), PacmanPix)))
157 pix->draw(pacman->position(), Widget, PacmanPix, pacman->pix());
158
159 if (gameState.testBit(Player) &&
160 rect.intersects(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE"))))
161 pix->draw(board->position(monsterhome, 0), Widget, i18n("PLAYER ONE"), CYAN);
162
163 if (gameState.testBit(Ready) &&
164 rect.intersects(pix->rect(board->position(fruithome), i18n("READY!"))))
165 pix->draw(board->position(fruithome), Widget, i18n("READY!"), YELLOW);
166
167 if (gameState.testBit(Paused) &&
168 rect.intersects(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED"))))
169 pix->draw((BoardWidth*BoardHeight)/2-BoardWidth, Widget, i18n("PAUSED"), RED, BLACK);
170}
171
172void Referee::timerEvent( QTimerEvent *e )
173{
174 if (gameState.testBit(HallOfFame))
175 return;
176
177 QRect lastRect;
178 int lastPix;
179 bool moved = FALSE;
180 int eated = 0;
181
182 if (e->timerId() == energizerTimer) {
183 for (int e = 0; e < board->energizers(); e++) {
184 lastRect = pix->rect(energizers->at(e)->position(), EnergizerPix);
185 lastPix = energizers->at(e)->pix();
186 if (energizers->at(e)->move()) {
187 moved = TRUE;
188 *energizerRect->at(e) = pix->rect(energizers->at(e)->position(), EnergizerPix);
189 if (lastPix == energizers->at(e)->pix() &&
190 lastRect == pix->rect(energizers->at(e)->position(), EnergizerPix))
191 energizerRect->at(e)->setRect(0, 0, 0, 0);
192 else
193 *energizerRect->at(e) = pix->rect(*energizerRect->at(e), lastRect);
194 }
195 }
196
197 for (int e = 0; e < board->energizers(); e++)
198 if (!energizerRect->at(e)->isNull())
199 repaint(*energizerRect->at(e), FALSE);
200
201 return;
202 }
203
204 timerCount++;
205
206 lastRect = pix->rect(pacman->position(), PacmanPix);
207 lastPix = pacman->pix();
208
209 if (moved = pacman->move()) { // pacman really moved
210 pacmanRect = pix->rect(pacman->position(), PacmanPix);
211 if (lastPix == pacman->pix() &&
212 lastRect == pix->rect(pacman->position(), PacmanPix))
213 pacmanRect.setRect(0, 0, 0, 0); // nothing to do, because the pixmap
214 else // and the position isn't changed.
215 pacmanRect = pix->rect(pacmanRect, lastRect);
216 } else
217 pacmanRect.setRect(0, 0, 0, 0);
218
219 int pos = pacman->position();
220
221 if (moved && board->isMonster(pos) && !gameState.testBit(Dying)) {
222 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
223 if (m && m->position() == pos) {
224 if (m->state() == harmless && !gameState.testBit(Dying)) {
225 m->setREM(remTicks[level]);
226 m->setDirection(X); // prevent movement before eaten()
227 eated++;
228 if (gameState.testBit(Introducing))
229 m->setPosition(OUT);
230 }
231 if (m->state() == dangerous && !gameState.testBit(Dying))
232 killed();
233 }
234 }
235
236 if (moved && !gameState.testBit(Dying)) {
237 if (board->isPoint(pos)) {
238 board->reset(pos, Point);
239 score(pointScore);
240 pix->erase(pos, PointPix);
241 }
242 if (board->isEnergizer(pos)) {
243 for (int e = 0; e < board->energizers();e++) {
244 if (energizers->at(e)->position() == pos) {
245 energizers->at(e)->setOff();
246 energizers->remove(e);
247 energizerRect->remove(e);
248 e = board->energizers();
249 }
250 }
251 board->reset(pos, energizer);
252 score(energizerScore);
253 monstersEaten = 0;
254 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
255 if (m && m->state() != rem) {
256 m->setHarmless(harmlessTicks[level], harmlessDurTicks[level],
257 harmlessWarnTicks[level]);
258 if (gameState.testBit(Introducing))
259 m->setDirection(board->turn(m->direction()));
260 }
261 }
262 if (pos == fruit->position() && fruit->state() == active) {
263 fruit->setEaten(fruitScoreDurTicks[level]);
264 initFruit(FALSE);
265 score(fruitScore[fruit->pix()]);
266 }
267 }
268
269 if (!gameState.testBit(Introducing)) {
270 if (fruit->state() != active && fruit->pix() >= 0)
271 lastRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
272 else
273 lastRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
274
275 lastPix = fruit->pix();
276 if (fruit->move()) {
277 if (pos == fruit->position() && fruit->state() == active) {
278 fruit->setEaten(fruitScoreDurTicks[level]);
279 initFruit(FALSE);
280 score(fruitScore[fruit->pix()]);
281 }
282 if (fruit->state() != active && fruit->pix() >= 0)
283 fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
284 else
285 fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
286 if (lastPix == fruit->pix() && lastRect == fruitRect)
287 fruitRect.setRect(0, 0, 0, 0);
288 else
289 fruitRect = pix->rect(fruitRect, lastRect);
290 } else
291 fruitRect.setRect(0, 0, 0, 0);
292 } else
293 fruitRect.setRect(0, 0, 0, 0);
294
295 int lastBodyPix;
296 int lastEyesPix;
297
298 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
299 if (m) {
300 lastRect = pix->rect(m->position(), MonsterPix);
301 lastBodyPix = m->body();
302 lastEyesPix = m->eyes();
303 if (m->move()) {
304 moved = TRUE;
305 *monsterRect->at(m->id()) = pix->rect(m->position(), MonsterPix);
306 if (lastBodyPix == m->body() && lastEyesPix == m->eyes() &&
307 lastRect == pix->rect(m->position(), MonsterPix))
308 monsterRect->at(m->id())->setRect(0, 0, 0, 0);
309 else
310 *monsterRect->at(m->id()) = pix->rect(*monsterRect->at(m->id()), lastRect);
311 if (m->position() == pos && !gameState.testBit(Dying)) {
312 if (m->state() == harmless && !gameState.testBit(Dying)) {
313 m->setREM(remTicks[level]);
314 eated++;
315 if (gameState.testBit(Introducing)) {
316 m->setPosition(OUT);
317 m->setDirection(X);
318 }
319 }
320 if (m->state() == dangerous && !gameState.testBit(Dying))
321 killed();
322 }
323 } else
324 monsterRect->at(m->id())->setRect(0, 0, 0, 0);
325 }
326
327 for (int m = 0; m < board->monsters(); m++)
328 if (pacmanRect.intersects(*monsterRect->at(m))) {
329 pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m));
330 monsterRect->at(m)->setRect(0, 0, 0, 0);
331 } else
332 for (int im = m+1; im < board->monsters(); im++)
333 if (monsterRect->at(m)->intersects(*monsterRect->at(im))) {
334 *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im));
335 monsterRect->at(im)->setRect(0, 0, 0, 0);
336 }
337
338 if (!pacmanRect.isNull())
339 repaint(pacmanRect, FALSE);
340
341 if (!fruitRect.isNull())
342 repaint(fruitRect, FALSE);
343
344 for (int m = 0; m < board->monsters(); m++)
345 if (!monsterRect->at(m)->isNull())
346 repaint(*monsterRect->at(m), FALSE);
347
348 if (board->points() == 0 && !gameState.testBit(Dying))
349 levelUp();
350
351 if (eated > 0 && !gameState.testBit(Dying)) {
352 timerCount = eated;
353 eaten();
354 }
355
356 if (gameState.testBit(Introducing) && moved)
357 introPlay();
358}
359
360void Referee::repaintFigures()
361{
362 pacmanRect = pix->rect(pacman->position(), PacmanPix);
363
364 for (int e = 0; e < board->energizers(); e++) {
365 *energizerRect->at(e) = pix->rect(board->position(energizer, e), EnergizerPix);
366
367 if (pacmanRect.intersects(*energizerRect->at(e))) {
368 pacmanRect = pix->rect(pacmanRect, *energizerRect->at(e));
369 energizerRect->at(e)->setRect(0, 0, 0, 0);
370 } else
371 for (int ie = e+1; ie < board->energizers(); ie++)
372 if (energizerRect->at(e)->intersects(*energizerRect->at(ie))) {
373 *energizerRect->at(e) = pix->rect(*energizerRect->at(e), *energizerRect->at(ie));
374 energizerRect->at(ie)->setRect(0, 0, 0, 0);
375 }
376 }
377
378 if (fruit->pix() != -1 && fruit->state() != active)
379 fruitRect = pix->rect(fruit->position(), FruitScorePix, fruit->pix());
380 else
381 fruitRect = pix->rect(fruit->position(), FruitPix, fruit->pix());
382
383 if (pacmanRect.intersects(fruitRect)) {
384 pacmanRect = pix->rect(pacmanRect, fruitRect);
385 fruitRect.setRect(0, 0, 0, 0);
386 }
387
388 for (int m = 0; m < board->monsters(); m++) {
389 *monsterRect->at(m) = pix->rect(board->position(monster, m), MonsterPix);
390
391 if (pacmanRect.intersects(*monsterRect->at(m))) {
392 pacmanRect = pix->rect(pacmanRect, *monsterRect->at(m));
393 monsterRect->at(m)->setRect(0, 0, 0, 0);
394 } else
395 for (int im = m+1; im < board->monsters(); im++)
396 if (monsterRect->at(m)->intersects(*monsterRect->at(im))) {
397 *monsterRect->at(m) = pix->rect(*monsterRect->at(m), *monsterRect->at(im));
398 monsterRect->at(im)->setRect(0, 0, 0, 0);
399 }
400 }
401
402 if (!pacmanRect.isNull())
403 repaint(pacmanRect, FALSE);
404
405 if (!fruitRect.isNull())
406 repaint(fruitRect, FALSE);
407
408 for (int m = 0; m < board->monsters(); m++)
409 if (!monsterRect->at(m)->isNull())
410 repaint(*monsterRect->at(m), FALSE);
411
412 for (int e = 0; e < board->energizers(); e++)
413 if (!energizerRect->at(e)->isNull())
414 repaint(*energizerRect->at(e), FALSE);
415
416}
417
418void Referee::initKeys()
419{
420 APP_CONFIG_BEGIN( cfg );
421 QString up("Up");
422 up = cfg->readEntry("upKey", (const char*) up);
423 UpKey = KAccel::stringToKey(up);
424
425 QString down("Down");
426 down = cfg->readEntry("downKey", (const char*) down);
427 DownKey = KAccel::stringToKey(down);
428
429 QString left("Left");
430 left = cfg->readEntry("leftKey", (const char*) left);
431 LeftKey = KAccel::stringToKey(left);
432
433 QString right("Right");
434 right = cfg->readEntry("rightKey", (const char*) right);
435 RightKey = KAccel::stringToKey(right);
436 APP_CONFIG_END( cfg );
437}
438
439void Referee::fillArray(QArray<int> &array, QString values, int max)
440{
441 if (max < 0)
442 max = values.contains(',')+1;
443
444 array.resize(max);
445 int last = 0;
446 bool ok;
447 QString value;
448
449 for (uint i = 0; i < array.size(); i++) {
450 if (values.find(',') < 0 && values.length() > 0) {
451 value = values;
452 values = "";
453 }
454 if (values.find(',') >= 0) {
455 value = values.left(values.find(','));
456 values.remove(0,values.find(',')+1);
457 }
458 array[i] = value.toInt(&ok);
459 if (ok)
460 last = array[i];
461 else
462 array[i] = last;
463 }
464}
465
466void Referee::fillStrList(QStrList &list, QString values, int max)
467{
468 if (!list.isEmpty())
469 list.clear();
470
471 QString last = "";
472 QString value;
473
474 for (uint i = 0; i < (uint) max; i++) {
475 if (values.find(',') < 0 && values.length() > 0) {
476 value = values;
477 values = "";
478 }
479 if (values.find(',') >= 0) {
480 value = values.left(values.find(','));
481 values.remove(0,values.find(',')+1);
482 }
483 if (!value.isEmpty())
484 last = value;
485
486 list.append(last);
487 }
488}
489
490void Referee::fillMapName()
491{
492 QStrList list = mapName;
493
494 if (!mapName.isEmpty())
495 mapName.clear();
496
497 QString map;
498
499 QFileInfo fileInfo;
500
501 for (uint i = 0; i < list.count(); i++) {
502 map = list.at(i);
503
504 if (map.left(1) != "/" && map.left(1) != "~")
505 map = FIND_APP_DATA( mapDirectory+map );
506
507 fileInfo.setFile(map);
508 if (!fileInfo.isReadable())
509 map = "";
510
511 mapName.append(map);
512 }
513}
514
515void Referee::confLevels(bool defGroup)
516{
517 APP_CONFIG_BEGIN( cfg );
518 if (defGroup || cfg->hasKey("Levels"))
519 maxLevel = cfg->readNumEntry("Levels", 13);
520 APP_CONFIG_END( cfg );
521}
522
523void Referee::confMisc(bool defGroup)
524{
525 APP_CONFIG_BEGIN( cfg );
526 if (defGroup || cfg->hasKey("PixmapDirectory")) {
527 pixmapDirectory = cfg->readEntry("PixmapDirectory");
528
529 if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
530 pixmapDirectory.insert(0, "pics/");
531 if (pixmapDirectory.right(1) != "/")
532 pixmapDirectory.append("/");
533 }
534
535 if (defGroup || cfg->hasKey("MapDirectory")) {
536 mapDirectory = cfg->readEntry("MapDirectory");
537
538 if (mapDirectory.left(1) != "/" && mapDirectory.left(1) != "~")
539 mapDirectory.insert(0, "maps/");
540 if (mapDirectory.right(1) != "/")
541 mapDirectory.append("/");
542 }
543
544 if (defGroup || cfg->hasKey("MapName"))
545 fillStrList(mapName, cfg->readEntry("MapName", "map"), maxLevel+1);
546
547 if (defGroup || cfg->hasKey("MonsterIQ"))
548 fillArray(monsterIQ, cfg->readEntry("MonsterIQ", "0,170,180,170,180,170,180"), maxLevel+1);
549 if (defGroup || cfg->hasKey("FruitIQ"))
550 fillArray(fruitIQ, cfg->readEntry("FruitIQ", "0,170,180,170,180,170,180"), maxLevel+1);
551 if (defGroup || cfg->hasKey("FruitIndex"))
552 fillArray(fruitIndex, cfg->readEntry("FruitIndex", "0"), maxLevel+1);
553 APP_CONFIG_END( cfg );
554}
555
556void Referee::confTiming(bool defGroup)
557{
558 APP_CONFIG_BEGIN( cfg );
559 if (defGroup || cfg->hasKey("SpeedMS"))
560 fillArray(speed, cfg->readEntry("SpeedMS", "20"), maxLevel+1);
561 if (defGroup || cfg->hasKey("PacmanTicks"))
562 fillArray(pacmanTicks,cfg->readEntry("PacmanTicks", "3"), maxLevel+1);
563 if (defGroup || cfg->hasKey("RemTicks"))
564 fillArray(remTicks, cfg->readEntry("RemTicks", "1"), maxLevel+1);
565 if (defGroup || cfg->hasKey("DangerousTicks"))
566 fillArray(dangerousTicks, cfg->readEntry("DangerousTicks", "3"), maxLevel+1);
567 if (defGroup || cfg->hasKey("HarmlessTicks"))
568 fillArray(harmlessTicks, cfg->readEntry("HarmlessTicks", "7,6,,5,,4"), maxLevel+1);
569 if (defGroup || cfg->hasKey("HarmlessDurationTicks"))
570 fillArray(harmlessDurTicks, cfg->readEntry("HarmlessDurationTicks", "375,,,300,,250,200,150"), maxLevel+1);
571 if (defGroup || cfg->hasKey("HarmlessWarningTicks"))
572 fillArray(harmlessWarnTicks, cfg->readEntry("HarmlessWarningTicks", "135"), maxLevel+1);
573 if (defGroup || cfg->hasKey("ArrestTicks"))
574 fillArray(arrestTicks, cfg->readEntry("ArrestTicks", "6"), maxLevel+1);
575 if (defGroup || cfg->hasKey("ArrestDurationTicks"))
576 fillArray(arrestDurTicks, cfg->readEntry("ArrestDurationTicks", "200,,,150"), maxLevel+1);
577 if (defGroup || cfg->hasKey("FruitTicks"))
578 fillArray(fruitTicks, cfg->readEntry("FruitTicks", "7,6,,5,,4"), maxLevel+1);
579 if (defGroup || cfg->hasKey("FruitAppearsTicks"))
580 fillArray(fruitAppearsTicks, cfg->readEntry("FruitAppearsTicks", "1000,,1500,2000,2500,3000,3500,4000"), maxLevel+1);
581 if (defGroup || cfg->hasKey("FruitDurationTicks"))
582 fillArray(fruitDurTicks, cfg->readEntry("FruitDurationTicks", "500,,,400,350,300,,250,200,150"), maxLevel+1);
583 if (defGroup || cfg->hasKey("FruitScoreDurationTicks"))
584 fillArray(fruitScoreDurTicks, cfg->readEntry("FruitScoreDurationTicks", "150"), maxLevel+1);
585
586 if (defGroup || cfg->hasKey("MonsterScoreDurationMS"))
587 monsterScoreDurMS = cfg->readNumEntry("MonsterScoreDurationMS", 1000);
588 if (defGroup || cfg->hasKey("PlayerDurationMS"))
589 playerDurMS = cfg->readNumEntry("PlayerDurationMS", 3000);
590 if (defGroup || cfg->hasKey("ReadyDurationMS"))
591 readyDurMS = cfg->readNumEntry("ReadyDurationMS", 2000);
592 if (defGroup || cfg->hasKey("GameOverDurationMS"))
593 gameOverDurMS = cfg->readNumEntry("GameOverDurationMS", 3000);
594 if (defGroup || cfg->hasKey("AfterPauseMS"))
595 afterPauseMS = cfg->readNumEntry("AfterPauseMS", 1000);
596 if (defGroup || cfg->hasKey("DyingPreAnimationMS"))
597 dyingPreAnimationMS = cfg->readNumEntry("DyingPreAnimationMS", 1000);
598 if (defGroup || cfg->hasKey("DyingAnimationMS"))
599 dyingAnimationMS = cfg->readNumEntry("DyingAnimationMS", 100);
600 if (defGroup || cfg->hasKey("DyingPostAnimationMS"))
601 dyingPostAnimationMS = cfg->readNumEntry("DyingPostAnimationMS", 500);
602 if (defGroup || cfg->hasKey("IntroAnimationMS"))
603 introAnimationMS = cfg->readNumEntry("IntroAnimationMS", 800);
604 if (defGroup || cfg->hasKey("IntroPostAnimationMS"))
605 introPostAnimationMS = cfg->readNumEntry("IntroPostAnimationMS", 1000);
606 if (defGroup || cfg->hasKey("LevelUpPreAnimationMS"))
607 levelUpPreAnimationMS = cfg->readNumEntry("LevelUpPreAnimationMS", 2000);
608 if (defGroup || cfg->hasKey("LevelUpAnimationMS"))
609 levelUpAnimationMS = cfg->readNumEntry("LevelUpAnimationMS", 2000);
610 if (defGroup || cfg->hasKey("EnergizerAnimationMS"))
611 energizerAnimationMS = cfg->readNumEntry("EnergizerAnimationMS", 200);
612 APP_CONFIG_END( cfg );
613}
614
615void Referee::confScoring(bool defGroup)
616{
617 APP_CONFIG_BEGIN( cfg );
618 if (defGroup || cfg->hasKey("PointScore"))
619 pointScore = cfg->readNumEntry("PointScore", 10);
620 if (defGroup || cfg->hasKey("EnergizerScore"))
621 energizerScore = cfg->readNumEntry("EnergizerScore", 50);
622 if (defGroup || cfg->hasKey("FruitScore"))
623 fillArray(fruitScore, cfg->readEntry("FruitScore", "100,300,500,,700,,1000,,2000,,3000,,5000"), maxLevel+1);
624 if (defGroup || cfg->hasKey("MonsterScore"))
625 fillArray(monsterScore, cfg->readEntry("MonsterScore", "200,400,800,1600"), 4);
626 if (defGroup || cfg->hasKey("ExtraLifeScore"))
627 fillArray(extraLifeScore, cfg->readEntry("ExtraLifeScore", "10000"), -1);
628 APP_CONFIG_END( cfg );
629}
630
631void Referee::confScheme()
632{
633 APP_CONFIG_BEGIN( cfg );
634 SAVE_CONFIG_GROUP( cfg, oldgroup );
635 QString newgroup;
636
637 // if not set, read mode and scheme from the configfile
638 if (mode == -1 && scheme == -1) {
639 scheme = cfg->readNumEntry("Scheme", -1);
640 mode = cfg->readNumEntry("Mode", -1);
641
642 // if mode is not set in the defGroup-group, lookup the scheme group
643 if (scheme != -1 || mode == -1) {
644 newgroup.sprintf("Scheme %d", scheme);
645 cfg->setGroup(newgroup);
646
647 mode = cfg->readNumEntry("Mode", -1);
648 RESTORE_CONFIG_GROUP( cfg, oldgroup );
649 }
650 }
651
652 confLevels();
653
654 if (mode != -1) {
655 newgroup.sprintf("Mode %d", mode);
656 cfg->setGroup(newgroup);
657
658 confLevels(FALSE);
659 }
660
661 if (scheme != -1) {
662 newgroup.sprintf("Scheme %d", scheme);
663 cfg->setGroup(newgroup);
664
665 confLevels(FALSE);
666 }
667
668 RESTORE_CONFIG_GROUP( cfg, oldgroup );
669
670 confMisc();
671 confTiming();
672 confScoring();
673
674 if (mode != -1) {
675 newgroup.sprintf("Mode %d", mode);
676 cfg->setGroup(newgroup);
677
678 confMisc(FALSE);
679 confTiming(FALSE);
680 confScoring(FALSE);
681 }
682
683 if (scheme != -1) {
684 newgroup.sprintf("Scheme %d", scheme);
685 cfg->setGroup(newgroup);
686
687 confMisc(FALSE);
688 confTiming(FALSE);
689 confScoring(FALSE);
690 }
691
692 fillMapName();
693
694 RESTORE_CONFIG_GROUP( cfg, oldgroup );
695 APP_CONFIG_END( cfg );
696}
697
698void Referee::setScheme(int Scheme, int Mode, Bitfont *font)
699{
700 mode = Mode;
701 scheme = Scheme;
702
703 confScheme();
704
705 pix->setScheme(scheme, mode, font);
706
707 pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix));
708 fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix));
709
710 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
711 if (m)
712 m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
713
714 for (Energizer *e = energizers->first(); e != 0; e = energizers->next())
715 if (e)
716 e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix));
717
718 if (gameState.testBit(Introducing))
719 for (int i = 0; i < (gameState.testBit(Init) ? timerCount : 15); i++)
720 introPaint(i);
721
722 setFixedSize(pix->levelPix().size());
723 repaint();
724}
725
726void Referee::keyPressEvent( QKeyEvent *k )
727{
728 uint key = k->key();
729#ifdef QWS
730 // "OK" => new game
731 if ( key == Key_F33 || key == Key_F2 || key == Key_Enter )
732 play();
733 else if ( !gameState.testBit(Playing) && key == Key_Space )
734 play();
735 // "Space" => pause
736 //else if ( key == Key_Space || key == Key_F3 )
737 // pause();
738 // "Menu" => hall of fame
739 //else if ( key == Key_F11 || key == Key_F4 )
740 // toggleHallOfFame();
741#endif
742
743 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame) ||
744 gameState.testBit(Demonstration) || gameState.testBit(Dying) ||
745 gameState.testBit(Ready) || gameState.testBit(LevelDone) ||
746 !gameState.testBit(Playing))
747 return;
748
749 if (key == UpKey)
750 pacman->setDirection(N);
751 else if (key == DownKey)
752 pacman->setDirection(S);
753 else if (key == RightKey)
754 pacman->setDirection(E);
755 else if (key == LeftKey)
756 pacman->setDirection(W);
757
758#ifdef CHEATS
759 else if (key == Key_L) { printf("levelUp()\n"); levelUp(); }
760 else if (key == Key_F) { printf("fruit->move(TRUE)\n"); fruit->move(TRUE); repaint(FALSE); }
761 else if (key == Key_E) { printf("setLifes(++lifes)\n"); emit setLifes(++lifes); }
762#endif
763
764 else {
765 k->ignore();
766 return;
767 }
768 k->accept();
769}
770
771void Referee::score(int p)
772{
773 if (!gameState.testBit(Playing))
774 return;
775
776 if ((points += p) < 0)
777 points = 0;
778
779 emit setPoints(points);
780
781 if (points >= nextExtraLifeScore) {
782 emit setLifes(++lifes);
783 if (extraLifeScoreIndex < (int) extraLifeScore.size()-1)
784 extraLifeScoreIndex++;
785 if (extraLifeScore[extraLifeScoreIndex] < 0)
786 nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex] * -1;
787 else
788 nextExtraLifeScore += extraLifeScore[extraLifeScoreIndex];
789 }
790}
791
792void Referee::eaten()
793{
794 if (gameState.testBit(Ready))
795 return;
796
797 stop();
798
799 if (monstersEaten < 4)
800 monstersEaten++;
801
802 gameState.setBit(Scoring);
803 score(monsterScore[monstersEaten-1]);
804
805 repaint(pix->rect(pix->rect(pacman->position(), MonsterPix),
806 pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)));
807
808 if (--timerCount > 0)
809 QTimer::singleShot( monsterScoreDurMS, this, SLOT(eaten()));
810 else {
811 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
812 if (m && m->direction() == X && !gameState.testBit(Introducing))
813 m->setDirection(N);
814 if (monstersEaten != 4 || !gameState.testBit(Introducing))
815 QTimer::singleShot( monsterScoreDurMS, this, SLOT(start()));
816 }
817}
818
819void Referee::toggleHallOfFame()
820{
821 gameState.toggleBit(HallOfFame);
822}
823
824void Referee::hallOfFame()
825{
826 if (gameState.testBit(HallOfFame)) // If the HallOfFame is switched on manually, toggle the
827 toggleHallOfFame(); // bit twice.
828
829 emit setLevel(0); // Clear status display for hall of fame
830 emit setScore(level, 0);
831 emit forcedHallOfFame(TRUE);
832}
833
834void Referee::pause()
835{
836 static int pausedTimer = 0;
837
838 if (!gameState.testBit(Paused)) {
839 pausedTimer = gameTimer;
840 stop();
841 stopEnergizer();
842 gameState.setBit(Paused);
843 repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")), FALSE);
844 } else {
845 gameState.clearBit(Paused);
846 repaint(pix->rect((BoardWidth*BoardHeight)/2-BoardWidth, i18n("PAUSED")), FALSE);
847 if (pausedTimer) {
848 pausedTimer = 0;
849 start();
850 }
851 }
852 emit togglePaused();
853}
854
855void Referee::intro()
856{
857 stop();
858 stopEnergizer();
859 bool paused = gameState.testBit(Paused);
860
861 gameState.fill(FALSE);
862 gameState.setBit(Introducing);
863 gameState.setBit(Init);
864
865 if (paused)
866 gameState.setBit(Paused);
867
868 level = 0;
869 emit setLevel(level);
870
871 board->init(Intro);
872 pix->setLevel(level);
873
874 initPacman();
875 initFruit();
876 initMonsters();
877 initEnergizers();
878
879 repaint();
880
881 monstersEaten = 0;
882 timerCount = 0;
883 introPlay();
884}
885
886void Referee::introMonster(int id)
887{
888 Monster *m = new Monster(board, id);
889
890 m->setPosition((10+id*6)*BoardWidth+10);
891 m->setDirection(E);
892 m->setDangerous(dangerousTicks[level], monsterIQ[level]);
893 m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
894
895 if (m->body() != -1)
896 pix->draw(m->position(), RoomPix, MonsterPix, m->body());
897 if (m->eyes() != -1)
898 pix->draw(m->position(), RoomPix, EyesPix, m->eyes());
899
900 repaint(pix->rect(m->position(), MonsterPix), FALSE);
901 m->setPosition(OUT);
902}
903
904void Referee::introPaint(int t)
905{
906 QString pts;
907
908 switch (t) {
909 case 0 : repaint(pix->draw(16, 6, RoomPix, i18n("CHARACTER"), WHITE, QColor(), AlignLeft), FALSE);
910 repaint(pix->draw(36, 6, RoomPix, i18n("/"), WHITE, QColor(), AlignLeft), FALSE);
911 repaint(pix->draw(40, 6, RoomPix, i18n("NICKNAME"), WHITE, QColor(), AlignLeft), FALSE);
912 break;
913 case 1 : introMonster(0);
914 break;
915 case 2 : repaint(pix->draw(16, 10, RoomPix, i18n("-SHADOW"), RED, QColor(), AlignLeft), FALSE);
916 break;
917 case 3 : repaint(pix->draw(38, 10, RoomPix, i18n("\"BLINKY\""), RED, QColor(), AlignLeft), FALSE);
918 break;
919 case 4 : introMonster(1);
920 break;
921 case 5 : repaint(pix->draw(16, 16, RoomPix, i18n("-SPEEDY"), PINK, QColor(), AlignLeft), FALSE);
922 break;
923 case 6 : repaint(pix->draw(38, 16, RoomPix, i18n("\"PINKY\""), PINK, QColor(), AlignLeft), FALSE);
924 break;
925 case 7 : introMonster(2);
926 break;
927 case 8 : repaint(pix->draw(16, 22, RoomPix, i18n("-BASHFUL"), CYAN, QColor(), AlignLeft), FALSE);
928 break;
929 case 9 : repaint(pix->draw(38, 22, RoomPix, i18n("\"INKY\""), CYAN, QColor(), AlignLeft), FALSE);
930 break;
931 case 10 : introMonster(3);
932 break;
933 case 11 : repaint(pix->draw(16, 28, RoomPix, i18n("-POKEY"), ORANGE, QColor(), AlignLeft), FALSE);
934 break;
935 case 12 : repaint(pix->draw(38, 28, RoomPix, i18n("\"CLYDE\""), ORANGE, QColor(), AlignLeft), FALSE);
936 break;
937 case 13 : pts.sprintf("%d", pointScore);
938 repaint(pix->draw(28, 44, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE);
939 repaint(pix->draw(31, 44, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE);
940 pts.sprintf("%d", energizerScore);
941 repaint(pix->draw(28, 48, RoomPix, pts.data(), WHITE, QColor(), AlignRight), FALSE);
942 repaint(pix->draw(31, 48, RoomPix, "\x1C\x1D\x1E", WHITE, QColor(), AlignLeft), FALSE);
943 break;
944 case 14 : // "@ 1980 MIDWAY MFG.CO."
945#if defined( KDE2_PORT )
946 repaint(pix->draw(30, 58, RoomPix, "© 1998-2002 J.THÖNNISSEN", PINK), FALSE);
947#elif defined( QPE_PORT )
948 repaint(pix->draw(30, 55, RoomPix, "© 1998-2002 J.THÖNNISSEN", PINK), FALSE);
949 repaint(pix->draw(29, 60, RoomPix, "Qtopia port: Catalin CLIMOV", GREEN), FALSE);
950#endif
951 break;
952 }
953}
954
955void Referee::introPlay()
956{
957 if (!gameState.testBit(Introducing) || gameState.testBit(Ready))
958 return;
959 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
960 QTimer::singleShot(afterPauseMS, this, SLOT(introPlay()));
961 return;
962 }
963
964 if (!gameState.testBit(Init)) {
965 if (monstersEaten == 4) {
966 stop();
967 QTimer::singleShot(introPostAnimationMS, this, SLOT(demo()));
968 }
969 if (pacman->direction() == W) {
970 int id = -1;
971 if (pacman->position() == 37*BoardWidth-6)
972 id = 0;
973 else
974 if (board->isMonster(37*BoardWidth-6))
975 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
976 if (m && m->position() == 37*BoardWidth-6) {
977 id = m->id();
978 id++;
979 break;
980 }
981
982 if (id >= 0 && id <= 4)
983 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
984 if (m && m->id() == id && m->position() == OUT) {
985 m->setPosition(37*BoardWidth-1);
986 m->setDirection(W);
987 m->setDangerous(dangerousTicks[level], monsterIQ[level]);
988 board->set(37*BoardWidth-1, monsterhome, id);
989 repaint(pix->rect(m->position(), MonsterPix));
990 break;
991 }
992 }
993 return;
994 }
995
996 if (timerCount < 15)
997 introPaint(timerCount);
998
999 switch (timerCount) {
1000 case 13 : board->set(44*BoardWidth+22, Point);
1001 pix->drawPoint(44*BoardWidth+22);
1002 repaint(pix->rect(44*BoardWidth+22, PointPix), FALSE);
1003 energizers->at(0)->setPosition(48*BoardWidth+22);
1004 energizers->at(0)->setOn();
1005 repaint(pix->rect(48*BoardWidth+22, EnergizerPix), FALSE);
1006 break;
1007 case 14 : energizers->at(1)->setPosition(36*BoardWidth+10);
1008 energizers->at(1)->setOn();
1009 repaint(pix->rect(36*BoardWidth+10, EnergizerPix), FALSE);
1010 for (int pos = 8; pos < BoardWidth; pos++) {
1011 board->set(34*BoardWidth+pos, out);
1012 board->set(38*BoardWidth+pos, out);
1013 }
1014 board->set(36*BoardWidth+8, out);
1015 break;
1016 case 15 : gameState.clearBit(Init);
1017 initPacman();
1018 pacman->setDemo(TRUE);
1019 pacman->setPosition(37*BoardWidth-1);
1020 repaintFigures();
1021 start();
1022 return;
1023 }
1024
1025 if (timerCount++ < 15)
1026 QTimer::singleShot(introAnimationMS, this, SLOT(introPlay()));
1027}
1028
1029void Referee::demo()
1030{
1031 if (gameState.testBit(Ready))
1032 return;
1033
1034 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1035 QTimer::singleShot(afterPauseMS, this, SLOT(demo()));
1036 return;
1037 }
1038
1039 stop();
1040 stopEnergizer();
1041
1042 gameState.fill(FALSE);
1043 gameState.setBit(Init);
1044 gameState.setBit(Demonstration);
1045
1046 level = 0;
1047 emit setLevel(level);
1048
1049 board->init(Demo, mapName.at(0));
1050 pix->setLevel(level);
1051
1052 initPacman();
1053 initFruit();
1054 initMonsters();
1055 initEnergizers();
1056
1057 gameState.clearBit(Init);
1058
1059 repaint();
1060
1061 timerCount = 0;
1062 QTimer::singleShot(playerDurMS, this, SLOT(start()));
1063}
1064
1065void Referee::play()
1066{
1067 stop();
1068 stopEnergizer();
1069
1070 gameState.fill(FALSE);
1071 gameState.setBit(Init);
1072 gameState.setBit(Playing);
1073 gameState.setBit(Player);
1074 gameState.setBit(Ready);
1075
1076 lifes = 3;
1077 level = 1;
1078 points = 0;
1079
1080 extraLifeScoreIndex = 0;
1081 nextExtraLifeScore = extraLifeScore[extraLifeScoreIndex];
1082 if (nextExtraLifeScore < 0)
1083 nextExtraLifeScore *= -1;
1084
1085 board->init(Level, mapName.at(level));
1086 pix->setLevel(level);
1087
1088 initPacman();
1089 initFruit();
1090 initMonsters();
1091 initEnergizers();
1092
1093 repaint();
1094 emit toggleNew();
1095 emit setLifes(lifes);
1096 emit setLevel(level);
1097 emit setPoints(points);
1098
1099 repaint(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")), FALSE);
1100 repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
1101
1102 timerCount = 0;
1103 QTimer::singleShot(playerDurMS, this, SLOT(ready()));
1104}
1105
1106void Referee::ready()
1107{
1108 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1109 QTimer::singleShot(afterPauseMS, this, SLOT(ready()));
1110 return;
1111 }
1112
1113 if (gameState.testBit(Player)) {
1114 emit setLifes(--lifes);
1115 gameState.clearBit(Player);
1116 gameState.clearBit(Init);
1117 repaint(pix->rect(board->position(monsterhome, 0), i18n("PLAYER ONE")), FALSE);
1118 repaintFigures();
1119 QTimer::singleShot(playerDurMS, this, SLOT(ready()));
1120 return;
1121 }
1122
1123 if (gameState.testBit(Ready)) {
1124 gameState.clearBit(Ready);
1125 repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
1126 start();
1127 } else {
1128 gameState.setBit(Ready);
1129 gameState.clearBit(Init);
1130 repaint(pix->rect(board->position(fruithome), i18n("READY!")), FALSE);
1131 QTimer::singleShot(readyDurMS, this, SLOT(ready()));
1132 }
1133}
1134
1135
1136void Referee::levelUp()
1137{
1138 stop();
1139 stopEnergizer();
1140
1141 gameState.setBit(LevelDone);
1142 pacman->setPosition(pacman->position()); // set mouthPosition to "0"
1143 repaint(pix->rect(pacman->position(), PacmanPix));
1144
1145 timerCount = 0;
1146 QTimer::singleShot(levelUpPreAnimationMS, this, SLOT(levelUpPlay()));
1147}
1148
1149void Referee::levelUpPlay()
1150{
1151 if (gameState.testBit(Ready))
1152 return;
1153
1154 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1155 QTimer::singleShot(afterPauseMS, this, SLOT(levelUpPlay()));
1156 return;
1157 }
1158
1159 switch (timerCount) {
1160 case 0 : gameState.setBit(Init);
1161 setOnEnergizers();
1162 repaintFigures();
1163 break;
1164 case 1 : gameState.clearBit(LevelDone);
1165 repaint(pix->rect(pacman->position(), PacmanPix));
1166 break;
1167 }
1168
1169 if (timerCount++ < 2) {
1170 QTimer::singleShot(levelUpAnimationMS, this, SLOT(levelUpPlay()));
1171 return;
1172 }
1173
1174 gameState.clearBit(Init);
1175
1176 if (gameState.testBit(Demonstration)) {
1177 hallOfFame();
1178 return;
1179 }
1180
1181 if (level < maxLevel)
1182 level++;
1183
1184 board->init(Level, mapName.at(level));
1185 pix->setLevel(level);
1186
1187 initPacman();
1188 initFruit();
1189 initMonsters();
1190 initEnergizers();
1191
1192 repaint();
1193 emit setLevel(level);
1194
1195 ready();
1196}
1197
1198void Referee::start()
1199{
1200 if (gameState.testBit(Ready))
1201 return;
1202
1203 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1204 QTimer::singleShot(afterPauseMS, this, SLOT(start()));
1205 return;
1206 }
1207
1208 if (gameState.testBit(Scoring)) {
1209 gameState.clearBit(Scoring);
1210 repaint(pix->rect(pix->rect(pacman->position(), MonsterPix),
1211 pix->rect(pacman->position(), MonsterScorePix, monstersEaten-1)));
1212 }
1213
1214 if (!gameTimer)
1215 gameTimer = startTimer( speed [level] );
1216
1217 if (!energizerTimer)
1218 energizerTimer = startTimer( energizerAnimationMS );
1219}
1220
1221void Referee::start(int t)
1222{
1223 gameTimer = startTimer(t);
1224}
1225
1226void Referee::stop()
1227{
1228 if (gameTimer) {
1229 killTimer (gameTimer);
1230 gameTimer = 0;
1231 }
1232}
1233
1234void Referee::stopEnergizer()
1235{
1236 if (energizerTimer) {
1237 killTimer (energizerTimer);
1238 energizerTimer = 0;
1239 }
1240}
1241
1242void Referee::killed()
1243{
1244 if (gameState.testBit(Ready))
1245 return;
1246
1247 if (!gameState.testBit(Dying)) {
1248 gameState.setBit(Dying);
1249
1250 pacman->setDirection(X, TRUE);
1251 for (Monster *m = monsters->first(); m != 0; m = monsters->next())
1252 if (m)
1253 m->setDirection(X);
1254 QTimer::singleShot(dyingPreAnimationMS, this, SLOT(killed()));
1255 } else {
1256 stop();
1257 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1258 QTimer::singleShot(afterPauseMS, this, SLOT(killed()));
1259 return;
1260 }
1261
1262 gameState.setBit(Init);
1263
1264 repaintFigures();
1265
1266 timerCount = 0;
1267 killedPlay();
1268 }
1269}
1270
1271void Referee::killedPlay()
1272{
1273 if (!gameState.testBit(Dying) || gameState.testBit(Ready))
1274 return;
1275 if (gameState.testBit(Paused) || gameState.testBit(HallOfFame)) {
1276 QTimer::singleShot(afterPauseMS, this, SLOT(killedPlay()));
1277 return;
1278 }
1279
1280 if (timerCount <= pix->maxPixmaps(DyingPix)) {
1281 repaint(pix->rect(pacman->position(), PacmanPix), FALSE);
1282 if (timerCount >= pix->maxPixmaps(DyingPix)-1 || timerCount == 0)
1283 QTimer::singleShot(dyingPostAnimationMS, this, SLOT(killedPlay()));
1284 else
1285 QTimer::singleShot(dyingAnimationMS, this, SLOT(killedPlay()));
1286 timerCount++;
1287 } else {
1288 gameState.clearBit(Dying);
1289 stopEnergizer();
1290 if (lifes == 0) {
1291 gameState.setBit(GameOver);
1292 gameState.clearBit(Playing);
1293 for (int e = 0; e < board->energizers(); e++) {
1294 energizers->at(e)->setOff();
1295 repaint(pix->rect(board->position(energizer, e), EnergizerPix), FALSE);
1296 }
1297 repaint(pix->rect(board->position(fruithome), i18n("GAME OVER")), FALSE);
1298 QTimer::singleShot(gameOverDurMS, this, SLOT(hallOfFame()));
1299 } else {
1300 gameState.clearBit(Init);
1301 initPacman();
1302 initFruit();
1303 initMonsters();
1304 initEnergizers();
1305 emit setLifes(--lifes);
1306 repaintFigures();
1307 ready();
1308 }
1309 }
1310}
1311
1312void Referee::initPacman()
1313{
1314 pacman->setMaxPixmaps(pix->maxPixmaps(PacmanPix));
1315 pacman->setDemo(gameState.testBit(Demonstration));
1316 pacman->setPosition(board->position(pacmanhome));
1317 pacman->setDirection(W, TRUE);
1318 pacman->setAlive(pacmanTicks[level]);
1319}
1320
1321void Referee::initFruit(bool fullInitialization)
1322{
1323 if (fullInitialization) {
1324 fruit->setMaxPixmaps(pix->maxPixmaps(FruitPix));
1325 if (fruitIndex[level] == 0)
1326 fruit->setLevel(level, fruitAppearsTicks[level],
1327 fruitDurTicks[level], fruitTicks[level]);
1328 else if (fruitIndex[level] < 0)
1329 fruit->setLevel(pix->maxPixmaps(FruitPix)+1,
1330 fruitAppearsTicks[level],
1331 fruitDurTicks[level], fruitTicks[level]);
1332 else
1333 fruit->setLevel(fruitIndex[level], fruitAppearsTicks[level],
1334 fruitDurTicks[level], fruitTicks[level]);
1335 }
1336
1337 if (board->tunnels() > 0)
1338 fruit->setMovement(board->position(tunnel, rand() % board->tunnels()),
1339 board->position(tunnel, rand() % board->tunnels()),
1340 fruitIQ[level]);
1341}
1342
1343void Referee::initMonsters()
1344{
1345 if( !monsters->isEmpty())
1346 monsters->clear();
1347 if( !monsterRect->isEmpty())
1348 monsterRect->clear();
1349
1350 for (int id = 0; id < (gameState.testBit(Introducing) ? 4 : board->monsters()); id++) {
1351 Monster *m = new Monster(board, id);
1352 monsters->append(m);
1353 QRect *r = new QRect();
1354 monsterRect->append(r);
1355 if (!gameState.testBit(Introducing)) {
1356 m->setFreedom(board->position(prisonexit));
1357 m->setDangerous(dangerousTicks[level], monsterIQ[level]);
1358 if (id == 0)
1359 m->setPrison(board->position(prisonentry));
1360 else {
1361 m->setPrison(board->position(monsterhome, id));
1362 m->setArrested(arrestTicks[level], arrestDurTicks[level]*id);
1363 }
1364 m->setPosition(board->position(monsterhome, id));
1365 switch(id) {
1366 case 0 : m->setDirection(W); break;
1367 case 1 : m->setDirection(N); break;
1368 default : m->setDirection(S);
1369 }
1370 }
1371 m->setMaxPixmaps(pix->maxPixmaps(MonsterPix), pix->maxPixmaps(EyesPix));
1372 }
1373}
1374
1375void Referee::initEnergizers()
1376{
1377 if( !energizers->isEmpty())
1378 energizers->clear();
1379 if( !energizerRect->isEmpty())
1380 energizerRect->clear();
1381
1382 for (int id = 0; id < (gameState.testBit(Introducing) ? 2 : board->energizers()); id++) {
1383 Energizer *e = new Energizer(board);
1384 energizers->append(e);
1385 QRect *r = new QRect();
1386 energizerRect->append(r);
1387 if (!gameState.testBit(Introducing)) {
1388 e->setPosition(board->position(energizer, id));
1389 e->setOn();
1390 }
1391 e->setMaxPixmaps(pix->maxPixmaps(EnergizerPix));
1392 }
1393}
1394
1395void Referee::setOnEnergizers()
1396{
1397 for (int e = 0; e < board->energizers(); e++) {
1398 energizers->at(e)->setOn();
1399 }
1400}
1401
1402void Referee::setFocusOutPause(bool FocusOutPause)
1403{
1404 focusOutPause = FocusOutPause;
1405}
1406
1407void Referee::setFocusInContinue(bool FocusInContinue)
1408{
1409 focusInContinue = FocusInContinue;
1410}
1411
1412void Referee::focusInEvent(QFocusEvent *)
1413{
1414 if (focusInContinue && focusedPause &&
1415 gameState.testBit(Paused) && gameState.testBit(Playing)) {
1416 pause();
1417 }
1418}
1419
1420void Referee::focusOutEvent(QFocusEvent *)
1421{
1422 if (focusOutPause && !gameState.testBit(Paused) && gameState.testBit(Playing)) {
1423 focusedPause = TRUE;
1424 pause();
1425 }
1426}