File indexing completed on 2024-05-05 04:02:03

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 John-Paul Stanford <jp@stanwood.org.uk>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 // own
0008 #include "bomber.h"
0009 
0010 // Qt
0011 #include <QAction>
0012 #include <QLabel>
0013 #include <QStatusBar>
0014 
0015 // KF
0016 #include <KActionCollection>
0017 #include <KLocalizedString>
0018 #include <KMessageBox>
0019 #include <KToggleAction>
0020 
0021 // KDEGames
0022 #include <KGameHighScoreDialog>
0023 #include <KGameThemeSelector>
0024 #include <KGameStandardAction>
0025 
0026 // Bomber
0027 #include "settings.h"
0028 
0029 Bomber::Bomber()
0030 {
0031     m_provider.discoverThemes(
0032         QStringLiteral("themes"),   //theme data location
0033         QStringLiteral("kbomber")); //default theme name
0034 
0035     m_selector = new KGameThemeSelector(&m_provider);
0036 
0037     m_statusBar = statusBar();
0038     m_level = new QLabel(i18nc("Used to display the current level of play to the user", "Level: %1", 0));
0039     m_statusBar->addPermanentWidget(m_level);
0040     m_score = new QLabel(i18nc("Used to inform the user of their current score", "Score: %1", 0));
0041     m_statusBar->addPermanentWidget(m_score);
0042     m_lives = new QLabel(i18nc("Used to tell the user how many lives they have left", "Lives: %1", 3));
0043     m_statusBar->addPermanentWidget(m_lives);
0044 
0045     m_gameWidget = new BomberGameWidget(&m_provider, this);
0046     connect(&m_provider, &KGameThemeProvider::currentThemeChanged, m_gameWidget, &BomberGameWidget::settingsChanged);
0047 
0048     connect(m_gameWidget, &BomberGameWidget::levelChanged, this, &Bomber::displayLevel);
0049     connect(m_gameWidget, &BomberGameWidget::scoreChanged, this, &Bomber::displayScore);
0050     connect(m_gameWidget, &BomberGameWidget::livesChanged, this, &Bomber::displayLives);
0051     connect(m_gameWidget, &BomberGameWidget::stateChanged, this, &Bomber::gameStateChanged);
0052 
0053     setCentralWidget(m_gameWidget);
0054 
0055     initXMLUI();
0056 
0057     setFocusPolicy(Qt::StrongFocus);
0058 
0059     setFocus();
0060     setupGUI();
0061 }
0062 
0063 Bomber::~Bomber()
0064 {
0065     delete m_selector;
0066 }
0067 
0068 /**
0069  * create the action events create the gui.
0070  */
0071 void Bomber::initXMLUI()
0072 {
0073     // Game
0074     m_newAction = KGameStandardAction::gameNew(this, &Bomber::newGame, actionCollection());
0075     KGameStandardAction::end(this, &Bomber::closeGame, actionCollection());
0076     m_pauseAction = KGameStandardAction::pause(this, &Bomber::pauseGame, actionCollection());
0077     KGameStandardAction::highscores(this, &Bomber::showHighscore, actionCollection());
0078     KGameStandardAction::quit(this, &QWidget::close, actionCollection());
0079 
0080     // Settings
0081     KStandardAction::preferences(this, &Bomber::showPreferences, actionCollection());
0082     m_soundAction = new KToggleAction(i18nc("Menu item used to disable or enable sound", "&Play Sounds"), this);
0083     actionCollection()->addAction(QStringLiteral("toggle_sound"), m_soundAction);
0084     connect(m_soundAction, &KToggleAction::triggered, m_gameWidget, &BomberGameWidget::setSoundsEnabled);
0085 
0086     QAction * dropBombAction = actionCollection()->addAction(QStringLiteral("drop_bomb"));
0087     dropBombAction->setText(i18nc("The name of the action used for dropping bombs", "&Drop bomb"));
0088     dropBombAction->setToolTip(i18nc("The tool tip text for the action used to drop bombs", "Drop bomb"));
0089     dropBombAction->setWhatsThis(i18nc("Description of the action used to drop bombs",
0090                                        "Makes the plane drop a bomb while flying"));
0091     KActionCollection::setDefaultShortcut(dropBombAction, Qt::Key_Space);
0092     dropBombAction->setEnabled(true);
0093     connect(dropBombAction, &QAction::triggered, m_gameWidget, &BomberGameWidget::onDropBomb);
0094 }
0095 
0096 void Bomber::readSettings()
0097 {
0098     m_soundAction->setChecked(BomberSettings::playSounds());
0099     m_gameWidget->settingsChanged();
0100 }
0101 
0102 void Bomber::newGame()
0103 {
0104     // Check for running game
0105     closeGame();
0106     if (m_gameWidget->state() == BomberGameWidget::State::BeforeFirstGame
0107         || m_gameWidget->state() == BomberGameWidget::State::GameOver) {
0108         m_gameWidget->newGame();
0109     }
0110 }
0111 
0112 void Bomber::pauseGame()
0113 {
0114     if (m_gameWidget->state() == BomberGameWidget::State::Paused) {
0115         m_gameWidget->setPaused(false);
0116     } else {
0117         m_gameWidget->setPaused(true);
0118     }
0119 }
0120 
0121 void Bomber::closeGame()
0122 {
0123     if (m_gameWidget->state() == BomberGameWidget::State::BeforeFirstGame
0124         || m_gameWidget->state() == BomberGameWidget::State::GameOver) {
0125         return;
0126     }
0127 
0128     BomberGameWidget::State old_state = m_gameWidget->state();
0129     if (old_state == BomberGameWidget::State::Running) {
0130         m_gameWidget->setPaused(true);
0131     }
0132     int ret = KMessageBox::questionTwoActions(this,
0133                                          i18nc("Message displayed when player tries to quit a game that is currently running",
0134                                                "Do you really want to close the running game?"),
0135                                          QString(),
0136                                          KStandardGuiItem::close(), KStandardGuiItem::cancel());
0137     if (ret == KMessageBox::PrimaryAction) {
0138         m_gameWidget->closeGame();
0139     } else if (old_state == BomberGameWidget::State::Running) {
0140         m_gameWidget->setPaused(false);
0141     }
0142 }
0143 
0144 void Bomber::showHighscore()
0145 {
0146     KGameHighScoreDialog ksdialog(KGameHighScoreDialog::Name | KGameHighScoreDialog::Score | KGameHighScoreDialog::Level, this);
0147     ksdialog.exec();
0148 }
0149 
0150 void Bomber::showPreferences()
0151 {
0152     m_selector->showAsDialog();
0153 }
0154 
0155 void Bomber::highscore()
0156 {
0157     const unsigned int score = m_gameWidget->score();
0158 
0159     QPointer<KGameHighScoreDialog> ksdialog = new KGameHighScoreDialog(KGameHighScoreDialog::Name | KGameHighScoreDialog::Score | KGameHighScoreDialog::Level, this);
0160 
0161     KGameHighScoreDialog::FieldInfo info;
0162     info[KGameHighScoreDialog::Score].setNum(score);
0163     info[KGameHighScoreDialog::Level].setNum(m_gameWidget->level());
0164     if (score > 0 && ksdialog->addScore(info) > 0) {
0165         QString const message = i18n("Congratulations!\nYou made it into the hall of fame.");
0166         ksdialog->setComment(message);
0167         ksdialog->exec();
0168     } else {
0169         QString const message = i18np("You gained a score of %1 point.", "You gained a score of %1 points.", score);
0170         KMessageBox::information(this, message, i18n("End of Game"));
0171     }
0172     delete ksdialog;
0173 }
0174 
0175 void Bomber::displayLevel(unsigned int level)
0176 {
0177     m_level->setText(i18nc(
0178         "Used to display the current level of play to the user",
0179         "Level: %1", level));
0180 }
0181 
0182 void Bomber::displayScore(unsigned int score)
0183 {
0184     m_score->setText(i18nc(
0185         "Used to inform the user of their current score", "Score: %1",
0186         score));
0187 }
0188 
0189 void Bomber::displayLives(unsigned int lives)
0190 {
0191     m_lives->setText(i18nc(
0192         "Used to tell the user how many lives they have left", "Lives: %1",
0193         lives));
0194 }
0195 
0196 void Bomber::gameStateChanged(BomberGameWidget::State state)
0197 {
0198     switch (state) {
0199         case BomberGameWidget::State::Paused:
0200             m_pauseAction->setChecked(true);
0201             m_statusBar->clearMessage();
0202             break;
0203         case BomberGameWidget::State::Running:
0204             m_pauseAction->setChecked(false);
0205             m_statusBar->clearMessage();
0206             break;
0207         case BomberGameWidget::State::GameOver:
0208             m_statusBar->showMessage(i18nc("Game over messaged displayed in the status bar", "Game over. Press '%1' for a new game",
0209                                            m_newAction->shortcuts().constFirst().toString(QKeySequence::NativeText)));
0210             highscore();
0211             break;
0212         default:
0213             break;
0214     }
0215 }
0216 
0217 #include "moc_bomber.cpp"