/*************************************************************************** begin : Fri May 19 2000 copyright : (C) 2000 by Roman Merzlyakov email : roman@sbrf.barrt.ru copyright : (C) 2000 by Roman Razilov email : Roman.Razilov@gmx.de ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ /* changes 21.05.2000 Roman Razilov Menu game/Next */ // // The implementation of the KLines widget // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cfg.h" #include "prefs.h" #include #include "klines.moc" enum { Nb_Levels = 5 }; static const char *LEVEL[Nb_Levels] = { I18N_NOOP("Very Easy"), I18N_NOOP("Easy"), I18N_NOOP("Normal"), I18N_NOOP("Hard"), I18N_NOOP("Very Hard") }; /* Creates the KLines widget and sets saved options (if any). */ KLines::KLines() { mwidget = new MainWidget(this); setCentralWidget( mwidget ); lsb = mwidget->GetLsb(); connect(lsb, TQ_SIGNAL(endTurn()), this, TQ_SLOT(makeTurn())); connect(lsb, TQ_SIGNAL(eraseLine(int)), this, TQ_SLOT(addScore(int))); connect(lsb, TQ_SIGNAL(endGame()), this, TQ_SLOT(endGame())); connect(lsb, TQ_SIGNAL(userTurn()), this, TQ_SLOT(userTurn())); lPrompt = mwidget->GetPrompt(); score = 0; score_undo = 0; bDemo = false; statusBar()->insertItem(i18n(" Score:"), 1, 1); statusBar()->setItemAlignment(1, AlignVCenter | AlignLeft); statusBar()->insertItem(i18n(" Level: "), 0, 1); statusBar()->setItemAlignment(0, AlignVCenter | AlignLeft); initTDEAction(); connect(&demoTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotDemo())); setFocusPolicy(TQWidget::StrongFocus); setFocus(); startGame(); } /* Saves the options and destroys the KLines widget. */ KLines::~KLines() { Prefs::setLevel(levelAction->currentItem()-2); Prefs::writeConfig(); } /* Init TDEAction objects (menubar, toolbar, shortcuts) */ void KLines::initTDEAction() { KStdGameAction::gameNew(this, TQ_SLOT(startGame()), actionCollection()); act_demo = KStdGameAction::demo(this, TQ_SLOT(startDemo()), actionCollection()); act_demo->setText(i18n("Start &Tutorial")); KStdGameAction::highscores(this, TQ_SLOT(viewHighScore()), actionCollection()); KStdGameAction::quit(this, TQ_SLOT(close()), actionCollection()); endTurnAction = KStdGameAction::endTurn(this, TQ_SLOT(makeTurn()), actionCollection()); showNextAction = new TDEToggleAction(i18n("&Show Next"), TDEShortcut(CTRL+Key_P), this, TQ_SLOT(switchPrompt()), actionCollection(), "options_show_next"); showNextAction->setCheckedState(i18n("Hide Next")); showNumberedAction = new TDEToggleAction(i18n("&Use Numbered Balls"), TDEShortcut(), this, TQ_SLOT(switchNumbered()), actionCollection(), "options_show_numbered"); undoAction = KStdGameAction::undo(this, TQ_SLOT(undo()), actionCollection()); levelAction = KStdGameAction::chooseGameType(0, 0, actionCollection()); TQStringList items; for (uint i=0; isetItems(items); levelAction->setCurrentItem(Prefs::level()+2); showNextAction->setChecked(Prefs::showNext()); showNumberedAction->setChecked(Prefs::numberedBalls()); lPrompt->setPrompt(Prefs::showNext()); (void)new TDEAction(i18n("Move Left"), Key_Left, lsb, TQ_SLOT(moveLeft()), actionCollection(), "left"); (void)new TDEAction(i18n("Move Right"), Key_Right, lsb, TQ_SLOT(moveRight()), actionCollection(), "right"); (void)new TDEAction(i18n("Move Up"), Key_Up, lsb, TQ_SLOT(moveUp()), actionCollection(), "up"); (void)new TDEAction(i18n("Move Down"), Key_Down, lsb, TQ_SLOT(moveDown()), actionCollection(), "down"); (void)new TDEAction(i18n("Move Ball"), Key_Space, lsb, TQ_SLOT(placePlayerBall()), actionCollection(), "place_ball"); setupGUI( TDEMainWindow::Save | Keys | StatusBar | Create ); } void KLines::startGame() { score = 0; score_undo = 0; bUndo = true; bNewTurn = true; if(bDemo) stopDemo(); bFirst = true; int level = levelAction->currentItem()-2; setLevel(level); lsb->setLevel(level); lsb->setGameOver(false); lsb->clearField(); generateRandomBalls(); placeBalls(); generateRandomBalls(); undoAction->setEnabled(false); endTurnAction->setEnabled(true); updateStat(); } void KLines::setLevel(int level) { levelStr = i18n(LEVEL[level+2]); statusBar()->changeItem(i18n(" Level: %1").arg(levelStr), 0); } void KLines::startDemo() { if (bDemo) { stopDemo(); return; } score = 0; score_undo = 0; bUndo = true; bNewTurn = true; bDemo = true; act_demo->setText(i18n("Stop &Tutorial")); bFirst = true; levelStr = i18n("Tutorial"); statusBar()->changeItem(i18n(" Level: %1").arg(levelStr), 0); lsb->startDemoMode(); lsb->setGameOver(false); lsb->clearField(); lsb->update(); undoAction->setEnabled(false); endTurnAction->setEnabled(false); generateRandomBalls(); demoStep = 0; demoTimer.start(1000, true); } void KLines::stopDemo() { bDemo = false; lsb->hideDemoText(); demoTimer.stop(); statusBar()->changeItem(i18n(" Level: %1").arg(i18n("Tutorial - Stopped")), 0); act_demo->setText(i18n("Start &Tutorial")); } void KLines::slotDemo() { bool newBalls = false; int ballColors = -1; int clickX = 0; int clickY = 0; TQString msg; demoStep++; if ((demoStep % 2) == 0) { lsb->hideDemoText(); demoTimer.start(1000, true); return; } if (demoStep == 1) { msg = i18n("The goal of the game is to put\n" "5 balls of the same color in line."); } else if (demoStep == 3) { newBalls = true; } else if (demoStep == 5) { msg = i18n("You can make horizontal, vertical\n" "and diagonal lines."); } else if (demoStep == 7) { newBalls = true; } else if (demoStep == 9) { msg = i18n("Each turn, three new balls are placed on the board."); } else if (demoStep == 11) { newBalls = true; } else if (demoStep == 13) { msg = i18n("Every turn, you can move one ball."); } else if (demoStep == 15) { newBalls = true; ballColors = 56; } else if (demoStep == 17) { msg = i18n("To move a ball, click on it with the mouse,\n" "then click where you want the ball to go."); } else if (demoStep == 19) { clickX = 6; clickY = 6; } else if (demoStep == 21) { clickX = 6; clickY = 9; } else if (demoStep == 23) { msg = i18n("You just moved the blue ball!"); } else if (demoStep == 25) { newBalls = true; } else if (demoStep == 27) { msg = i18n("Balls can be moved to every position on the board,\n" "as long as there are no other balls in their way."); } else if (demoStep == 29) { clickX = 4; clickY = 3; demoStep++; } else if (demoStep == 31) { clickX = 7; clickY = 9; } else if (demoStep == 33) { msg = i18n("Now we only need one more blue ball."); } else if (demoStep == 35) { newBalls = true; } else if (demoStep == 37) { msg = i18n("It seems to be our lucky day!"); } else if (demoStep == 39) { clickX = 8; clickY = 2; demoStep++; } else if (demoStep == 41) { clickX = 8; clickY = 9; } else if (demoStep == 43) { msg = i18n("Hurray! And away they go!\n" "Now lets try the green balls."); } else if (demoStep == 45) { clickX = 8; clickY = 7; demoStep++; } else if (demoStep == 47) { clickX = 4; clickY = 5; lsb->demoAdjust(42); } else if (demoStep == 49) { newBalls = true; } else if (demoStep == 51) { msg = i18n("Now you try!\n" "Click on the green ball and move it to the others!"); demoStep++; } else if (demoStep == 53) { lsb->hideDemoText(); lsb->adjustDemoMode(true, false); demoStep++; } else if (demoStep == 55) { msg = i18n("Almost, try again!"); demoStep -= 4; } else if (demoStep == 57) { msg = i18n("Very good!"); } else if (demoStep == 59) { msg = i18n("Whenever you complete a line you get an extra turn."); } else if (demoStep == 61) { msg = i18n("This is the end of this tutorial.\n" "Feel free to finish the game!"); demoStep++; } else if (demoStep == 63) { lsb->hideDemoText(); lsb->adjustDemoMode(true, true); bDemo = false; act_demo->setText(i18n("Start &Tutorial")); } if (!msg.isEmpty()) { lsb->showDemoText(msg); demoTimer.start(3500 + msg.contains("\n")*1500, true); return; } if (newBalls) { placeBalls(); if (ballColors == -1) { generateRandomBalls(); } else { for( int i = 0 ; i < BALLSDROP ; i++ ) { nextBalls[i] = ballColors % 10; ballColors = ballColors / 10; lPrompt->SetBalls(nextBalls); } } updateStat(); demoTimer.start(1000, true); return; } if (clickX) { lsb->demoClick(clickX-1, clickY-1); if (hasFocus()) demoTimer.start(1000, true); return; } } void KLines::focusOutEvent(TQFocusEvent *ev) { if (bDemo) { lsb->hideDemoText(); demoTimer.stop(); statusBar()->changeItem(i18n(" Level: %1").arg(i18n("Tutorial - Paused")), 0); } TDEMainWindow::focusOutEvent(ev); } void KLines::focusInEvent(TQFocusEvent *ev) { if (bDemo) { statusBar()->changeItem(i18n(" Level: %1").arg(levelStr), 0); slotDemo(); } TDEMainWindow::focusInEvent(ev); } void KLines::stopGame() { if (!lsb->gameOver()) endGame(); startGame(); } void KLines::searchBallsLine() { } void KLines::generateRandomBalls() { score_undo = score; for( int i = 0 ; i < BALLSDROP ; i++ ) { nextBalls_undo[i] = nextBalls[i]; nextBalls[i] = bUndo ? lsb->random(NCOLORS) : nextBalls_redo[i]; } lPrompt->SetBalls(nextBalls); } void KLines::placeBalls() { lsb->placeBalls(nextBalls); } void KLines::undo() { if (lsb->gameOver()) return; if (!bUndo) return; for( int i = 0 ; i < BALLSDROP ; i++ ) { nextBalls_redo[i] = nextBalls[i]; nextBalls[i] = nextBalls_undo[i]; } score = score_undo; updateStat(); lPrompt->SetBalls(nextBalls); lsb->undo(); switchUndo(FALSE); } void KLines::makeTurn() { if (bDemo) { lsb->adjustDemoMode(false, false); demoTimer.start(100, true); } if (lsb->gameOver()) return; if (!bDemo){ placeBalls(); if(sender() != lsb) lsb->saveUndo(); } bNewTurn = true; } void KLines::userTurn() { if(bNewTurn) { bNewTurn = false; if (!bDemo) generateRandomBalls(); if (!bFirst && !bDemo) switchUndo(true); } bFirst = false; } void KLines::addScore(int ballsErased) { if(ballsErased >= 5){ score += 2*ballsErased*ballsErased - 20*ballsErased + 60 ; if( !lPrompt->getState() ) score+= 1; updateStat(); }; if (bDemo) { lsb->adjustDemoMode(false, false); demoStep += 2; if (hasFocus()) demoTimer.start(100, true); } } void KLines::updateStat() { statusBar()->changeItem(i18n(" Score: %1").arg(score), 1); } void KLines::viewHighScore() { KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Level, this); d.exec(); } void KLines::endGame() { lsb->setGameOver(true); lsb->repaint(false); if (bDemo) return; KScoreDialog d(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Level, this); KScoreDialog::FieldInfo scoreInfo; scoreInfo.insert(KScoreDialog::Level, levelStr); if (d.addScore(score, scoreInfo, true)) d.exec(); } void KLines::switchPrompt() { Prefs::setShowNext(!Prefs::showNext()); lPrompt->setPrompt(Prefs::showNext()); showNextAction->setChecked(Prefs::showNext()); } void KLines::switchNumbered() { Prefs::setNumberedBalls(!Prefs::numberedBalls()); lPrompt->setPrompt(Prefs::showNext()); showNumberedAction->setChecked(Prefs::numberedBalls()); mwidget->updatePix(); } void KLines::switchUndo(bool bu) { bUndo = bu; undoAction->setEnabled(bu); } void KLines::keyPressEvent(TQKeyEvent *e) { if (lsb->gameOver() && (e->key() == TQt::Key_Space)) { e->accept(); startGame(); return; } TDEMainWindow::keyPressEvent(e); }