/*************************************************************************** kbattleship.cpp ----------------- Developers: (c) 2000-2001 Nikolas Zimmermann (c) 2000-2001 Daniel Molkentin ***************************************************************************/ /*************************************************************************** * * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include "kbattleship.moc" extern const char *clientVersion; KBattleshipWindow::KBattleshipWindow() : TDEMainWindow() { 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(TQT_TQOBJECT(this), TQT_SLOT(slotConfigureNotifications()), actionCollection()); m_gameServerConnect = new TDEAction(i18n("&Connect to Server..."), "connect_no", Key_F2, TQT_TQOBJECT(this), TQT_SLOT(slotServerConnect()), actionCollection(), "game_serverconnect"); m_gameNewServer = new TDEAction(i18n("&Start Server..."), "network", Key_F3, TQT_TQOBJECT(this), TQT_SLOT(slotNewServer()), actionCollection(), "game_newserver"); m_gameSingle = new TDEAction(i18n("S&ingle Player..."), "gear", Key_F4, TQT_TQOBJECT(this), TQT_SLOT(slotSinglePlayer()), actionCollection(), "game_singleplayer"); m_gameQuit = KStdGameAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), actionCollection()); KStdGameAction::highscores(TQT_TQOBJECT(this), TQT_SLOT(slotHighscore()), actionCollection()); m_gameEnemyInfo = new TDEAction(i18n("&Enemy Info"), "view_text", Key_F11, TQT_TQOBJECT(this), TQT_SLOT(slotEnemyClientInfo()), actionCollection(), "game_enemyinfo"); m_configSound = new TDEToggleAction(i18n("&Play Sounds"), 0, actionCollection(), "options_configure_sound"); m_configGrid = new TDEToggleAction(i18n("&Show Grid"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotShowGrid()), actionCollection(), "options_show_grid"); m_configGrid->setCheckedState(i18n("Hide Grid")); m_gameEnemyInfo->setEnabled(false); setupGUI( TDEMainWindow::Save | StatusBar | Keys | Create ); } void KBattleshipWindow::initChat() { connect(m_chat, TQT_SIGNAL(sigSendMessage(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotSendChatMessage(const TQString &))); connect(m_chat, TQT_SIGNAL(sigChangeEnemyNickname(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotChangeEnemyPlayer(const TQString &))); connect(m_chat, TQT_SIGNAL(sigChangeOwnNickname(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotChangedNickCommand(const TQString &))); } void KBattleshipWindow::changeShipPlacementDirection(){ shift = !shift; } void KBattleshipWindow::initShipPlacing() { connect(m_ownshiplist, TQT_SIGNAL(sigOwnFieldDataChanged(int, int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotChangeOwnFieldData(int, int, int))); connect(m_ownshiplist, TQT_SIGNAL(sigLastShipAdded()), TQT_TQOBJECT(this), TQT_SLOT(slotShipsReady())); } void KBattleshipWindow::initView() { TQWidget *dummy = new TQWidget(this, "dummy"); setCentralWidget(dummy); TQGridLayout *topLayout = new TQGridLayout(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, TQT_SIGNAL(sigEnemyFieldClicked(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotEnemyFieldClick(int, int))); connect(m_view, TQT_SIGNAL(sigOwnFieldClicked(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotPlaceShip(int, int))); connect(m_view, TQT_SIGNAL(sigMouseOverField(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotPlaceShipPreview(int, int))); connect(m_view, TQT_SIGNAL(changeShipPlacementDirection()), TQT_TQOBJECT(this), TQT_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", TQString::number(fieldx)); msg->addField("fieldy", TQString::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 TQValueList 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(fieldxm_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 (fieldxm_fieldx)m_view->changeEnemyFieldData(fieldx+1, ship->shipystart()-1, KBattleField::BORDER); } if(ship->shipystop()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 (fieldxm_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?"),TQString(),i18n("Restart"),i18n("Do Not Restart"))) { case KMessageBox::Yes: TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotRestartAI())); break; case KMessageBox::No: TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_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(fieldxm_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 (fieldxm_fieldx)m_view->changeEnemyFieldData(fieldx+1, ystart-1, KBattleField::BORDER); } if(ystopm_fieldy) { if (fieldx>0)m_view->changeEnemyFieldData(fieldx-1, ystop+1, KBattleField::BORDER); m_view->changeEnemyFieldData(fieldx, ystop+1, KBattleField::BORDER); if (fieldxm_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(TQString("fieldx"), TQString::number(fieldx)); msg->addField(TQString("fieldy"), TQString::number(fieldy)); msg->addField(TQString("fieldstate"), TQString::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 TQString &text) { if(m_connection != 0 && m_serverHasClient) { KMessage *msg = new KMessage(KMessage::CHAT); msg->chatMessage(m_ownNickname, text); slotSendMessage(msg); } } void KBattleshipWindow::slotChangedNickCommand(const TQString &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] = TQString::number(m_stat->shot()); info[KScoreDialog::Custom2] = TQString::number(m_stat->hit()); info[KScoreDialog::Custom3] = TQString::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, TQT_SIGNAL(sigConnectServer()), TQT_TQOBJECT(this), TQT_SLOT(slotConnectToBattleshipServer())); connect(m_client, TQT_SIGNAL(sigCancelConnect()), TQT_TQOBJECT(this), TQT_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?"),TQString(),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?"), TQString(), 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?"), TQString(), 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 TDEServerDialog(this); connect(m_server, TQT_SIGNAL(okClicked()), TQT_TQOBJECT(this), TQT_SLOT(slotStartBattleshipServer())); connect(m_server, TQT_SIGNAL(cancelClicked()), TQT_TQOBJECT(this), TQT_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); TQTimer::singleShot(150, TQT_TQOBJECT(this), TQT_SLOT(slotSendGreet())); } void KBattleshipWindow::slotSendGreet() { m_serverHasClient = true; m_chat->slotAcceptMsg(true); KMessage *msg = new KMessage(KMessage::GREET); msg->addField(TQString("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, TQT_SIGNAL(sigStatusBar(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotStatusMsg(const TQString &))); connect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotChangeEnemyPlayer(const TQString &))); connect(m_connection, TQT_SIGNAL(sigSendNickname()), TQT_TQOBJECT(this), TQT_SLOT(slotSendGreet())); connect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetPlaceable(bool))); connect(m_connection, TQT_SIGNAL(sigShootable(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetShootable(bool))); connect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotSendEnemyFieldState(int, int))); connect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool))); connect(m_connection, TQT_SIGNAL(sigClientLost()), TQT_TQOBJECT(this), TQT_SLOT(slotClientLost())); connect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), TQT_TQOBJECT(this), TQT_SLOT(slotAbortNetworkGame())); connect(m_connection, TQT_SIGNAL(sigReplay()), TQT_TQOBJECT(this), TQT_SLOT(slotReplayRequest())); connect(m_connection, TQT_SIGNAL(sigChatMessage(const TQString &, const TQString &, bool)), m_chat, TQT_SLOT(slotReceivedMessage(const TQString &, const TQString &, bool))); connect(m_connection, TQT_SIGNAL(sigClientInformation(const TQString &, const TQString &, const TQString &, const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedClientInformation(const TQString &, const TQString &, const TQString &, const TQString &))); connect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), TQT_TQOBJECT(this), TQT_SLOT(slotLost(KMessage *))); } else { if(m_connection->type() == KonnectionHandling::CLIENT) { disconnect(m_kbclient, TQT_SIGNAL(sigConnected()), TQT_TQOBJECT(this), TQT_SLOT(slotSendVersion())); disconnect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), TQT_TQOBJECT(this), TQT_SLOT(slotAbortNetworkGame())); disconnect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotStatusMsg(const TQString &))); disconnect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotChangeEnemyPlayer(const TQString &))); disconnect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotSendEnemyFieldState(int, int))); disconnect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool))); disconnect(m_connection, TQT_SIGNAL(sigShootable(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetShootable(bool))); disconnect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetPlaceable(bool))); disconnect(m_connection, TQT_SIGNAL(sigServerLost()), TQT_TQOBJECT(this), TQT_SLOT(slotServerLost())); disconnect(m_connection, TQT_SIGNAL(sigReplay()), TQT_TQOBJECT(this), TQT_SLOT(slotReplay())); disconnect(m_connection, TQT_SIGNAL(sigChatMessage(const TQString &, const TQString &, bool)), m_chat, TQT_SLOT(slotReceivedMessage(const TQString &, const TQString &, bool))); disconnect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), TQT_TQOBJECT(this), TQT_SLOT(slotLost(KMessage *))); m_connection->updateInternal(m_kbserver); connect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotStatusMsg(const TQString &))); connect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotChangeEnemyPlayer(const TQString &))); connect(m_connection, TQT_SIGNAL(sigSendNickname()), TQT_TQOBJECT(this), TQT_SLOT(slotSendGreet())); connect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetPlaceable(bool))); connect(m_connection, TQT_SIGNAL(sigShootable(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetShootable(bool))); connect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotSendEnemyFieldState(int, int))); connect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool))); connect(m_connection, TQT_SIGNAL(sigClientLost()), TQT_TQOBJECT(this), TQT_SLOT(slotClientLost())); connect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), TQT_TQOBJECT(this), TQT_SLOT(slotAbortNetworkGame())); connect(m_connection, TQT_SIGNAL(sigReplay()), TQT_TQOBJECT(this), TQT_SLOT(slotReplayRequest())); connect(m_connection, TQT_SIGNAL(sigChatMessage(const TQString &, const TQString &, bool)), m_chat, TQT_SLOT(slotReceivedMessage(const TQString &, const TQString &, bool))); connect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), TQT_TQOBJECT(this), TQT_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 TQValueList 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(TQString("xstart"), TQString::number(fieldx)); msg->addField(TQString("xstop"), TQString::number(fieldx)); msg->addField(TQString("ystart"), TQString::number(fieldy)); msg->addField(TQString("ystop"), TQString::number(fieldy)); msg->addField(TQString("death"), TQString("true")); is_kill = true; } } msg->addField(TQString("fieldx"), TQString::number(fieldx)); msg->addField(TQString("fieldy"), TQString::number(fieldy)); if(xokay) { msg->addField(TQString("xstart"), TQString::number(deathList.first())); msg->addField(TQString("xstop"), TQString::number(deathList.last())); msg->addField(TQString("ystart"), TQString::number(fieldy)); msg->addField(TQString("ystop"), TQString::number(fieldy)); msg->addField(TQString("death"), TQString("true")); is_kill = true; } else if(yokay) { msg->addField(TQString("xstart"), TQString::number(fieldx)); msg->addField(TQString("xstop"), TQString::number(fieldx)); msg->addField(TQString("ystart"), TQString::number(deathList.first())); msg->addField(TQString("ystop"), TQString::number(deathList.last())); msg->addField(TQString("death"), TQString("true")); is_kill = true; } if(is_kill) // If sunk, reveal ship type msg->addField(TQString("fieldstate"), TQString::number(data)); else if(showstate == KBattleField::HIT) // On non-fatal hit, keep ship type secret msg->addField(TQString("fieldstate"), TQString::number(1)); else /* showstate == KBattleField::WATER */ // Miss msg->addField(TQString("fieldstate"), TQString::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() { TDECmdLineArgs *args = TDECmdLineArgs::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 TDE Battleship '%1' is not a valid url") .arg(args->arg(0))); return; } if( u.protocol() != "kbattleship" ) { KMessageBox::sorry(this, i18n("The URL passed to TDE Battleship '%1' is not recognised " "as a Battleship game.") .arg(args->arg(0))); return; } slotConnectToBattleshipServer(u.host(), u.port(), u.user()); } } void KBattleshipWindow::slotConnectToBattleshipServer() { TQString host = m_client->host(); int port = m_client->port().toInt(); TQString nickname = m_client->nickname(); delete m_client; m_client = 0; slotConnectToBattleshipServer(host, port, nickname); } void KBattleshipWindow::slotConnectToBattleshipServer(const TQString &host, int port, const TQString &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, TQT_SIGNAL(sigConnected()), TQT_TQOBJECT(this), TQT_SLOT(slotSendVersion())); connect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), TQT_TQOBJECT(this), TQT_SLOT(slotAbortNetworkGame())); connect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotStatusMsg(const TQString &))); connect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotChangeEnemyPlayer(const TQString &))); connect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotSendEnemyFieldState(int, int))); connect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool))); connect(m_connection, TQT_SIGNAL(sigShootable(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetShootable(bool))); connect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetPlaceable(bool))); connect(m_connection, TQT_SIGNAL(sigServerLost()), TQT_TQOBJECT(this), TQT_SLOT(slotServerLost())); connect(m_connection, TQT_SIGNAL(sigReplay()), TQT_TQOBJECT(this), TQT_SLOT(slotReplay())); connect(m_connection, TQT_SIGNAL(sigChatMessage(const TQString &, const TQString &, bool)), m_chat, TQT_SLOT(slotReceivedMessage(const TQString &, const TQString &, bool))); connect(m_connection, TQT_SIGNAL(sigClientInformation(const TQString &, const TQString &, const TQString &, const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedClientInformation(const TQString &, const TQString &, const TQString &, const TQString &))); connect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), TQT_TQOBJECT(this), TQT_SLOT(slotLost(KMessage *))); } else { if(m_connection->type() == KonnectionHandling::SERVER) { disconnect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotStatusMsg(const TQString &))); disconnect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotChangeEnemyPlayer(const TQString &))); disconnect(m_connection, TQT_SIGNAL(sigSendNickname()), TQT_TQOBJECT(this), TQT_SLOT(slotSendGreet())); disconnect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetPlaceable(bool))); disconnect(m_connection, TQT_SIGNAL(sigShootable(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetShootable(bool))); disconnect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotSendEnemyFieldState(int, int))); disconnect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool))); disconnect(m_connection, TQT_SIGNAL(sigClientLost()), TQT_TQOBJECT(this), TQT_SLOT(slotClientLost())); disconnect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), TQT_TQOBJECT(this), TQT_SLOT(slotAbortNetworkGame())); disconnect(m_connection, TQT_SIGNAL(sigReplay()), TQT_TQOBJECT(this), TQT_SLOT(slotReplayRequest())); disconnect(m_connection, TQT_SIGNAL(sigChatMessage(const TQString &, const TQString &, bool)), m_chat, TQT_SLOT(slotReceivedMessage(const TQString &, const TQString &, bool))); disconnect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), TQT_TQOBJECT(this), TQT_SLOT(slotLost(KMessage *))); m_connection->updateInternal(m_kbclient); connect(m_kbclient, TQT_SIGNAL(sigConnected()), TQT_TQOBJECT(this), TQT_SLOT(slotSendVersion())); connect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), TQT_TQOBJECT(this), TQT_SLOT(slotAbortNetworkGame())); connect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotStatusMsg(const TQString &))); connect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotChangeEnemyPlayer(const TQString &))); connect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), TQT_TQOBJECT(this), TQT_SLOT(slotSendEnemyFieldState(int, int))); connect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool))); connect(m_connection, TQT_SIGNAL(sigShootable(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetShootable(bool))); connect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), TQT_TQOBJECT(this), TQT_SLOT(slotSetPlaceable(bool))); connect(m_connection, TQT_SIGNAL(sigServerLost()), TQT_TQOBJECT(this), TQT_SLOT(slotServerLost())); connect(m_connection, TQT_SIGNAL(sigReplay()), TQT_TQOBJECT(this), TQT_SLOT(slotReplay())); connect(m_connection, TQT_SIGNAL(sigChatMessage(const TQString &, const TQString &, bool)), m_chat, TQT_SLOT(slotReceivedMessage(const TQString &, const TQString &, bool))); m_kbclient->init(); connect(m_connection, TQT_SIGNAL(sigClientInformation(const TQString &, const TQString &, const TQString &, const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotReceivedClientInformation(const TQString &, const TQString &, const TQString &, const TQString &))); connect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), TQT_TQOBJECT(this), TQT_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 TQString &text) { statusBar()->clear(); statusBar()->changeItem(text, ID_STATUS_MSG); } void KBattleshipWindow::slotChangeOwnPlayer(const TQString &text) { statusBar()->clear(); statusBar()->changeItem(i18n(" Player 1: %1 ").arg(text), ID_PLAYER_OWN); } void KBattleshipWindow::slotChangeEnemyPlayer(const TQString &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(); TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_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, TQT_SIGNAL(sigReady()), TQT_TQOBJECT(this), TQT_SLOT(slotAIReady())); connect(m_aiPlayer, TQT_SIGNAL(sigShootAt(const TQPoint)), TQT_TQOBJECT(this), TQT_SLOT(slotAIShootsAt(const TQPoint))); } 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 TQPoint 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?"), TQString(), i18n("Restart"), i18n("Do Not Restart"))) { case KMessageBox::Yes: TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotRestartAI())); break; case KMessageBox::No: TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotDeleteAI())); break; } } else { if(!m_shootable) m_shootable = true; } } void KBattleshipWindow::slotReceivedClientInformation(const TQString &clientName, const TQString &clientVersion, const TQString &clientDescription, const TQString &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); } }