summaryrefslogtreecommitdiffstats
path: root/kbattleship/kbattleship/kbattleship.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kbattleship/kbattleship/kbattleship.cpp')
-rw-r--r--kbattleship/kbattleship/kbattleship.cpp1352
1 files changed, 1352 insertions, 0 deletions
diff --git a/kbattleship/kbattleship/kbattleship.cpp b/kbattleship/kbattleship/kbattleship.cpp
new file mode 100644
index 00000000..b7d38891
--- /dev/null
+++ b/kbattleship/kbattleship/kbattleship.cpp
@@ -0,0 +1,1352 @@
+/***************************************************************************
+ kbattleship.cpp
+ -----------------
+ Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
+ (c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include <qlayout.h>
+#include <qtimer.h>
+
+#include <kgamemisc.h>
+#include <kinputdialog.h>
+#include <knotifyclient.h>
+#include <knotifydialog.h>
+#include <kstandarddirs.h>
+#include <kstatusbar.h>
+#include <kstdgameaction.h>
+#include <kcmdlineargs.h>
+#include <kmessagebox.h>
+#include <kuser.h>
+
+#include <kscoredialog.h>
+
+
+#include "kbattleship.moc"
+
+extern const char *clientVersion;
+
+KBattleshipWindow::KBattleshipWindow() : KMainWindow()
+{
+ shift = false;
+ m_connection = 0;
+ m_lost = 0;
+ m_config = 0;
+ m_client = 0;
+ m_server = 0;
+ m_aiPlayer = 0;
+ m_aiHits = 0;
+
+ init();
+}
+
+KBattleshipWindow::~KBattleshipWindow()
+{
+ if(m_config != 0)
+ saveOptions();
+ delete m_aiPlayer;
+ delete m_ownshiplist;
+ delete m_enemyshiplist;
+}
+
+void KBattleshipWindow::init()
+{
+ m_aiPlaying = false;
+ m_placeable = false;
+ m_shootable = false;
+ m_serverHasClient = false;
+ m_config = kapp->config();
+ initStatusBar();
+ initActions();
+ readOptions();
+ initView();
+ initChat();
+ initShipPlacing();
+ parseCommandLine();
+}
+
+void KBattleshipWindow::slotConfigureNotifications()
+{
+ KNotifyDialog::configure(this);
+}
+
+void KBattleshipWindow::initStatusBar()
+{
+ m_ownNickname = "-";
+ m_enemyNickname = "-";
+ statusBar()->insertItem(i18n(" Player 1: %1 ").arg(m_ownNickname), ID_PLAYER_OWN, 0, true);
+ statusBar()->insertItem(i18n(" Player 2: %1 ").arg(m_enemyNickname), ID_PLAYER_ENEMY, 0, true);
+ statusBar()->insertItem(i18n("Ready"), ID_STATUS_MSG, 1);
+ statusBar()->setItemAlignment(ID_STATUS_MSG, AlignLeft);
+}
+
+void KBattleshipWindow::initActions()
+{
+ KStdAction::configureNotifications(this, SLOT(slotConfigureNotifications()), actionCollection());
+ m_gameServerConnect = new KAction(i18n("&Connect to Server..."), "connect_no", Key_F2, this, SLOT(slotServerConnect()), actionCollection(), "game_serverconnect");
+ m_gameNewServer = new KAction(i18n("&Start Server..."), "network", Key_F3, this, SLOT(slotNewServer()), actionCollection(), "game_newserver");
+ m_gameSingle = new KAction(i18n("S&ingle Player..."), "gear", Key_F4, this, SLOT(slotSinglePlayer()), actionCollection(), "game_singleplayer");
+ m_gameQuit = KStdGameAction::quit(this, SLOT(close()), actionCollection());
+ KStdGameAction::highscores(this, SLOT(slotHighscore()), actionCollection());
+ m_gameEnemyInfo = new KAction(i18n("&Enemy Info"), "view_text", Key_F11, this, SLOT(slotEnemyClientInfo()), actionCollection(), "game_enemyinfo");
+
+ m_configSound = new KToggleAction(i18n("&Play Sounds"), 0, actionCollection(), "options_configure_sound");
+ m_configGrid = new KToggleAction(i18n("&Show Grid"), 0, this, SLOT(slotShowGrid()), actionCollection(), "options_show_grid");
+ m_configGrid->setCheckedState(i18n("Hide Grid"));
+
+ m_gameEnemyInfo->setEnabled(false);
+
+ setupGUI( KMainWindow::Save | StatusBar | Keys | Create );
+}
+
+void KBattleshipWindow::initChat()
+{
+ connect(m_chat, SIGNAL(sigSendMessage(const QString &)), this, SLOT(slotSendChatMessage(const QString &)));
+ connect(m_chat, SIGNAL(sigChangeEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_chat, SIGNAL(sigChangeOwnNickname(const QString &)), this, SLOT(slotChangedNickCommand(const QString &)));
+}
+
+void KBattleshipWindow::changeShipPlacementDirection(){
+ shift = !shift;
+}
+
+void KBattleshipWindow::initShipPlacing()
+{
+ connect(m_ownshiplist, SIGNAL(sigOwnFieldDataChanged(int, int, int)), this, SLOT(slotChangeOwnFieldData(int, int, int)));
+ connect(m_ownshiplist, SIGNAL(sigLastShipAdded()), this, SLOT(slotShipsReady()));
+}
+
+void KBattleshipWindow::initView()
+{
+ QWidget *dummy = new QWidget(this, "dummy");
+ setCentralWidget(dummy);
+
+ QGridLayout *topLayout = new QGridLayout(dummy, 2, 2, 0, -1, "topLayout");
+
+ m_chat = new KChatWidget(dummy);
+ m_view = new KBattleshipView(dummy, "", m_configGrid->isChecked());
+ m_stat = new KStatDialog(dummy);
+ topLayout->setColStretch(1, 10);
+ topLayout->setRowStretch(1, 10);
+ topLayout->addWidget(m_view, 0, 0);
+ topLayout->addWidget(m_stat, 0, 1);
+ topLayout->addMultiCellWidget(m_chat, 1, 1, 0, 1);
+
+ m_ownshiplist = new KShipList();
+ m_enemyshiplist = new KShipList();
+
+ m_view->startDrawing();
+ setFocusProxy(m_view);
+
+ connect(m_view, SIGNAL(sigEnemyFieldClicked(int, int)), this, SLOT(slotEnemyFieldClick(int, int)));
+ connect(m_view, SIGNAL(sigOwnFieldClicked(int, int)), this, SLOT(slotPlaceShip(int, int)));
+ connect(m_view, SIGNAL(sigMouseOverField(int, int)), this, SLOT(slotPlaceShipPreview(int, int)));
+ connect(m_view, SIGNAL(changeShipPlacementDirection()), this, SLOT(changeShipPlacementDirection()));
+}
+
+void KBattleshipWindow::slotDeleteAI()
+{
+ m_aiHits = 0;
+ delete m_aiPlayer;
+ m_aiPlayer = 0;
+}
+
+void KBattleshipWindow::slotRestartAI()
+{
+ m_aiHits = 0;
+ slotStartBattleshipGame(false);
+}
+
+void KBattleshipWindow::slotEnemyFieldClick(int fieldx, int fieldy)
+{
+ if(m_connection != 0 || m_aiPlaying)
+ {
+ if(!m_aiPlaying && m_connection == 0)
+ return;
+
+ if(!m_serverHasClient && m_connection != 0)
+ return;
+
+ if(!m_shootable)
+ return;
+
+ if(m_view->enemyFieldState(fieldx, fieldy) == KBattleField::FREE)
+ {
+ if(!m_aiPlaying && !m_lost)
+ {
+ slotStatusMsg(i18n("Sending Message..."));
+ KMessage *msg = new KMessage(KMessage::SHOOT);
+ msg->addField("fieldx", QString::number(fieldx));
+ msg->addField("fieldy", QString::number(fieldy));
+ slotSendMessage(msg);
+ }
+
+ if(m_stat->hit() != 10 && m_aiPlaying)
+ {
+ m_stat->setShot();
+
+ int showstate;
+
+ if(m_enemyshiplist->shipTypeAt(fieldx, fieldy) == 99)
+ {
+ m_stat->setWater();
+ showstate = KBattleField::WATER;
+ }
+ else
+ {
+ m_stat->setHit();
+ showstate = KBattleField::HIT;
+ }
+
+ slotChangeEnemyFieldData(fieldx, fieldy, showstate);
+
+ if(showstate == KBattleField::HIT)
+ {
+ KShip *ship = m_enemyshiplist->shipAt(fieldx, fieldy);
+ typedef QValueList<int> DeathValueList;
+ DeathValueList deathList;
+ bool xokay = true, yokay = true;
+ int tempy = 0, tempx = 0;
+
+ if(ship->placedLeft())
+ {
+ for(tempx = ship->shipxstart(); tempx <= ship->shipxstop(); tempx++)
+ {
+ if(m_view->enemyFieldState(tempx, fieldy) == KBattleField::HIT)
+ {
+ deathList.append(tempx);
+ xokay = true;
+ yokay = false;
+ }
+ else
+ {
+ xokay = false;
+ yokay = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for(tempy = ship->shipystart(); tempy <= ship->shipystop(); tempy++)
+ {
+ if(m_view->enemyFieldState(fieldx, tempy) == KBattleField::HIT)
+ {
+ deathList.append(tempy);
+ xokay = false;
+ yokay = true;
+ }
+ else
+ {
+ xokay = false;
+ yokay = false;
+ break;
+ }
+ }
+ }
+
+ if(xokay)
+ {
+ DeathValueList::Iterator it;
+ for(it = deathList.begin(); it != deathList.end(); ++it)
+ {
+ if(fieldy+1 < m_enemyshiplist->m_fieldy) m_view->changeEnemyFieldData(*it, fieldy+1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(*it, fieldy, KBattleField::DEATH);
+ if(fieldy > 0) m_view->changeEnemyFieldData(*it, fieldy-1, KBattleField::BORDER);
+ }
+ if(ship->shipxstart() > 0)
+ {
+ if (fieldy > 0) m_view->changeEnemyFieldData(ship->shipxstart()-1, fieldy-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(ship->shipxstart()-1, fieldy, KBattleField::BORDER);
+ if (fieldy < m_enemyshiplist->m_fieldy) m_view->changeEnemyFieldData(ship->shipxstart()-1, fieldy+1, KBattleField::BORDER);
+ }
+ if(ship->shipxstop() < m_enemyshiplist->m_fieldx)
+ {
+ if (fieldy>0) m_view->changeEnemyFieldData(ship->shipxstop()+1, fieldy-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(ship->shipxstop()+1, fieldy, KBattleField::BORDER);
+ if (fieldy < m_enemyshiplist->m_fieldy)m_view->changeEnemyFieldData(ship->shipxstop()+1,fieldy+1, KBattleField::BORDER);
+ }
+ }
+ else if(yokay)
+ {
+ DeathValueList::Iterator it;
+ for(it = deathList.begin(); it != deathList.end(); ++it)
+ {
+ if (fieldx>0) m_view->changeEnemyFieldData(fieldx-1, *it, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, *it, KBattleField::DEATH);
+ if(fieldx<m_enemyshiplist->m_fieldx) m_view->changeEnemyFieldData(fieldx+1, *it, KBattleField::BORDER);
+ }
+ if(ship->shipystart()>0)
+ {
+ if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ship->shipystart()-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, ship->shipystart()-1, KBattleField::BORDER);
+ if (fieldx<m_enemyshiplist->m_fieldx)m_view->changeEnemyFieldData(fieldx+1, ship->shipystart()-1, KBattleField::BORDER);
+ }
+ if(ship->shipystop()<m_enemyshiplist->m_fieldy)
+ {
+ if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ship->shipystop()+1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, ship->shipystop()+1, KBattleField::BORDER);
+ if (fieldx<m_enemyshiplist->m_fieldx)m_view->changeEnemyFieldData(fieldx+1, ship->shipystop()+1, KBattleField::BORDER);
+ }
+ }
+ }
+ }
+
+ if(m_stat->hit() == 10 && m_aiPlaying)
+ {
+ m_aiPlaying = false;
+ m_shootable = false;
+ slotChangeOwnPlayer("-");
+ slotChangeEnemyPlayer("-");
+ m_gameSingle->setText(i18n("S&ingle Player"));
+ m_gameNewServer->setEnabled(true);
+ m_gameServerConnect->setEnabled(true);
+ slotStatusMsg(i18n("You won the game :)"));
+ m_stat->slotAddOwnWon();
+ slotUpdateHighscore();
+ switch(KMessageBox::questionYesNo(this, i18n("Do you want to restart the game?"),QString::null,i18n("Restart"),i18n("Do Not Restart")))
+ {
+ case KMessageBox::Yes:
+ QTimer::singleShot(0, this, SLOT(slotRestartAI()));
+ break;
+
+ case KMessageBox::No:
+ QTimer::singleShot(0, this, SLOT(slotDeleteAI()));
+ break;
+ }
+ return;
+ }
+ else if(m_aiPlayer != 0 && m_aiPlaying)
+ m_aiPlayer->slotRequestShot();
+ }
+ }
+}
+
+void KBattleshipWindow::slotReceivedEnemyFieldData(int fieldx, int fieldy, int enemystate, int xstart, int xstop, int ystart, int ystop, bool death)
+{
+ m_stat->setShot();
+
+ int showstate;
+
+ if(enemystate == 99)
+ {
+ m_stat->setWater();
+ showstate = KBattleField::WATER;
+ }
+ else
+ {
+ m_stat->setHit();
+ showstate = KBattleField::HIT;
+ }
+
+ slotChangeEnemyFieldData(fieldx, fieldy, showstate);
+
+ if(death)
+ {
+ if(xstart == xstop)
+ {
+ for(int i = ystart; i <= ystop; i++)
+ {
+ if (fieldx>0) m_view->changeEnemyFieldData(fieldx-1, i, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, i, KBattleField::DEATH);
+ if(fieldx<m_enemyshiplist->m_fieldx) m_view->changeEnemyFieldData(fieldx+1, i, KBattleField::BORDER);
+ }
+ if(ystart>0)
+ {
+ if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ystart-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, ystart-1, KBattleField::BORDER);
+ if (fieldx<m_enemyshiplist->m_fieldx)m_view->changeEnemyFieldData(fieldx+1, ystart-1, KBattleField::BORDER);
+ }
+ if(ystop<m_enemyshiplist->m_fieldy)
+ {
+ if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ystop+1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(fieldx, ystop+1, KBattleField::BORDER);
+ if (fieldx<m_enemyshiplist->m_fieldx)m_view->changeEnemyFieldData(fieldx+1, ystop+1, KBattleField::BORDER);
+ }
+ }
+ else if(ystart == ystop)
+ {
+ for(int i = xstart; i <= xstop; i++)
+ {
+ if(fieldy+1 < m_enemyshiplist->m_fieldy) m_view->changeEnemyFieldData(i, fieldy+1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(i, fieldy, KBattleField::DEATH);
+ if(fieldy > 0) m_view->changeEnemyFieldData(i, fieldy-1, KBattleField::BORDER);
+ }
+ if(xstart > 0)
+ {
+ if (fieldy > 0) m_view->changeEnemyFieldData(xstart-1, fieldy-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(xstart-1, fieldy, KBattleField::BORDER);
+ if (fieldy < m_enemyshiplist->m_fieldy) m_view->changeEnemyFieldData(xstart-1, fieldy+1, KBattleField::BORDER);
+ }
+ if(xstop < m_enemyshiplist->m_fieldx)
+ {
+ if (fieldy>0) m_view->changeEnemyFieldData(xstop+1, fieldy-1, KBattleField::BORDER);
+ m_view->changeEnemyFieldData(xstop+1, fieldy, KBattleField::BORDER);
+ if (fieldy < m_enemyshiplist->m_fieldy)m_view->changeEnemyFieldData(xstop+1,fieldy+1, KBattleField::BORDER);
+ }
+ }
+ }
+
+ if(m_stat->hit() != 10)
+ slotStatusMsg(i18n("Waiting for enemy to shoot.."));
+ else
+ {
+ KMessage *msg = m_view->getAliveShips(m_ownshiplist); // let's show ai player ships
+ slotSendMessage(msg);
+ slotStatusMsg(i18n("You won the game :)"));
+ m_stat->slotAddOwnWon();
+ slotUpdateHighscore();
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ slotServerReplay();
+ else
+ slotClientReplay();
+ }
+}
+
+void KBattleshipWindow::slotClientLost()
+{
+ slotAbortNetworkGame();
+ slotStatusMsg(i18n("Enemy disconnected."));
+}
+
+void KBattleshipWindow::slotServerLost()
+{
+ slotAbortNetworkGame();
+ slotStatusMsg(i18n("Enemy disconnected."));
+}
+
+void KBattleshipWindow::slotAbortNetworkGame()
+{
+ slotStatusMsg(i18n("Ready"));
+ slotChangeOwnPlayer("-");
+ slotChangeEnemyPlayer("-");
+
+ m_gameServerConnect->setText(i18n("&Connect to server"));
+ m_gameNewServer->setText(i18n("&Start server"));
+ m_gameSingle->setText(i18n("S&ingle game"));
+ m_gameServerConnect->setEnabled(true);
+ m_gameNewServer->setEnabled(true);
+ m_gameSingle->setEnabled(true);
+ m_gameEnemyInfo->setEnabled(false);
+
+ m_chat->clear();
+
+ m_aiPlaying = false;
+ m_shootable = false;
+ m_placeable = false;
+ m_serverHasClient = false;
+
+ if (m_connection)
+ {
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ {
+ delete m_kbserver;
+ m_kbserver = 0;
+ }
+ else
+ {
+ delete m_kbclient;
+ m_kbclient = 0;
+ }
+ delete m_connection;
+ m_connection = 0;
+ }
+}
+
+void KBattleshipWindow::slotReplay()
+{
+ cleanup(true);
+ m_aiPlaying = false;
+ m_shootable = false;
+ m_lost = false;
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ m_placeable = true;
+ else
+ m_placeable = false;
+ m_stat->clear();
+}
+
+void KBattleshipWindow::slotPlaceShipPreview(int fieldx, int fieldy)
+{
+ int xadd = 0, yadd = 0;
+
+ if(m_connection != 0 || m_aiPlaying)
+ {
+ if(!m_aiPlaying && m_connection == 0)
+ return;
+
+ if(m_connection != 0 && !m_aiPlaying && !m_serverHasClient)
+ return;
+
+ if((m_placeable && m_ownshiplist->canAddShips()) || m_aiPlaying)
+ {
+ switch(m_ownshiplist->shipCount())
+ {
+ case 4:
+ for(int i = 0; i <= 3; i++)
+ {
+ if(!shift)
+ xadd = i;
+ else
+ yadd = i;
+ m_view->previewShip(fieldx + xadd, fieldy + yadd, KBattleField::SHIP4P1 + i, shift);
+ }
+ break;
+
+ case 3:
+ for(int i = 0; i <= 2; i++)
+ {
+ if(!shift)
+ xadd = i;
+ else
+ yadd = i;
+ m_view->previewShip(fieldx + xadd, fieldy + yadd, KBattleField::SHIP3P1 + i, shift);
+ }
+ break;
+
+ case 2:
+ for(int i = 0; i <= 1; i++)
+ {
+ if(!shift)
+ xadd = i;
+ else
+ yadd = i;
+ m_view->previewShip(fieldx + xadd, fieldy + yadd, KBattleField::SHIP2P1 + i, shift);
+ }
+ break;
+
+ case 1:
+ m_view->previewShip(fieldx, fieldy, KBattleField::SHIP1P1, shift);
+ break;
+ }
+
+ m_view->field()->drawField();
+ }
+ }
+}
+
+void KBattleshipWindow::slotPlaceShip(int fieldx, int fieldy)
+{
+ if(m_connection != 0 || m_aiPlaying)
+ {
+ if(!m_aiPlaying && m_connection == 0)
+ return;
+
+ if(m_connection != 0 && !m_aiPlaying && !m_serverHasClient)
+ return;
+
+ if(m_placeable && m_ownshiplist->canAddShips())
+ m_ownshiplist->addNewShip(shift, fieldx, fieldy);
+ }
+}
+
+void KBattleshipWindow::slotShipsReady()
+{
+ if(m_aiPlaying)
+ {
+ slotStatusMsg(i18n("Waiting for computer player to start the match..."));
+ m_placeable = false;
+ m_aiPlayer->slotRequestShot();
+ return;
+ }
+
+ KMessage *msg = new KMessage(KMessage::SHIPSREADY);
+ slotSendMessage(msg);
+
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ slotStatusMsg(i18n("Waiting for other player to place their ships..."));
+ else
+ slotStatusMsg(i18n("Waiting for other player to start the match..."));
+
+ m_placeable = false;
+}
+
+void KBattleshipWindow::slotSendMessage(int fieldx, int fieldy, int state)
+{
+ if(m_connection != 0)
+ {
+ KMessage *msg = new KMessage(KMessage::ANSWER_SHOOT);
+ msg->addField(QString("fieldx"), QString::number(fieldx));
+ msg->addField(QString("fieldy"), QString::number(fieldy));
+ msg->addField(QString("fieldstate"), QString::number(state));
+
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ m_kbserver->sendMessage(msg);
+ else
+ m_kbclient->sendMessage(msg);
+ }
+}
+
+void KBattleshipWindow::slotSendMessage(KMessage *msg)
+{
+ if(m_connection != 0)
+ {
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ m_kbserver->sendMessage(msg);
+ else
+ m_kbclient->sendMessage(msg);
+ }
+}
+
+void KBattleshipWindow::slotSendChatMessage(const QString &text)
+{
+ if(m_connection != 0 && m_serverHasClient)
+ {
+ KMessage *msg = new KMessage(KMessage::CHAT);
+ msg->chatMessage(m_ownNickname, text);
+ slotSendMessage(msg);
+ }
+}
+
+void KBattleshipWindow::slotChangedNickCommand(const QString &text)
+{
+ m_ownNickname = text;
+ slotChangeOwnPlayer(m_ownNickname);
+ m_chat->setNickname(m_ownNickname);
+}
+
+KShip *KBattleshipWindow::shipAt(int fieldx, int fieldy)
+{
+ return m_ownshiplist->shipAt(fieldx, fieldy);
+}
+
+KShip *KBattleshipWindow::enemyShipAt(int fieldx, int fieldy)
+{
+ return m_enemyshiplist->shipAt(fieldx, fieldy);
+}
+
+void KBattleshipWindow::slotUpdateHighscore()
+{
+ // Balancing factors
+ // a = shot-balance
+ // b = water-balance
+ double a = 3;
+ double b = 0.5;
+ double score = (a * m_stat->hit() - b * m_stat->water()) / (m_stat->shot() + m_stat->water()) * 1000;
+ if(score == 0) score = 1;
+
+ KScoreDialog *scoreDialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Custom1 | KScoreDialog::Custom2 | KScoreDialog::Custom3, this);
+ scoreDialog->addField(KScoreDialog::Custom1, i18n("Shots"), "shots");
+ scoreDialog->addField(KScoreDialog::Custom2, i18n("Hits"), "hits");
+ scoreDialog->addField(KScoreDialog::Custom3, i18n("Water"), "water");
+
+ KScoreDialog::FieldInfo info;
+ info[KScoreDialog::Name] = m_ownNickname;
+ info[KScoreDialog::Custom1] = QString::number(m_stat->shot());
+ info[KScoreDialog::Custom2] = QString::number(m_stat->hit());
+ info[KScoreDialog::Custom3] = QString::number(m_stat->water());
+
+ scoreDialog->addScore((int)score, info, false, false);
+}
+
+void KBattleshipWindow::saveOptions()
+{
+ m_config->setGroup("General");
+ m_config->writeEntry("PlaySounds", m_configSound->isChecked());
+ m_config->writeEntry("ShowGrid", m_configGrid->isChecked());
+ m_config->sync();
+}
+
+void KBattleshipWindow::readOptions()
+{
+ m_config->setGroup("General");
+ m_configSound->setChecked(m_config->readBoolEntry("PlaySounds", true));
+ m_configGrid->setChecked(m_config->readBoolEntry("ShowGrid", false));
+}
+
+void KBattleshipWindow::slotHighscore()
+{
+ KScoreDialog *scoreDialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Custom1 | KScoreDialog::Custom2 | KScoreDialog::Custom3, this);
+ scoreDialog->addField(KScoreDialog::Custom1, i18n("Shots"), "shots");
+ scoreDialog->addField(KScoreDialog::Custom2, i18n("Hits"), "hits");
+ scoreDialog->addField(KScoreDialog::Custom3, i18n("Water"), "water");
+ scoreDialog->show();
+}
+
+void KBattleshipWindow::slotEnemyClientInfo()
+{
+ KInfoDialog *m_info = new KInfoDialog(this);
+
+ m_info->lbl_clientIdentfier->setText(m_enemyClient);
+ m_info->lbl_clientVersion->setText(m_enemyClientVersion);
+ m_info->lbl_ClientInformation->setText(m_enemyClientDescription);
+ m_info->lbl_ProtocolVersion->setText(m_enemyProtocolVersion);
+
+ m_info->show();
+}
+
+void KBattleshipWindow::slotServerConnect()
+{
+ if(m_connection == 0)
+ {
+ if(m_client != 0) {
+ m_client->show();
+ return;
+ }
+
+ slotStatusMsg(i18n("Loading Connect-Server dialog..."));
+
+ m_client = new KClientDialog(this);
+ connect(m_client, SIGNAL(sigConnectServer()), this, SLOT(slotConnectToBattleshipServer()));
+ connect(m_client, SIGNAL(sigCancelConnect()), this, SLOT(slotDeleteConnectDialog()));
+ m_client->show();
+
+ slotStatusMsg(i18n("Ready"));
+ }
+ else
+ slotAbortNetworkGame();
+}
+
+void KBattleshipWindow::slotDeleteConnectDialog()
+{
+ delete m_client;
+ m_client = 0;
+}
+
+void KBattleshipWindow::slotReplayRequest()
+{
+ switch(KMessageBox::questionYesNo(this, i18n("The client is asking to restart the game. Do you accept?"),QString::null,i18n("Accept Restart"), i18n("Deny Restart")))
+ {
+ case KMessageBox::Yes:
+ if (m_connection)
+ { // the client could have closed while the user was thinking if he wanted to replay
+ slotReplay();
+ slotStatusMsg(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
+ }
+ else slotAbortNetworkGame();
+ break;
+
+ case KMessageBox::No:
+ slotAbortNetworkGame();
+ break;
+ }
+}
+
+void KBattleshipWindow::slotServerReplay()
+{
+ KMessage *msg = new KMessage(KMessage::REPLAY);
+ switch(KMessageBox::questionYesNo(this, i18n("Do you want to restart the game?"), QString::null, i18n("Restart"), i18n("Do Not Restart")))
+ {
+ case KMessageBox::Yes:
+ if (m_connection)
+ { // the client could have closed while the user was thinking if he wanted to replay
+ slotReplay();
+ slotStatusMsg(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
+ slotSendMessage(msg);
+ }
+ else
+ {
+ delete msg;
+ slotAbortNetworkGame();
+ }
+ break;
+
+ case KMessageBox::No:
+ delete msg;
+ slotAbortNetworkGame();
+ break;
+ }
+}
+
+void KBattleshipWindow::slotClientReplay()
+{
+ KMessage *msg = new KMessage(KMessage::REPLAY);
+ switch(KMessageBox::questionYesNo(this, i18n("Do you want to ask the server restarting the game?"), QString::null, i18n("Ask to Restart"), i18n("Do Not Ask")))
+ {
+ case KMessageBox::Yes:
+ if (m_connection)
+ { // the server could have closed while the user was thinking if he wanted to replay
+ slotReplay();
+ slotStatusMsg(i18n("Waiting for an answer..."));
+ slotSendMessage(msg);
+ }
+ else
+ {
+ delete msg;
+ slotAbortNetworkGame();
+ }
+ break;
+
+ case KMessageBox::No:
+ delete msg;
+ slotAbortNetworkGame();
+ break;
+ }
+}
+
+void KBattleshipWindow::cleanup(bool placechange)
+{
+ if(placechange)
+ m_placeable = false;
+ m_view->field()->setDrawField(false);
+ m_ownshiplist->clear();
+ m_enemyshiplist->clear();
+ m_view->clearField();
+ m_view->field()->setDrawField(true);
+ m_view->field()->drawField();
+}
+
+void KBattleshipWindow::slotNewServer()
+{
+ if(m_connection == 0)
+ {
+ if(m_server != 0)
+ return;
+
+ slotStatusMsg(i18n("Loading Start-Server dialog..."));
+
+ m_server = new KServerDialog(this);
+ connect(m_server, SIGNAL(okClicked()), this, SLOT(slotStartBattleshipServer()));
+ connect(m_server, SIGNAL(cancelClicked()), this, SLOT(slotDeleteServerDialog()));
+ m_server->show();
+
+ slotStatusMsg(i18n("Ready"));
+ }
+ else
+ slotAbortNetworkGame();
+}
+
+void KBattleshipWindow::slotDeleteServerDialog()
+{
+ delete m_server;
+ m_server = 0;
+}
+
+void KBattleshipWindow::slotSendVersion()
+{
+ KMessage *msg = new KMessage(KMessage::GETVERSION);
+ msg->versionMessage();
+ slotSendMessage(msg);
+
+ QTimer::singleShot(150, this, SLOT(slotSendGreet()));
+}
+
+void KBattleshipWindow::slotSendGreet()
+{
+ m_serverHasClient = true;
+ m_chat->slotAcceptMsg(true);
+
+ KMessage *msg = new KMessage(KMessage::GREET);
+ msg->addField(QString("nickname"), m_ownNickname);
+ slotSendMessage(msg);
+}
+
+void KBattleshipWindow::slotStartBattleshipServer()
+{
+ m_gameNewServer->setText(i18n("&Stop server"));
+ m_gameServerConnect->setEnabled(false);
+ m_gameSingle->setEnabled(false);
+ slotStatusMsg(i18n("Waiting for a player..."));
+ m_kbserver = new KBattleshipServer((m_server->port()).toInt(),m_server->gamename());
+ m_ownNickname = m_server->nickname();
+ m_chat->setNickname(m_ownNickname);
+ slotChangeOwnPlayer(m_ownNickname);
+ delete m_server;
+ m_server = 0;
+ cleanup(true);
+ m_aiPlaying = false;
+ m_shootable = false;
+ m_placeable = true;
+ m_stat->clear();
+ m_stat->clearWon();
+ if(m_connection == 0)
+ {
+ m_connection = new KonnectionHandling(this, m_kbserver);
+ connect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ connect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_connection, SIGNAL(sigSendNickname()), this, SLOT(slotSendGreet()));
+ connect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ connect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ connect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ connect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ connect(m_connection, SIGNAL(sigClientLost()), this, SLOT(slotClientLost()));
+ connect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ connect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplayRequest()));
+ connect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ connect(m_connection, SIGNAL(sigClientInformation(const QString &, const QString &, const QString &, const QString &)), this, SLOT(slotReceivedClientInformation(const QString &, const QString &, const QString &, const QString &)));
+ connect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ }
+ else
+ {
+ if(m_connection->type() == KonnectionHandling::CLIENT)
+ {
+ disconnect(m_kbclient, SIGNAL(sigConnected()), this, SLOT(slotSendVersion()));
+ disconnect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ disconnect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ disconnect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ disconnect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ disconnect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ disconnect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ disconnect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ disconnect(m_connection, SIGNAL(sigServerLost()), this, SLOT(slotServerLost()));
+ disconnect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplay()));
+ disconnect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ disconnect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ m_connection->updateInternal(m_kbserver);
+ connect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ connect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_connection, SIGNAL(sigSendNickname()), this, SLOT(slotSendGreet()));
+ connect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ connect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ connect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ connect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ connect(m_connection, SIGNAL(sigClientLost()), this, SLOT(slotClientLost()));
+ connect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ connect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplayRequest()));
+ connect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ connect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ }
+ else
+ m_connection->updateInternal(m_kbserver);
+ }
+ m_kbserver->init();
+}
+
+void KBattleshipWindow::slotLost(KMessage *msg)
+{
+ m_stat->slotAddEnemyWon();
+ if (!msg->field("ship0").isNull()) m_view->drawEnemyShipsHuman(msg, m_enemyshiplist);
+ m_lost = true;
+}
+
+void KBattleshipWindow::slotSendEnemyFieldState(int fieldx, int fieldy)
+{
+ int data, showstate;
+ bool xokay = false, yokay = false, is_kill = false;
+ typedef QValueList<int> DeathValueList;
+ DeathValueList deathList;
+
+ data = m_ownshiplist->shipTypeAt(fieldx, fieldy);
+ if(data == 99)
+ showstate = KBattleField::WATER;
+ else
+ showstate = KBattleField::HIT;
+
+ slotChangeOwnFieldData(fieldx, fieldy, showstate);
+
+ KMessage *msg = new KMessage(KMessage::ANSWER_SHOOT);
+
+ if(showstate == KBattleField::HIT)
+ {
+ if(m_ownshiplist->shipTypeAt(fieldx, fieldy) != 0 && m_ownshiplist->shipTypeAt(fieldx, fieldy) != 99)
+ {
+ KShip *ship = m_ownshiplist->shipAt(fieldx, fieldy);
+ int tempy = 0, tempx = 0;
+
+ if(ship->shipystart() == ship->shipystop() && ship->shipxstart() != ship->shipxstop())
+ {
+ for(tempx = ship->shipxstart(); tempx <= ship->shipxstop(); tempx++)
+ {
+ if(m_view->ownFieldState(tempx, fieldy) == KBattleField::HIT)
+ {
+ deathList.append(tempx);
+ xokay = true;
+ yokay = false;
+ }
+ else
+ {
+ xokay = false;
+ yokay = false;
+ break;
+ }
+ }
+ }
+ else if(ship->shipystart() != ship->shipystop() && ship->shipxstart() == ship->shipxstop())
+ {
+ for(tempy = ship->shipystart(); tempy <= ship->shipystop(); tempy++)
+ {
+ if(m_view->ownFieldState(fieldx, tempy) == KBattleField::HIT)
+ {
+ deathList.append(tempy);
+ xokay = false;
+ yokay = true;
+ }
+ else
+ {
+ xokay = false;
+ yokay = false;
+ break;
+ }
+ }
+ }
+ }
+ else if(m_ownshiplist->shipTypeAt(fieldx, fieldy) == 0)
+ {
+ msg->addField(QString("xstart"), QString::number(fieldx));
+ msg->addField(QString("xstop"), QString::number(fieldx));
+ msg->addField(QString("ystart"), QString::number(fieldy));
+ msg->addField(QString("ystop"), QString::number(fieldy));
+ msg->addField(QString("death"), QString("true"));
+ is_kill = true;
+ }
+ }
+
+ msg->addField(QString("fieldx"), QString::number(fieldx));
+ msg->addField(QString("fieldy"), QString::number(fieldy));
+
+ if(xokay)
+ {
+ msg->addField(QString("xstart"), QString::number(deathList.first()));
+ msg->addField(QString("xstop"), QString::number(deathList.last()));
+ msg->addField(QString("ystart"), QString::number(fieldy));
+ msg->addField(QString("ystop"), QString::number(fieldy));
+ msg->addField(QString("death"), QString("true"));
+ is_kill = true;
+ }
+ else if(yokay)
+ {
+ msg->addField(QString("xstart"), QString::number(fieldx));
+ msg->addField(QString("xstop"), QString::number(fieldx));
+ msg->addField(QString("ystart"), QString::number(deathList.first()));
+ msg->addField(QString("ystop"), QString::number(deathList.last()));
+ msg->addField(QString("death"), QString("true"));
+ is_kill = true;
+ }
+
+ if(is_kill)
+ // If sunk, reveal ship type
+ msg->addField(QString("fieldstate"), QString::number(data));
+ else if(showstate == KBattleField::HIT)
+ // On non-fatal hit, keep ship type secret
+ msg->addField(QString("fieldstate"), QString::number(1));
+ else /* showstate == KBattleField::WATER */
+ // Miss
+ msg->addField(QString("fieldstate"), QString::number(99));
+
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ m_kbserver->sendMessage(msg);
+ else
+ m_kbclient->sendMessage(msg);
+}
+
+void KBattleshipWindow::slotChangeOwnFieldData(int fieldx, int fieldy, int type)
+{
+ m_view->changeOwnFieldData(fieldx, fieldy, type);
+ playSound(true, type);
+}
+
+void KBattleshipWindow::playSound(bool enemy, int fieldstate)
+{
+ if (m_configSound->isChecked())
+ {
+ switch(fieldstate)
+ {
+ case KBattleField::WATER:
+ KNotifyClient::event(winId(), "shoot_water");
+ break;
+
+ case KBattleField::HIT:
+ if(enemy)
+ KNotifyClient::event(winId(), "shoot_hit_1");
+ else
+ KNotifyClient::event(winId(), "shoot_hit_2");
+ break;
+
+ case KBattleField::DEATH:
+ KNotifyClient::event(winId(), "shoot_sink");
+ break;
+ }
+ }
+}
+
+void KBattleshipWindow::slotChangeEnemyFieldData(int fieldx, int fieldy, int type)
+{
+ m_view->changeEnemyFieldData(fieldx, fieldy, type);
+ playSound(false, type);
+}
+
+void KBattleshipWindow::parseCommandLine() {
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if ( args->count() > 0 )
+ {
+ KURL u( args->url(0));
+ if(u.protocol().isEmpty())
+ u.setProtocol("kbattleship");
+ if( !u.isValid()) {
+ KMessageBox::sorry(this,
+ i18n("The URL passed to KDE Battleship '%1' is not a valid url")
+ .arg(args->arg(0)));
+ return;
+ }
+ if( u.protocol() != "kbattleship" ) {
+ KMessageBox::sorry(this,
+ i18n("The URL passed to KDE Battleship '%1' is not recognised "
+ "as a Battleship game.")
+ .arg(args->arg(0)));
+ return;
+ }
+
+ slotConnectToBattleshipServer(u.host(), u.port(), u.user());
+
+ }
+
+}
+
+void KBattleshipWindow::slotConnectToBattleshipServer()
+{
+ QString host = m_client->host();
+ int port = m_client->port().toInt();
+ QString nickname = m_client->nickname();
+ delete m_client;
+ m_client = 0;
+ slotConnectToBattleshipServer(host, port, nickname);
+}
+void KBattleshipWindow::slotConnectToBattleshipServer(const QString &host, int port, const QString &nickname)
+{
+ m_kbclient = new KBattleshipClient(host, port);
+ nickname.isEmpty() ? m_ownNickname = "TestUser" : m_ownNickname = nickname;
+ m_chat->setNickname(m_ownNickname);
+ slotChangeOwnPlayer(m_ownNickname);
+ cleanup(true);
+ m_aiPlaying = false;
+ m_shootable = false;
+ m_placeable = false;
+ m_stat->clear();
+ m_stat->clearWon();
+ m_gameServerConnect->setText(i18n("Dis&connect from server"));
+ m_gameNewServer->setEnabled(false);
+ m_gameSingle->setEnabled(false);
+ if(m_connection == 0)
+ {
+ m_connection = new KonnectionHandling(this, m_kbclient);
+ connect(m_kbclient, SIGNAL(sigConnected()), this, SLOT(slotSendVersion()));
+ connect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ connect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ connect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ connect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ connect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ connect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ connect(m_connection, SIGNAL(sigServerLost()), this, SLOT(slotServerLost()));
+ connect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplay()));
+ connect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ connect(m_connection, SIGNAL(sigClientInformation(const QString &, const QString &, const QString &, const QString &)), this, SLOT(slotReceivedClientInformation(const QString &, const QString &, const QString &, const QString &)));
+ connect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ }
+ else
+ {
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ {
+ disconnect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ disconnect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ disconnect(m_connection, SIGNAL(sigSendNickname()), this, SLOT(slotSendGreet()));
+ disconnect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ disconnect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ disconnect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ disconnect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ disconnect(m_connection, SIGNAL(sigClientLost()), this, SLOT(slotClientLost()));
+ disconnect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ disconnect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplayRequest()));
+ disconnect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ disconnect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ m_connection->updateInternal(m_kbclient);
+ connect(m_kbclient, SIGNAL(sigConnected()), this, SLOT(slotSendVersion()));
+ connect(m_connection, SIGNAL(sigAbortNetworkGame()), this, SLOT(slotAbortNetworkGame()));
+ connect(m_connection, SIGNAL(sigStatusBar(const QString &)), this, SLOT(slotStatusMsg(const QString &)));
+ connect(m_connection, SIGNAL(sigEnemyNickname(const QString &)), this, SLOT(slotChangeEnemyPlayer(const QString &)));
+ connect(m_connection, SIGNAL(sigSendFieldState(int, int)), this, SLOT(slotSendEnemyFieldState(int, int)));
+ connect(m_connection, SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
+ connect(m_connection, SIGNAL(sigShootable(bool)), this, SLOT(slotSetShootable(bool)));
+ connect(m_connection, SIGNAL(sigPlaceShips(bool)), this, SLOT(slotSetPlaceable(bool)));
+ connect(m_connection, SIGNAL(sigServerLost()), this, SLOT(slotServerLost()));
+ connect(m_connection, SIGNAL(sigReplay()), this, SLOT(slotReplay()));
+ connect(m_connection, SIGNAL(sigChatMessage(const QString &, const QString &, bool)), m_chat, SLOT(slotReceivedMessage(const QString &, const QString &, bool)));
+ m_kbclient->init();
+ connect(m_connection, SIGNAL(sigClientInformation(const QString &, const QString &, const QString &, const QString &)), this, SLOT(slotReceivedClientInformation(const QString &, const QString &, const QString &, const QString &)));
+ connect(m_connection, SIGNAL(sigLost(KMessage *)), this, SLOT(slotLost(KMessage *)));
+ }
+ else
+ m_connection->updateInternal(m_kbclient);
+ }
+ m_kbclient->init();
+}
+
+void KBattleshipWindow::slotSetPlaceable(bool place)
+{
+ m_placeable = place;
+}
+
+void KBattleshipWindow::slotSetShootable(bool shoot)
+{
+ m_shootable = shoot;
+}
+
+void KBattleshipWindow::slotShowGrid()
+{
+ if(!m_configGrid->isChecked())
+ m_view->field()->disableGrid();
+ else
+ m_view->field()->enableGrid();
+}
+
+void KBattleshipWindow::slotStatusMsg(const QString &text)
+{
+ statusBar()->clear();
+ statusBar()->changeItem(text, ID_STATUS_MSG);
+}
+
+void KBattleshipWindow::slotChangeOwnPlayer(const QString &text)
+{
+ statusBar()->clear();
+ statusBar()->changeItem(i18n(" Player 1: %1 ").arg(text), ID_PLAYER_OWN);
+}
+
+void KBattleshipWindow::slotChangeEnemyPlayer(const QString &text)
+{
+ statusBar()->clear();
+ statusBar()->changeItem(i18n(" Player 2: %1 ").arg(text), ID_PLAYER_ENEMY);
+}
+
+void KBattleshipWindow::slotSinglePlayer()
+{
+ bool ok;
+ if(!m_aiPlaying)
+ {
+ KUser u;
+ m_ownNickname = KInputDialog::getText(i18n("Start Game"), i18n("Nick name:"),
+ u.loginName(), &ok, this);
+ if (ok)
+ {
+ slotStatusMsg(i18n("Ready"));
+ slotStartBattleshipGame();
+ }
+ }
+ else
+ {
+ if(m_aiPlayer != 0)
+ {
+ m_aiPlaying = false;
+ slotChangeOwnPlayer("-");
+ slotChangeEnemyPlayer("-");
+ m_gameSingle->setText(i18n("S&ingle Player"));
+ m_gameNewServer->setEnabled(true);
+ m_gameServerConnect->setEnabled(true);
+ slotStatusMsg(i18n("Ready"));
+ m_stat->clear();
+ m_chat->clear();
+ QTimer::singleShot(0, this, SLOT(slotDeleteAI()));
+ cleanup(false);
+ }
+ }
+}
+
+void KBattleshipWindow::slotStartBattleshipGame()
+{
+ slotStartBattleshipGame(true);
+}
+
+void KBattleshipWindow::slotStartBattleshipGame(bool clearstat)
+{
+ m_gameSingle->setText(i18n("&Stop game"));
+ m_gameNewServer->setEnabled(false);
+ m_gameServerConnect->setEnabled(false);
+ slotStatusMsg(i18n("Waiting for the AI player to place the ships..."));
+ slotChangeOwnPlayer(m_ownNickname);
+ slotChangeEnemyPlayer(KGameMisc::randomName());
+ cleanup(true);
+ if(m_connection != 0)
+ {
+ delete m_connection;
+ m_connection = 0;
+ }
+ m_aiPlaying = true;
+ m_shootable = false;
+ m_stat->clear();
+ if(clearstat)
+ m_stat->clearWon();
+
+ if(m_aiPlayer == 0)
+ {
+ m_aiPlayer = new KBAIPlayer();
+ m_aiPlayer->init(m_view->field(), m_enemyshiplist);
+ connect(m_aiPlayer, SIGNAL(sigReady()), this, SLOT(slotAIReady()));
+ connect(m_aiPlayer, SIGNAL(sigShootAt(const QPoint)), this, SLOT(slotAIShootsAt(const QPoint)));
+ }
+ m_aiPlayer->slotRestart();
+}
+
+void KBattleshipWindow::slotAIReady()
+{
+ slotStatusMsg(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
+ m_placeable = true;
+}
+
+void KBattleshipWindow::slotAIShootsAt(const QPoint pos)
+{
+ if(!m_shootable)
+ m_shootable = true;
+
+ int showstate = m_view->ownFieldState(pos.x(), pos.y());
+
+ if(showstate == KBattleField::HIT)
+ {
+ m_aiPlayer->slotRequestShot();
+ return;
+ }
+ else if(showstate == KBattleField::FREE)
+ showstate = KBattleField::WATER;
+ else if(showstate >= KBattleField::SHIP1P1)
+ {
+ showstate = KBattleField::HIT;
+ m_aiHits++;
+ }
+
+ slotStatusMsg(i18n("Enemy has shot. Shoot now."));
+ slotChangeOwnFieldData(pos.x(), pos.y(), showstate);
+
+ if(m_aiHits == 10 && m_stat->hit() != 10)
+ {
+ m_aiPlaying = false;
+ m_shootable = false;
+ slotChangeOwnPlayer("-");
+ slotChangeEnemyPlayer("-");
+ m_gameSingle->setText(i18n("S&ingle Player"));
+ m_gameNewServer->setEnabled(true);
+ m_gameServerConnect->setEnabled(true);
+ slotStatusMsg(i18n("You lost the game. :("));
+ m_stat->slotAddEnemyWon();
+ slotUpdateHighscore();
+ m_view->drawEnemyShipsAI(m_enemyshiplist); // let's show ai player ships
+ switch(KMessageBox::questionYesNo(this, i18n("Do you want to restart the game?"), QString::null, i18n("Restart"), i18n("Do Not Restart")))
+ {
+ case KMessageBox::Yes:
+ QTimer::singleShot(0, this, SLOT(slotRestartAI()));
+ break;
+
+ case KMessageBox::No:
+ QTimer::singleShot(0, this, SLOT(slotDeleteAI()));
+ break;
+ }
+ }
+ else
+ {
+ if(!m_shootable)
+ m_shootable = true;
+ }
+}
+
+void KBattleshipWindow::slotReceivedClientInformation(const QString &clientName, const QString &clientVersion, const QString &clientDescription, const QString &protocolVersion)
+{
+ m_enemyClient = clientName;
+ m_enemyClientVersion = clientVersion;
+ m_enemyClientDescription = clientDescription;
+ m_enemyProtocolVersion = protocolVersion;
+ m_gameEnemyInfo->setEnabled(true);
+
+ if(m_connection->type() == KonnectionHandling::SERVER)
+ {
+ KMessage *msg = new KMessage(KMessage::GETVERSION);
+ msg->versionMessage();
+ slotSendMessage(msg);
+ }
+}