Lowers speeds on the hardest new levels.
[ghostsoverboard] / seascene.cpp
1 /**************************************************************************
2         Ghosts Overboard - a game for 'Meego 1.2 Harmattan'
3
4         Copyright (C) 2011  Heli Hyvättinen
5
6         This file is part of Ghosts Overboard
7
8         Ghosts Overboard is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 2 of the License, or
11         (at your option) any later version.
12
13         This program is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 **************************************************************************/
22
23 #include "seascene.h"
24 #include "octopus.h"
25 #include "ship.h"
26 #include <QGraphicsPixmapItem>
27 #include <QDebug>
28 #include <QMessageBox>
29 #include <QTime>
30 #include <QApplication>
31 #include <QAction>
32 #include <QPushButton>
33 #include <QLabel>
34 #include <QVBoxLayout>
35 #include <QSettings>
36 #include <QPixmap>
37
38
39 const QString ghostImageFilename_ = ":/pix/aave.png";
40 const QString rockImageFilename_ =":/pix/kari.png";
41 const QString octopusImageFilename_= ":/pix/tursas.png";
42
43
44 SeaScene::SeaScene(QObject *parent) :
45     QGraphicsScene(parent)
46 {
47
48     setItemPointersNull();
49
50     paused_ = false;
51     screenLitKeeper_.keepScreenLit(true);
52
53     //set background
54
55     QPixmap waves (":/pix/meri.png");
56     waves.scaled(20,20);
57     setBackgroundBrush(QBrush(waves));
58
59     //set random seed
60
61     qsrand(QTime::currentTime().msec()+2);  //+2 to avoid setting it to 1
62
63
64
65 //Setup the level list
66
67     QList<Level> levelList;
68     Level level1(5,10);
69     levelList.append(level1);
70     Level level2(5,10,2,50);
71     levelList.append(level2);
72     Level level3(5,15,2,50);
73     levelList.append(level3);
74     Level level4(5,15,4,50);
75     levelList.append(level4);
76     Level level5(5,15,5,100);
77     levelList.append(level5);
78
79     Levelset set ("Original",levelList);
80     levelset_ = set;
81     availableLevelsets_.append(set);
82
83     currentLevel_ = 0;
84
85     totalScore_ = 0;
86
87    //Create another set of levels and place it in the available levelsets list
88     levelList.clear();
89     Level set2level1(8,15,4,50);
90     levelList.append(set2level1);
91     Level set2level2(8,20,4,50);
92     levelList.append(set2level2);
93     Level set2level3(8,20,5,80);
94     levelList.append(set2level3);
95     Level set2level4(8,20,6,120);
96     levelList.append(set2level4);
97     Level set2level5(8,25,8,150);
98     levelList.append(set2level5);
99
100     Levelset set2("Difficult",levelList);
101     availableLevelsets_.append(set2);
102
103
104     //This ensures that nextlevel will not be called until its safe to delete the Ship object.
105     //Leaving out Qt::QueuedConnection or calling nextlevel directly instead of emitting the signal will CRASH
106     connect(this,SIGNAL(allGhostsPicked()),this,SLOT(nextLevel()),Qt::QueuedConnection);
107
108
109
110
111     pVibrateAction_ = new QAction(tr("Vibration effects"),this);
112     pVibrateAction_->setCheckable(true);
113     connect(pVibrateAction_,SIGNAL(toggled(bool)),this,SLOT(vibrationActivate(bool)));
114     QSettings settings;
115     pVibrateAction_->setChecked(settings.value("vibration",false).toBool());
116
117
118     pPauseAction_ = new QAction(tr("Pause"),this);
119     pPauseAction_->setCheckable(true);
120     connect(pPauseAction_,SIGNAL(toggled(bool)),this,SLOT(pause(bool)));
121
122
123     autopauseTimer.setSingleShot(true);
124     autopauseTimer.setInterval(15*60*1000);
125     connect(&autopauseTimer,SIGNAL(timeout()),this,SLOT(turnPauseOn()));
126
127     vibrationAllowed_ = false;
128     pResourceSet_ = new ResourcePolicy::ResourceSet("game",this);
129     ResourcePolicy::VibraResource * pVibraResource = new ResourcePolicy::VibraResource();
130     pVibraResource->setOptional(false); //The only resource of the set, so no sense for it to be optional
131     pResourceSet_->addResourceObject(pVibraResource);
132
133     connect(pResourceSet_,SIGNAL(resourcesGranted(const QList< ResourcePolicy::ResourceType >)),this,SLOT(resourcesAvailable()));
134     connect(pResourceSet_,SIGNAL(lostResources()),this,SLOT(resourcesLost()));
135
136     //To test whether resources were succesfully asked but not given
137     connect(pResourceSet_,SIGNAL(resourcesDenied()),this,SLOT(resourcesLost()));
138     pResourceSet_->setAlwaysReply();
139
140     pResourceSet_->acquire();
141
142 }
143
144 void SeaScene::setupMap(int ghosts, int rocks, int octopuses, int octopusSpeed)
145 {
146     //empty the map
147
148     clear();
149
150     setItemPointersNull();
151
152     createMenuItems();
153
154     createAboutBoxItems();
155
156     createSelectLevelsetFromListItems();
157
158     createVictoryItems();
159
160     createLevelCompletedItems();
161
162
163     //empty the list of moving items
164
165     movingItems_.clear();
166
167     //empty the list of free slots
168     freeTiles_.clear();
169
170     //fill the list of free slots
171
172     int numberOfXTiles  = width() / 40;
173     int numberOfYTiles = height() /40;
174
175 //    qDebug() << numberOfXTiles << " slots in x direction";
176 //    qDebug() << numberOfYTiles << " slots in y rirection";
177
178     for (int i = 0; i < numberOfXTiles; i++ )
179     {
180         for (int j = 0; j < numberOfYTiles; j++)
181         {
182             freeTiles_.append(QPointF(i*40,j*40));
183         }
184     }
185
186
187     //spread the rocks
188
189     for (int i = 0; i < rocks; i++)
190     {
191         QPointF * pPosition = findRandomFreeSlot();
192
193         //If there was no room no point to continue
194         if (pPosition == NULL)
195             break;
196
197         QPixmap rockPixmap (":/pix/kari.png");
198         QGraphicsPixmapItem * pRock = addPixmap(rockPixmap);
199         pRock->setData(0,"rock");
200         pRock->setPos(*pPosition);
201         delete pPosition;
202
203     }
204
205     //spread the ghosts
206
207     ghostsLeft_ = ghosts;
208     spreadGhosts(ghosts);
209
210
211
212     //spread the octopuses
213
214     QList <Octopus*> octopusList;
215
216     for (int i=0; i < octopuses; i++)
217     {
218         QPointF * pPosition = findRandomFreeSlot();
219
220         //If there was no room no point to continue
221         if (pPosition == NULL)
222             break;
223
224     QPixmap octopusPixmap (":/pix/tursas.png");
225     Octopus * pOctopus = new Octopus(octopusPixmap,octopusSpeed);
226     pOctopus->setData(0,"octopus");
227     pOctopus->setPos(*pPosition);
228     addItem(pOctopus);
229     pOctopus->startMoving();
230     movingItems_.append(pOctopus);
231     connect(this,SIGNAL(pauseOn()),pOctopus,SLOT(stopMoving()));
232     connect(this,SIGNAL(pauseOff()),pOctopus,SLOT(startMoving()));
233     octopusList.append(pOctopus);
234     delete pPosition;
235
236     }
237
238
239     //place the ship
240
241     QPointF * pPosition = findRandomFreeSlot();
242     if (pPosition == NULL)
243     {
244         // Game cannot begin without a free position for ship, so give an error message and return
245
246         QMessageBox::critical(NULL,"Error! Too many objects on screen","No free space to place the ship. The game cannot start. Please choose another level.");
247         return;
248     }
249
250     QList<QPixmap> shipImages;
251     shipImages.append(QPixmap(":/pix/laiva.png"));
252     shipImages.append(QPixmap(":/pix/laiva_1aave.png"));
253     shipImages.append(QPixmap(":/pix/laiva_2aave.png"));
254     shipImages.append(QPixmap(":/pix/laiva_3aave.png"));
255     shipImages.append(QPixmap(":/pix/laiva_4aave.png"));
256     shipImages.append(QPixmap(":/pix/laiva_5aave.png"));
257     shipImages.append(QPixmap(":/pix/laiva_6aave.png"));
258     shipImages.append(QPixmap(":/pix/laiva_7aave.png"));
259     shipImages.append(QPixmap(":/pix/laiva_8aave.png"));
260     shipImages.append(QPixmap(":/pix/laiva_9aave.png"));
261     shipImages.append(QPixmap(":/pix/laiva_10aave.png"));
262
263     Ship * pShip = new Ship (shipImages);
264     pShip->setData(0,"ship");
265     pShip->setPos(*pPosition);
266     addItem(pShip);
267     connect(pShip,SIGNAL(pickingGhost(QGraphicsItem*)),this, SLOT(removeGhost(QGraphicsItem*)) );
268     connect(pShip,SIGNAL(droppingGhosts(int)),this,SLOT(ghostsDropped(int)));
269     connect(this,SIGNAL(vibrationActivated(bool)),pShip,SLOT(setVibrationActivate(bool)));
270     if (vibrationAllowed_)
271         pShip->allowVibration(); //Vibration is disallowed by default so only allowing needs to be done explicitly
272     connect(pResourceSet_,SIGNAL(resourcesGranted(const QList< ResourcePolicy::ResourceType >)),pShip,SLOT(allowVibration()));
273     connect(pResourceSet_,SIGNAL(lostResources()),pShip,SLOT(disallowVibration()));
274     pShip->startMoving();
275     movingItems_.append(pShip);
276     connect(this,SIGNAL(pauseOn()),pShip,SLOT(stopMoving()));
277     connect(this,SIGNAL(pauseOff()),pShip,SLOT(startMoving()));
278     foreach (Octopus* pOctopus, octopusList)
279     {
280         connect(pOctopus,SIGNAL(droppingGhosts()),pShip,SLOT(dropAllGhosts()));
281     }
282     delete pPosition;
283 }
284
285 void SeaScene::setupMap(Level level)
286 {
287     setupMap(level.getNumberOfGhosts(),level.getNumberOfRocks(),level.getNumberOfOctopuses(),level.getOctopusSpeed());
288 }
289
290 void SeaScene::spreadGhosts(int ghosts)
291 {
292
293
294     //the octopuses and the ship may have moved from their original positions,
295     //so the list of free slots must be adjusted to exclude their current positions
296
297     QList<QPointF> temporarilyReservedSlots;
298
299     foreach (QGraphicsItem* pItem, movingItems_)
300     {
301         if (pItem == NULL)
302         {
303  //           qDebug() << "NULL item in movingItems_";
304             continue;
305         }
306
307         //round x and y down to fit the slot size
308         int x = pItem->x();
309         x = x/40;
310         x = x*40;
311
312         int y = pItem->y();
313         y = y/40;
314         y=y*40;
315
316
317         QPointF position (x,y);
318
319         //remove the tiles (potentially) occupied by the item from free slots and place in temp list if was in the list before
320
321         if (freeTiles_.removeOne(position))
322             temporarilyReservedSlots.append(position);
323
324
325         position.setX(x+40);
326
327         if (freeTiles_.removeOne(position))
328             temporarilyReservedSlots.append(position);
329
330         position.setY(y+40);
331
332         if (freeTiles_.removeOne(position))
333             temporarilyReservedSlots.append(position);
334
335         position.setX(x);
336
337         if (freeTiles_.removeOne(position))
338             temporarilyReservedSlots.append(position);
339
340     }
341
342
343     //spread ghosts in random free slots
344
345     for (int i=0; i < ghosts; i++)
346     {
347         QPointF * pPosition = findRandomFreeSlot();
348
349         //If there was no room no point to continue
350         if (pPosition == NULL)
351             return;
352
353         QPixmap ghostPixmap(":/pix/aave.png");
354         QGraphicsPixmapItem * pGhost = addPixmap(ghostPixmap);
355         pGhost->setData(0,"ghost");
356         pGhost->setPos(*pPosition);
357         delete pPosition;
358     }
359
360     //return the slots occupied by moving items to free slots
361     freeTiles_.append(temporarilyReservedSlots);
362
363     //clear temp for the next round
364     temporarilyReservedSlots.clear();
365 }
366
367 QPointF* SeaScene::findRandomFreeSlot()
368 {
369     if (freeTiles_.isEmpty())
370         return NULL;
371
372     int index = qrand()%freeTiles_.size();
373
374 //    qDebug()  << index << " index";
375     return new QPointF (freeTiles_.takeAt(index));
376
377 }
378
379 void SeaScene::removeGhost(QGraphicsItem *pGhost)
380 {
381     removeItem(pGhost);  //remove the item from scene
382     freeTiles_.append(pGhost->scenePos()); //add the item's position to free slots
383     delete pGhost;
384     ghostsLeft_--;
385     if (ghostsLeft_ == 0)
386     {
387         emit allGhostsPicked();
388  //       qDebug() << "All ghosts picked!";
389     }
390 }
391
392 void SeaScene::ghostsDropped(int ghosts)
393 {
394     ghostsLeft_ += ghosts;
395
396     spreadGhosts(ghosts);
397 }
398
399 void SeaScene::pause(bool paused)
400 {
401     //    qDebug() << "pause pressed " << paused;
402         if (paused_ == paused)
403                 return;
404
405         paused_ = paused;
406
407         if (paused == false)
408         {
409      //       qDebug() << "starting to move again";
410 //            emit fullscreenRequested();   fremantle specific (since no "show statusbar" action in harmattan version)
411             emit pauseOff();
412             screenLitKeeper_.keepScreenLit(true);
413             if (pPausetextItem_)
414                 pPausetextItem_->hide();
415
416             scoreCounter_.start();
417
418             autopauseTimer.start(); //Start counting towards autopause
419         }
420
421         else
422         {
423 //         qDebug("about to stop movement");
424             emit pauseOn();
425             screenLitKeeper_.keepScreenLit(false);
426             if (pPausetextItem_ != NULL)
427             {
428 //                qDebug() << "about to show the pause text";
429                 pPausetextItem_->show();
430 //                qDebug() << "showing pause text";
431             }
432 //                else qDebug() << "No pause text available";
433
434             levelScore_ += scoreCounter_.elapsed();
435
436             autopauseTimer.stop(); //No need to count toward autopause when already paused
437         }
438 }
439
440 void SeaScene::vibrationActivate(bool on)
441 {
442     emit vibrationActivated(on);
443 }
444
445 void SeaScene::handleScreenTapped()
446 {
447
448     //If the game is going just pause it
449     if (!paused_)
450     {
451         pPauseAction_->setChecked(true);
452         return;
453     }
454
455     //If the game is paused and about box is shown, close it and show the pause text and menu again
456
457     if(pAboutBoxItem_)
458     {
459         if(pAboutBoxItem_->isVisible())
460         {
461             pAboutBoxItem_->hide();
462             pPausetextItem_->show();
463             return;
464         }
465     }
466
467     //If the game is paused, check if the level completed item is shown
468
469     if (pLevelCompletedItem_)
470     {
471         if (pLevelCompletedItem_->isVisible())
472         {
473             pLevelCompletedItem_->hide();
474             restartLevel(); //Current level has already been set to the next one before showing the level completed item
475             pPauseAction_->setChecked(false); //unpause
476             return;
477         }
478     }
479    
480     //If the game is paused, check if the victory item is being shown
481     if(pVictoryCongratulationsItem_)
482     {
483         if (pVictoryCongratulationsItem_->isVisibleTo(NULL)) //returns visibility to scene
484         {
485             pVictoryCongratulationsItem_->hide();
486             restartGame();
487             pPauseAction_->setChecked(false); // unpause
488             return;
489         }
490     }
491
492
493     //If the game is paused and no victory or about box, check if menu item was selected
494
495     QList<QGraphicsItem *> items = selectedItems();
496
497     //if nothing selected resume play
498
499     if (items.isEmpty())
500     {
501         pSelectLevelsetFromListItem_->hide();
502         pPauseAction_->setChecked(false);
503
504         return;
505
506     }
507
508     //If something was selected check if it was one of the menu items and act on it
509     //(Nothing else should be made selectable anyway)
510
511     //Menu functions
512
513     QGraphicsItem* pItem = items.at(0); //Selecting an item brings here, thus only selecting one item should be possible
514                                        //... so we can just take the first one
515
516     //Selection is just used to get notice of a menu item being clicked, removed after use
517
518     clearSelection();
519
520
521     //Act upon the selected item
522
523
524     if (pItem == pRestartGameItem_)
525     {
526 //        qDebug() << "game restart requested";
527         restartGame();
528         pPauseAction_->setChecked(false); //unpause game
529
530     }
531
532     else if (pItem == pRestartLevelItem_)
533     {
534 //        qDebug() << "Level restart requested";
535         restartLevel();
536         pPauseAction_->setChecked(false); //unpause game
537
538     }
539
540     else if (pItem == pSettingsItem_)
541     {
542         pVibrateAction_->toggle();
543
544         QSettings settings;
545         settings.setValue("vibration",pVibrateAction_->isChecked());
546
547         QString text = pSettingsItem_->toHtml();
548         if (pVibrateAction_->isChecked())
549             text.replace(" on"," off"); //don't remove spaces or you get vibratioff...
550         else
551             text.replace(" off"," on");
552         pSettingsItem_->setHtml(text);
553     }
554
555     else if (pItem == pAboutItem_)
556     {
557         about();
558     }
559
560     else if (pItem == pQuitItem_)
561     {
562         qApp->quit();
563     }
564
565     else if (pItem == pChooseLevelsetItem_)
566     {
567         pPausetextItem_->hide();
568         pSelectLevelsetFromListItem_->show();
569     }
570
571     else
572     {
573         foreach (QGraphicsItem* pLevelItem, levelsetItems_)
574         {
575             if (pItem == pLevelItem)
576             {
577                 QVariant variant = pLevelItem->data(0);
578
579                 if (variant.canConvert<Levelset>())
580                 {
581                     levelset_ = variant.value<Levelset>();
582                     restartGame();
583                     pPauseAction_->setChecked(false); //unpause game
584                 }
585             }
586         }
587     }
588
589 }
590
591
592
593 void SeaScene::createMenuItems()
594 {
595
596     QFont font;
597     font.setPixelSize(35);
598
599
600
601     pPausetextItem_ = new QGraphicsTextItem;
602
603  // This is for fremantle
604 //    pPausetextItem_->setHtml("<font size = \"5\" color = darkorange> Game paused. Tap to continue.");
605
606 //Harmattan needs bigger font
607     pPausetextItem_->setHtml("<font size = \"7\" color = darkorange> Game paused. Tap to continue.");
608
609
610     pPausetextItem_->setZValue(1000);
611     pPausetextItem_->setPos(200,50);
612     addItem(pPausetextItem_);
613     pPausetextItem_->hide();
614
615     menuItemCount_ = 0;
616
617   // This is for fremantle
618  //   QString menufonthtml = "<font size = \"4\" color = darkorange>";
619
620
621  //Harmattan needs bigger font
622         QString menufonthtml = "<font size = \"6\" color = darkorange>";
623
624
625     pRestartGameItem_ = new QGraphicsTextItem;
626     pRestartGameItem_->setHtml(tr("Restart <br> game").prepend(menufonthtml));
627     prepareForMenu(pRestartGameItem_);
628
629     pRestartLevelItem_ = new QGraphicsTextItem;
630     pRestartLevelItem_->setHtml(tr("Restart <br> level").prepend(menufonthtml));
631     prepareForMenu(pRestartLevelItem_);
632
633     pChooseLevelsetItem_ = new QGraphicsTextItem;
634     pChooseLevelsetItem_->setHtml(tr("Choose <br> levelset").prepend(menufonthtml));
635     prepareForMenu(pChooseLevelsetItem_);
636
637     pSettingsItem_ = new QGraphicsTextItem;
638     QString vibraText(tr("Turn vibration <br> effects "));
639     QString statusText;
640     if (pVibrateAction_->isChecked())
641     {
642         statusText = "off";
643     }
644     else
645     {
646         statusText = "on";
647     }
648     vibraText.append(statusText);
649     pSettingsItem_->setHtml(vibraText.prepend(menufonthtml));
650     prepareForMenu(pSettingsItem_);
651
652     pAboutItem_ = new QGraphicsTextItem;
653     pAboutItem_->setHtml(tr("About <br> game").prepend(menufonthtml));
654     prepareForMenu(pAboutItem_);
655
656     pQuitItem_ = new QGraphicsTextItem;
657     pQuitItem_->setHtml(tr("Quit <br> game").prepend(menufonthtml));
658     prepareForMenu(pQuitItem_);
659
660 }
661
662 void SeaScene::prepareForMenu(QGraphicsItem * pItem)
663 {
664
665     //Menu items have pause text item as their parent and are thus added to scene automatically
666     //They are also shown and hidden with it, resulting in the menu being visble when the game is paused
667     //Their coordinates are given relative to the parent.
668
669     int itemsPerRow = 3;
670
671     pItem->setParentItem(pPausetextItem_);
672     pItem->setZValue(1000);
673     pItem->setFlag(QGraphicsItem::ItemIsSelectable);
674
675     if (menuItemCount_< itemsPerRow)
676     {
677         pItem->setY(120);
678     }
679     else pItem->setY(240);
680
681
682     pItem->setX((menuItemCount_++%itemsPerRow)*180-10);
683  }
684
685
686 void SeaScene::about()
687 {
688     pPausetextItem_->hide();
689     pAboutBoxItem_->show();
690 }
691
692
693 void SeaScene::restartLevel()
694 {
695
696     levelScore_ = 0;
697
698     setupMap(levelset_.getLevel(currentLevel_));  //getLevel() returns default constructor Level if index is invalid, so no risk of crash
699
700     scoreCounter_.start();
701
702     vibrationActivate(pVibrateAction_->isChecked());  //Vibration effects are lost without this
703    // qDebug() << pVibrateAction_->isChecked();
704
705     autopauseTimer.start();  //reset counting towards autopause
706
707
708 }
709
710
711
712 void SeaScene::nextLevel()
713 {
714
715     //get score for previous level
716     levelScore_ += scoreCounter_.elapsed();
717     totalScore_ += levelScore_;
718     int highscore = levelset_.getLevelHighScore(currentLevel_);
719
720     qDebug() << highscore;
721
722     QString scoretext;
723
724     if (levelScore_ >= highscore)
725     {
726         scoretext = tr("<font size=\"7\" color = darkorange>Your time: %1.%2 s<br>Best time: %3.%4 s").arg(levelScore_/1000).arg((levelScore_%1000)/100).arg(highscore/1000).arg((highscore%1000)/100);
727     }
728
729     else //New high score!
730
731     {
732         scoretext = tr("<font size=\"7\" color = darkorange>Your time %1.%2 s is<br>the new best time!").arg(levelScore_/1000).arg((levelScore_%1000)/100);
733         levelset_.setLevelHighScore(currentLevel_,levelScore_);
734     }
735
736     //pause to show the highscore or victory screen
737
738     turnPauseOn();
739     pPausetextItem_->hide();
740
741
742     //Go to the next level if available
743     currentLevel_++;
744
745     if ( currentLevel_ < levelset_.numberOfLevels() )
746     {
747
748        pLevelCompletedItem_->setHtml(scoretext);
749        pLevelCompletedItem_->show();
750 //       restartLevel();
751     }
752
753     else //Victory!
754     {
755         int totalHighsore = levelset_.getTotalHighScore();
756         if (totalScore_ >= totalHighsore)
757         {
758             scoretext.append(tr("<br>Your total time: %1.%2 s<br>Best total time: %3.%4 s").arg(totalScore_/1000).arg((totalScore_%1000)/100).arg(totalHighsore/1000).arg((totalHighsore%1000)/100));
759         }
760         else //new total high score
761         {
762             scoretext.append(tr("<br>Your total time %1.%2 s is<br>the new best time").arg(totalScore_/1000).arg((totalScore_%1000)/100));
763             levelset_.setTotalHighScore(totalScore_);
764         }
765
766         pVictoryScoreItem_->setHtml(scoretext);
767         pVictoryCongratulationsItem_->show();
768     }
769 }
770
771
772 void SeaScene::restartGame()
773 {
774     currentLevel_ = 0;
775     totalScore_ = 0;
776     restartLevel();
777 }
778
779
780 void SeaScene::forcePause()
781 {
782     //Pause without setting the pause action state
783     pause(true);
784 }
785
786 void SeaScene::softContinue()
787 {
788     //Continue if not being paused by the user
789     // Reverts forcePause()
790
791     pause(pPauseAction_->isChecked());
792 }
793
794
795 void SeaScene::createVictoryItems()
796 {
797     pVictoryCongratulationsItem_ = new QGraphicsTextItem;
798     pVictoryCongratulationsItem_->setHtml("<font size=\"7\" color = darkorange> <b> Victory!");
799     pVictoryCongratulationsItem_->hide();
800     pVictoryCongratulationsItem_->setPos(315,30);
801     pVictoryCongratulationsItem_->setZValue(1000);
802     addItem(pVictoryCongratulationsItem_);
803
804
805     //coordinates are relative to the parent
806
807     QGraphicsTextItem * pTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
808     pTextItem->setHtml("<font size=\"7\" color = darkorange> Congratulations!");
809     pTextItem->setPos(-50,80);
810     pTextItem->setZValue(1000);
811
812     QGraphicsTextItem * pMiddleTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
813     pMiddleTextItem->setHtml("<font size=\"7\" color = darkorange> You have saved all the ghosts.");
814     pMiddleTextItem->setPos(-145,120);
815     pMiddleTextItem->setZValue(1000);
816
817
818     pVictoryScoreItem_ = new QGraphicsTextItem(pVictoryCongratulationsItem_);
819     pVictoryScoreItem_->setPos(-50,180);
820     pMiddleTextItem->setZValue(1000);
821     //Text is set at usetime!
822
823     QGraphicsTextItem * pLowestTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
824     pLowestTextItem->setHtml("<font size=\"7\" color = darkorange> Tap to play again");
825     pLowestTextItem->setPos(-50,360);
826     pLowestTextItem->setZValue(1000);
827 }
828
829
830 void SeaScene::createAboutBoxItems()
831 {
832     pAboutBoxItem_ = new QGraphicsTextItem;
833     addItem(pAboutBoxItem_);
834     pAboutBoxItem_->setPos(25,50);
835     pAboutBoxItem_->setZValue(1000);
836     pAboutBoxItem_->hide();
837
838     pAboutBoxItem_->setHtml(tr("<font color = darkorange size = \"7\"><b>"
839                           "%1 Version %2</b>"
840                           "<p><font size = \"6\"> Copyright 2011 Heli Hyv&auml;ttinen"
841                           "<p><font size = \"6\"> License: GNU General Public License v2"
842                           "<p><font size = \"6\">  The source code of this game is available trough it's web pages."
843                           "<p><font size = \"6\"> Web: http://ghostsoverboard.garage.maemo.org/<br>"
844                           "Bug Reports: <br> https://bugs.maemo.org/"
845                           "enter_bug.cgi?product=Ghosts%20Overboard"
846                           ).arg(QApplication::applicationName(),QApplication::applicationVersion()));
847
848 }
849
850 void SeaScene::setItemPointersNull()
851 {
852     pPausetextItem_ = NULL;
853     pRestartLevelItem_ = NULL;
854     pRestartGameItem_ = NULL;
855     pSettingsItem_ = NULL;
856     pAboutItem_ = NULL;
857     pQuitItem_ = NULL ;
858 //    pMinimizeItem_ = NULL; //Fremantle spesific
859     pChooseLevelsetItem_ = NULL;
860
861     pAboutBoxItem_ = NULL;
862     pLevelCompletedItem_ = NULL;
863     pVictoryCongratulationsItem_ = NULL;
864     pVictoryScoreItem_ = NULL;
865
866 }
867
868 void SeaScene::turnPauseOn()
869 {
870     pPauseAction_->setChecked(true);
871 }
872
873
874
875 void SeaScene::createLevelCompletedItems()
876 {
877     pLevelCompletedItem_ = new QGraphicsTextItem;
878     addItem(pLevelCompletedItem_);
879     pLevelCompletedItem_->setPos(240,100);
880     pLevelCompletedItem_->setZValue(1000);
881     pLevelCompletedItem_->hide();
882     //The text is set at usetime
883
884     QGraphicsTextItem * pTapForNextLevelItem = new QGraphicsTextItem(pLevelCompletedItem_);
885     pTapForNextLevelItem->setPos(-60,100);
886     pTapForNextLevelItem->setZValue(1000);
887     pTapForNextLevelItem->setHtml("<font size=\"7\" color = darkorange>Tap to start the next level");
888 }
889
890 void SeaScene::createSelectLevelsetFromListItems()
891 {
892
893     if (availableLevelsets_.isEmpty()) //Something is badly wrong in code if this is true...
894             return;
895
896
897     pSelectLevelsetFromListItem_ = new QGraphicsTextItem;
898     addItem(pSelectLevelsetFromListItem_);
899     pSelectLevelsetFromListItem_->setPos(295,60);
900     pSelectLevelsetFromListItem_->setZValue(1000);
901     pSelectLevelsetFromListItem_->hide();
902
903
904     QString fontstring ("<font color = darkorange size = \"7\">");
905
906     pSelectLevelsetFromListItem_->setHtml(tr("Choose a levelset").prepend(fontstring));
907
908     int yPos = 100;
909
910     levelsetItems_.clear();
911
912
913     foreach (Levelset set, availableLevelsets_)
914     {
915         QGraphicsTextItem * pItem = new QGraphicsTextItem(pSelectLevelsetFromListItem_);
916         QString text (fontstring);
917         if (levelset_.getName() == set.getName())
918             text.append("<b>");
919         text.append(set.getName());
920         pItem->setHtml(text);
921         pItem->setPos(65,yPos);
922         yPos+=80;
923         pItem->setZValue(1000);
924         pItem->setFlag(QGraphicsItem::ItemIsSelectable);
925         pItem->setData(0,QVariant::fromValue(set));
926         levelsetItems_.append(pItem);
927
928     }
929
930   }
931
932
933     void SeaScene::resourcesAvailable()
934     {
935         qDebug() << "Resources available";
936         vibrationAllowed_ = true;
937     }
938
939
940     void SeaScene::resourcesLost()
941     {
942         qDebug() << "Resources lost";
943         vibrationAllowed_ = false;
944     }