You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1353 lines
44 KiB
C++
1353 lines
44 KiB
C++
/***************************************************************************
|
|
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 <tqlayout.h>
|
|
#include <tqtimer.h>
|
|
|
|
#include <kgamemisc.h>
|
|
#include <kinputdialog.h>
|
|
#include <knotifyclient.h>
|
|
#include <knotifydialog.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kstatusbar.h>
|
|
#include <kstdgameaction.h>
|
|
#include <tdecmdlineargs.h>
|
|
#include <tdemessagebox.h>
|
|
#include <kuser.h>
|
|
|
|
#include <highscore/kscoredialog.h>
|
|
|
|
|
|
#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(this, TQT_SLOT(slotConfigureNotifications()), actionCollection());
|
|
m_gameServerConnect = new TDEAction(i18n("&Connect to Server..."), "connect_no", Key_F2, this, TQT_SLOT(slotServerConnect()), actionCollection(), "game_serverconnect");
|
|
m_gameNewServer = new TDEAction(i18n("&Start Server..."), "network", Key_F3, this, TQT_SLOT(slotNewServer()), actionCollection(), "game_newserver");
|
|
m_gameSingle = new TDEAction(i18n("S&ingle Player..."), "gear", Key_F4, this, TQT_SLOT(slotSinglePlayer()), actionCollection(), "game_singleplayer");
|
|
m_gameQuit = KStdGameAction::quit(this, TQT_SLOT(close()), actionCollection());
|
|
KStdGameAction::highscores(this, TQT_SLOT(slotHighscore()), actionCollection());
|
|
m_gameEnemyInfo = new TDEAction(i18n("&Enemy Info"), "view_text", Key_F11, 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, 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 &)), this, TQT_SLOT(slotSendChatMessage(const TQString &)));
|
|
connect(m_chat, TQT_SIGNAL(sigChangeEnemyNickname(const TQString &)), this, TQT_SLOT(slotChangeEnemyPlayer(const TQString &)));
|
|
connect(m_chat, TQT_SIGNAL(sigChangeOwnNickname(const TQString &)), this, TQT_SLOT(slotChangedNickCommand(const TQString &)));
|
|
}
|
|
|
|
void KBattleshipWindow::changeShipPlacementDirection(){
|
|
shift = !shift;
|
|
}
|
|
|
|
void KBattleshipWindow::initShipPlacing()
|
|
{
|
|
connect(m_ownshiplist, TQT_SIGNAL(sigOwnFieldDataChanged(int, int, int)), this, TQT_SLOT(slotChangeOwnFieldData(int, int, int)));
|
|
connect(m_ownshiplist, TQT_SIGNAL(sigLastShipAdded()), 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)), this, TQT_SLOT(slotEnemyFieldClick(int, int)));
|
|
connect(m_view, TQT_SIGNAL(sigOwnFieldClicked(int, int)), this, TQT_SLOT(slotPlaceShip(int, int)));
|
|
connect(m_view, TQT_SIGNAL(sigMouseOverField(int, int)), this, TQT_SLOT(slotPlaceShipPreview(int, int)));
|
|
connect(m_view, TQT_SIGNAL(changeShipPlacementDirection()), 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<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?"),TQString(),i18n("Restart"),i18n("Do Not Restart")))
|
|
{
|
|
case KMessageBox::Yes:
|
|
TQTimer::singleShot(0, this, TQT_SLOT(slotRestartAI()));
|
|
break;
|
|
|
|
case KMessageBox::No:
|
|
TQTimer::singleShot(0, 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(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(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()), this, TQT_SLOT(slotConnectToBattleshipServer()));
|
|
connect(m_client, TQT_SIGNAL(sigCancelConnect()), 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()), this, TQT_SLOT(slotStartBattleshipServer()));
|
|
connect(m_server, TQT_SIGNAL(cancelClicked()), 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, 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 &)), this, TQT_SLOT(slotStatusMsg(const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), this, TQT_SLOT(slotChangeEnemyPlayer(const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigSendNickname()), this, TQT_SLOT(slotSendGreet()));
|
|
connect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), this, TQT_SLOT(slotSetPlaceable(bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigShootable(bool)), this, TQT_SLOT(slotSetShootable(bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), this, TQT_SLOT(slotSendEnemyFieldState(int, int)));
|
|
connect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigClientLost()), this, TQT_SLOT(slotClientLost()));
|
|
connect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), this, TQT_SLOT(slotAbortNetworkGame()));
|
|
connect(m_connection, TQT_SIGNAL(sigReplay()), 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 &)), this, TQT_SLOT(slotReceivedClientInformation(const TQString &, const TQString &, const TQString &, const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), this, TQT_SLOT(slotLost(KMessage *)));
|
|
}
|
|
else
|
|
{
|
|
if(m_connection->type() == KonnectionHandling::CLIENT)
|
|
{
|
|
disconnect(m_kbclient, TQT_SIGNAL(sigConnected()), this, TQT_SLOT(slotSendVersion()));
|
|
disconnect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), this, TQT_SLOT(slotAbortNetworkGame()));
|
|
disconnect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), this, TQT_SLOT(slotStatusMsg(const TQString &)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), this, TQT_SLOT(slotChangeEnemyPlayer(const TQString &)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), this, TQT_SLOT(slotSendEnemyFieldState(int, int)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigShootable(bool)), this, TQT_SLOT(slotSetShootable(bool)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), this, TQT_SLOT(slotSetPlaceable(bool)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigServerLost()), this, TQT_SLOT(slotServerLost()));
|
|
disconnect(m_connection, TQT_SIGNAL(sigReplay()), 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 *)), this, TQT_SLOT(slotLost(KMessage *)));
|
|
m_connection->updateInternal(m_kbserver);
|
|
connect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), this, TQT_SLOT(slotStatusMsg(const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), this, TQT_SLOT(slotChangeEnemyPlayer(const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigSendNickname()), this, TQT_SLOT(slotSendGreet()));
|
|
connect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), this, TQT_SLOT(slotSetPlaceable(bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigShootable(bool)), this, TQT_SLOT(slotSetShootable(bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), this, TQT_SLOT(slotSendEnemyFieldState(int, int)));
|
|
connect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigClientLost()), this, TQT_SLOT(slotClientLost()));
|
|
connect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), this, TQT_SLOT(slotAbortNetworkGame()));
|
|
connect(m_connection, TQT_SIGNAL(sigReplay()), 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 *)), 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<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(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()), this, TQT_SLOT(slotSendVersion()));
|
|
connect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), this, TQT_SLOT(slotAbortNetworkGame()));
|
|
connect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), this, TQT_SLOT(slotStatusMsg(const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), this, TQT_SLOT(slotChangeEnemyPlayer(const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), this, TQT_SLOT(slotSendEnemyFieldState(int, int)));
|
|
connect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigShootable(bool)), this, TQT_SLOT(slotSetShootable(bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), this, TQT_SLOT(slotSetPlaceable(bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigServerLost()), this, TQT_SLOT(slotServerLost()));
|
|
connect(m_connection, TQT_SIGNAL(sigReplay()), 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 &)), this, TQT_SLOT(slotReceivedClientInformation(const TQString &, const TQString &, const TQString &, const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), this, TQT_SLOT(slotLost(KMessage *)));
|
|
}
|
|
else
|
|
{
|
|
if(m_connection->type() == KonnectionHandling::SERVER)
|
|
{
|
|
disconnect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), this, TQT_SLOT(slotStatusMsg(const TQString &)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), this, TQT_SLOT(slotChangeEnemyPlayer(const TQString &)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigSendNickname()), this, TQT_SLOT(slotSendGreet()));
|
|
disconnect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), this, TQT_SLOT(slotSetPlaceable(bool)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigShootable(bool)), this, TQT_SLOT(slotSetShootable(bool)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), this, TQT_SLOT(slotSendEnemyFieldState(int, int)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
|
|
disconnect(m_connection, TQT_SIGNAL(sigClientLost()), this, TQT_SLOT(slotClientLost()));
|
|
disconnect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), this, TQT_SLOT(slotAbortNetworkGame()));
|
|
disconnect(m_connection, TQT_SIGNAL(sigReplay()), 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 *)), this, TQT_SLOT(slotLost(KMessage *)));
|
|
m_connection->updateInternal(m_kbclient);
|
|
connect(m_kbclient, TQT_SIGNAL(sigConnected()), this, TQT_SLOT(slotSendVersion()));
|
|
connect(m_connection, TQT_SIGNAL(sigAbortNetworkGame()), this, TQT_SLOT(slotAbortNetworkGame()));
|
|
connect(m_connection, TQT_SIGNAL(sigStatusBar(const TQString &)), this, TQT_SLOT(slotStatusMsg(const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigEnemyNickname(const TQString &)), this, TQT_SLOT(slotChangeEnemyPlayer(const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigSendFieldState(int, int)), this, TQT_SLOT(slotSendEnemyFieldState(int, int)));
|
|
connect(m_connection, TQT_SIGNAL(sigEnemyFieldData(int, int, int, int, int, int, int, bool)), this, TQT_SLOT(slotReceivedEnemyFieldData(int, int, int, int, int, int, int, bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigShootable(bool)), this, TQT_SLOT(slotSetShootable(bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigPlaceShips(bool)), this, TQT_SLOT(slotSetPlaceable(bool)));
|
|
connect(m_connection, TQT_SIGNAL(sigServerLost()), this, TQT_SLOT(slotServerLost()));
|
|
connect(m_connection, TQT_SIGNAL(sigReplay()), 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 &)), this, TQT_SLOT(slotReceivedClientInformation(const TQString &, const TQString &, const TQString &, const TQString &)));
|
|
connect(m_connection, TQT_SIGNAL(sigLost(KMessage *)), 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, 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()), this, TQT_SLOT(slotAIReady()));
|
|
connect(m_aiPlayer, TQT_SIGNAL(sigShootAt(const TQPoint)), 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, this, TQT_SLOT(slotRestartAI()));
|
|
break;
|
|
|
|
case KMessageBox::No:
|
|
TQTimer::singleShot(0, 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);
|
|
}
|
|
}
|