You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
586 lines
14 KiB
586 lines
14 KiB
/***************************************************************************
|
|
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 <tqkeycode.h>
|
|
#include <tqlabel.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqtooltip.h>
|
|
#include <tqstring.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
|
|
#include <tdeapplication.h>
|
|
#include <kiconloader.h>
|
|
#include <tdelocale.h>
|
|
#include <tdeconfig.h>
|
|
#include <tdemenubar.h>
|
|
#include <tdepopupmenu.h>
|
|
#include <highscore/kscoredialog.h>
|
|
#include <tdeaction.h>
|
|
#include <kstdaction.h>
|
|
#include <kstdgameaction.h>
|
|
|
|
#include "cfg.h"
|
|
#include "prefs.h"
|
|
#include <kstatusbar.h>
|
|
#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, TQT_SIGNAL(endTurn()), TQT_TQOBJECT(this), TQT_SLOT(makeTurn()));
|
|
connect(lsb, TQT_SIGNAL(eraseLine(int)), TQT_TQOBJECT(this), TQT_SLOT(addScore(int)));
|
|
connect(lsb, TQT_SIGNAL(endGame()), TQT_TQOBJECT(this), TQT_SLOT(endGame()));
|
|
connect(lsb, TQT_SIGNAL(userTurn()), TQT_TQOBJECT(this), TQT_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, TQT_SIGNAL(timeout()), TQT_TQOBJECT(this), TQT_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(TQT_TQOBJECT(this), TQT_SLOT(startGame()), actionCollection());
|
|
act_demo = KStdGameAction::demo(TQT_TQOBJECT(this), TQT_SLOT(startDemo()), actionCollection());
|
|
act_demo->setText(i18n("Start &Tutorial"));
|
|
KStdGameAction::highscores(TQT_TQOBJECT(this), TQT_SLOT(viewHighScore()), actionCollection());
|
|
KStdGameAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), actionCollection());
|
|
endTurnAction = KStdGameAction::endTurn(TQT_TQOBJECT(this), TQT_SLOT(makeTurn()), actionCollection());
|
|
showNextAction = new TDEToggleAction(i18n("&Show Next"), TDEShortcut(CTRL+Key_P),
|
|
TQT_TQOBJECT(this), TQT_SLOT(switchPrompt()), actionCollection(), "options_show_next");
|
|
showNextAction->setCheckedState(i18n("Hide Next"));
|
|
showNumberedAction = new TDEToggleAction(i18n("&Use Numbered Balls"), TDEShortcut(),
|
|
TQT_TQOBJECT(this), TQT_SLOT(switchNumbered()), actionCollection(), "options_show_numbered");
|
|
undoAction = KStdGameAction::undo(TQT_TQOBJECT(this), TQT_SLOT(undo()), actionCollection());
|
|
|
|
levelAction = KStdGameAction::chooseGameType(0, 0, actionCollection());
|
|
TQStringList items;
|
|
for (uint i=0; i<Nb_Levels; i++)
|
|
items.append( i18n(LEVEL[i]) );
|
|
levelAction->setItems(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, TQT_TQOBJECT(lsb), TQT_SLOT(moveLeft()), actionCollection(), "left");
|
|
(void)new TDEAction(i18n("Move Right"), Key_Right, TQT_TQOBJECT(lsb), TQT_SLOT(moveRight()), actionCollection(), "right");
|
|
(void)new TDEAction(i18n("Move Up"), Key_Up, TQT_TQOBJECT(lsb), TQT_SLOT(moveUp()), actionCollection(), "up");
|
|
(void)new TDEAction(i18n("Move Down"), Key_Down, TQT_TQOBJECT(lsb), TQT_SLOT(moveDown()), actionCollection(), "down");
|
|
(void)new TDEAction(i18n("Move Ball"), Key_Space, TQT_TQOBJECT(lsb), TQT_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);
|
|
}
|