1 /*
2  *      boatstabitem.cpp
3  *
4  *      Copyright 2014 David Vachulka <arch_dvx@users.sourceforge.net>
5  *
6  *      This program is free software; you can redistribute it and/or modify
7  *      it under the terms of the GNU General Public License as published by
8  *      the Free Software Foundation; either version 3 of the License, or
9  *      (at your option) any later version.
10  *
11  *      This program is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *      GNU General Public License for more details.
15  *
16  *      You should have received a copy of the GNU General Public License
17  *      along with this program; if not, write to the Free Software
18  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *      MA 02110-1301, USA.
20  */
21 
22 #include "boatstabitem.h"
23 #include "config.h"
24 #include "i18n.h"
25 
26 #define SPACE 5
27 #define LINEWIDTH 1
28 
Boats(bool first,QWidget * parent)29 Boats::Boats(bool first, QWidget *parent)
30     : QWidget(parent), m_first(first), m_placeBoats(true), m_rotated(false), m_previousX(-1), m_previousY(-1),
31       m_cells(1), m_onFire(false), m_readyToPlay(false)
32 {
33     setFocusPolicy(Qt::StrongFocus);
34     setFocus();
35     setMouseTracking(true);
36     m_cell = qMin((width()-9*SPACE)/(2*bcolumns), (height()-2*SPACE)/brows);
37     clearCellsAndBoats();
38     placeMyBoats();
39 }
40 
setCellType(int x,int y,bool my,CELLTYPE type)41 void Boats::setCellType(int x, int y, bool my, CELLTYPE type)
42 {
43     if(x>-1 && x<bcolumns && y>-1 && y<brows)
44     {
45         if(my) m_mycells[x][y].type = type;
46         else m_hiscells[x][y].type = type;
47     }
48 }
49 
getCellType(int x,int y,bool my)50 CELLTYPE Boats::getCellType(int x, int y, bool my)
51 {
52     if(x>-1 && x<bcolumns && y>-1 && y<brows)
53     {
54         if(my) return m_mycells[x][y].type;
55         else return m_hiscells[x][y].type;
56     }
57     return CLEAR;
58 }
59 
mousePressEvent(QMouseEvent * ev)60 void Boats::mousePressEvent(QMouseEvent *ev)
61 {
62     if(ev->button() == Qt::LeftButton)
63     {
64         if(m_placeBoats)
65         {
66 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
67             if(qRound(ev->position().x()) < SPACE || qRound(ev->position().x()) > SPACE+bcolumns*m_cell)
68                 return;
69             if(qRound(ev->position().y()) < SPACE || qRound(ev->position().y()) > SPACE+brows*m_cell)
70                 return;
71             int x = (qRound(ev->position().x())-SPACE)/m_cell;
72             int y = (qRound(ev->position().y())-SPACE)/m_cell;
73 #else
74             if(ev->x() < SPACE || ev->x() > SPACE+bcolumns*m_cell)
75                 return;
76             if(ev->y() < SPACE || ev->y() > SPACE+brows*m_cell)
77                 return;
78             int x = (ev->x()-SPACE)/m_cell;
79             int y = (ev->y()-SPACE)/m_cell;
80 #endif
81             if(x>-1 && x<bcolumns && y>-1 && y<brows
82                     && m_mycells[x][y].type == PLACED)
83             {
84                 m_previousX = -1;
85                 m_previousY = -1;
86                 for(int i=0; i<m_cells; i++)
87                 {
88                     if(m_rotated) m_mycells[x][y+i].type = BOAT;
89                     else m_mycells[x+i][y].type = BOAT;
90                 }
91                 for(int i=0; i<boats; i++)
92                 {
93                     if(!m_boats[i].isValid())
94                     {
95                         m_boats[i].x = x;
96                         m_boats[i].y = y;
97                         m_boats[i].cells = m_cells;
98                         m_boats[i].rotated = m_rotated;
99                         break;
100                     }
101                 }
102             }
103             update();
104             placeMyBoats();
105         }
106         else
107         {
108             if(m_onFire)
109             {
110 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
111                 if(qRound(ev->position().x()) < 6*SPACE+bcolumns*m_cell || qRound(ev->position().x()) > 6*SPACE+2*bcolumns*m_cell)
112                     return;
113                 if(qRound(ev->position().y()) < SPACE || qRound(ev->position().y()) > SPACE+brows*m_cell)
114                     return;
115                 int x = (qRound(ev->position().x())-6*SPACE-bcolumns*m_cell)/m_cell;
116                 int y = (qRound(ev->position().y())-SPACE)/m_cell;
117 #else
118                 if(ev->x() < 6*SPACE+bcolumns*m_cell || ev->x() > 6*SPACE+2*bcolumns*m_cell)
119                     return;
120                 if(ev->y() < SPACE || ev->y() > SPACE+brows*m_cell)
121                     return;
122                 int x = (ev->x()-6*SPACE-bcolumns*m_cell)/m_cell;
123                 int y = (ev->y()-SPACE)/m_cell;
124 #endif
125                 if(x>-1 && x<bcolumns && y>-1 && y<brows
126                         && m_hiscells[x][y].type == CLEAR)
127                 {
128                     m_hiscells[x][y].type = FIRE;
129                     emit fire(x, y);
130                     m_onFire = false;
131                 }
132                 update();
133             }
134         }
135     }
136     if(ev->button() == Qt::RightButton)
137     {
138         if(m_placeBoats)
139         {
140 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
141             if(qRound(ev->position().x()) < SPACE || qRound(ev->position().x()) > SPACE+bcolumns*m_cell)
142                 return;
143             if(qRound(ev->position().y()) < SPACE || qRound(ev->position().y()) > SPACE+brows*m_cell)
144                 return;
145             int x = (qRound(ev->position().x())-SPACE)/m_cell;
146             int y = (qRound(ev->position().y())-SPACE)/m_cell;
147 #else
148             if(ev->x() < SPACE || ev->x() > SPACE+bcolumns*m_cell)
149                 return;
150             if(ev->y() < SPACE || ev->y() > SPACE+brows*m_cell)
151                 return;
152             int x = (ev->x()-SPACE)/m_cell;
153             int y = (ev->y()-SPACE)/m_cell;
154 #endif
155             if(x>-1 && x<bcolumns && y>-1 && y<brows && isRightForPlaceBoat(x, y))
156             {
157                 for(int i=0; i<m_cells; i++)
158                 {
159                     if(m_rotated) m_mycells[x][y+i].type = CLEAR;
160                     else m_mycells[x+i][y].type = CLEAR;
161                 }
162             }
163             m_rotated = !m_rotated;
164             if(x>-1 && x<bcolumns && y>-1 && y<brows && isRightForPlaceBoat(x, y))
165             {
166                 for(int i=0; i<m_cells; i++)
167                 {
168                     if(m_rotated) m_mycells[x][y+i].type = PLACED;
169                     else m_mycells[x+i][y].type = PLACED;
170                 }
171             }
172             update();
173         }
174     }
175 }
176 
mouseMoveEvent(QMouseEvent * ev)177 void Boats::mouseMoveEvent(QMouseEvent *ev)
178 {
179     if(m_placeBoats)
180     {
181 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
182         if(qRound(ev->position().x()) < SPACE || qRound(ev->position().x()) > SPACE+bcolumns*m_cell)
183             return;
184         if(qRound(ev->position().y()) < SPACE || qRound(ev->position().y()) > SPACE+brows*m_cell)
185             return;
186         int x = (qRound(ev->position().x())-SPACE)/m_cell;
187         int y = (qRound(ev->position().y())-SPACE)/m_cell;
188 #else
189         if(ev->x() < SPACE || ev->x() > SPACE+bcolumns*m_cell)
190             return;
191         if(ev->y() < SPACE || ev->y() > SPACE+brows*m_cell)
192             return;
193         int x = (ev->x()-SPACE)/m_cell;
194         int y = (ev->y()-SPACE)/m_cell;
195 #endif
196         if((m_previousX!=x || m_previousY!=y)
197                 && m_previousX>-1 && m_previousX<bcolumns
198                 && m_previousY>-1 && m_previousY<brows)
199         {
200             for(int i=0; i<m_cells; i++)
201             {
202                 if(m_rotated)
203                 {
204                     if(m_mycells[m_previousX][m_previousY+i].type == PLACED) m_mycells[m_previousX][m_previousY+i].type = CLEAR;
205                 }
206                 else
207                 {
208                     if(m_mycells[m_previousX+i][m_previousY].type == PLACED) m_mycells[m_previousX+i][m_previousY].type = CLEAR;
209                 }
210             }
211         }
212         if(x>-1 && x<bcolumns && y>-1 && y<brows && isRightForPlaceBoat(x, y))
213         {
214             m_previousX = x;
215             m_previousY = y;
216             for(int i=0; i<m_cells; i++)
217             {
218                 if(m_rotated) m_mycells[x][y+i].type = PLACED;
219                 else m_mycells[x+i][y].type = PLACED;
220             }
221         }
222         update();
223     }
224 }
225 
paintEvent(QPaintEvent *)226 void Boats::paintEvent(QPaintEvent *)
227 {
228     QPainter painter(this);
229     painter.setRenderHint(QPainter::Antialiasing, true);
230     painter.fillRect(QRect(0, 0, width(), height()), QColor("black"));
231     painter.setPen(QPen(QColor(168,168,168),LINEWIDTH));
232     int x1 = 0;
233     int y1 = 0;
234     for(int x=0; x<bcolumns; ++x)
235     {
236         for(int y=0; y<brows; ++y)
237         {
238             painter.drawRect(SPACE+x1,SPACE+y1, m_cell, m_cell);
239             painter.drawRect(6*SPACE+bcolumns*m_cell+x1,SPACE+y1, m_cell, m_cell);
240             y1 += m_cell;
241         }
242         y1 = 0;
243         x1 += m_cell;
244     }
245     for(int x=0; x<bcolumns; ++x)
246     {
247         for(int y=0; y<brows; ++y)
248         {
249             painter.setBrush(getCellColor(m_mycells[x][y].type));
250             painter.drawRect(SPACE+x*m_cell+1, SPACE+y*m_cell+1, m_cell-LINEWIDTH, m_cell-LINEWIDTH);
251             painter.setBrush(getCellColor(m_hiscells[x][y].type));
252             painter.drawRect(6*SPACE+bcolumns*m_cell+x*m_cell+1, SPACE+y*m_cell+1, m_cell-LINEWIDTH, m_cell-LINEWIDTH);
253         }
254     }
255 }
256 
resizeEvent(QResizeEvent * event)257 void Boats::resizeEvent(QResizeEvent *event)
258 {
259     m_cell = qMin((event->size().width()-9*SPACE)/(2*bcolumns), (event->size().height()-2*SPACE)/brows);
260 }
261 
placeBoats() const262 bool Boats::placeBoats() const
263 {
264     return m_placeBoats;
265 }
266 
setPlaceBoats(bool placeBoats)267 void Boats::setPlaceBoats(bool placeBoats)
268 {
269     m_placeBoats = placeBoats;
270 }
271 
readyToPlay() const272 bool Boats::readyToPlay() const
273 {
274     return m_readyToPlay;
275 }
276 
setReadyToPlay(bool readyToPlay)277 void Boats::setReadyToPlay(bool readyToPlay)
278 {
279     m_readyToPlay = readyToPlay;
280 }
281 
onFire() const282 bool Boats::onFire() const
283 {
284     return m_onFire;
285 }
286 
setOnFire(bool onFire)287 void Boats::setOnFire(bool onFire)
288 {
289     m_onFire = onFire;
290 }
291 
first() const292 bool Boats::first() const
293 {
294     return m_first;
295 }
296 
setFirst(bool first)297 void Boats::setFirst(bool first)
298 {
299     m_first = first;
300 }
301 
placeMyBoats()302 void Boats::placeMyBoats()
303 {
304     int cells = 0;
305     for(int x=0; x<bcolumns; ++x)
306     {
307         for(int y=0; y<brows; ++y)
308         {
309             if(m_mycells[x][y].type == BOAT)
310                 cells++;
311         }
312     }
313     if(cells < 4)
314     {
315         m_cells = 1;
316         return;
317     }
318     if(cells < 10)
319     {
320         m_cells = 2;
321         return;
322     }
323     if(cells < 16)
324     {
325         m_cells = 3;
326         return;
327     }
328     if(cells == 16)
329     {
330         m_cells = 4;
331         return;
332     }
333     if(cells == 20)
334     {
335         m_placeBoats = false;
336         emit statusText(_("Placing of boats finished"));
337         emit ready();
338         return;
339     }
340 }
341 
getCellColor(CELLTYPE type)342 QColor Boats::getCellColor(CELLTYPE type)
343 {
344     switch (type) {
345     case CLEAR: return QColor(0,0,0);
346     case BOAT: return QColor(78,154,6);
347     case WATER: return QColor(32,74,135);
348     case HIT: return QColor(164,0,0);
349     case PLACED: return QColor(78,154,6);
350     case FIRE: return QColor(196,160,0);
351     default: return QColor(0,0,0);
352     }
353 }
354 
isRightForPlaceBoat(int x,int y)355 bool Boats::isRightForPlaceBoat(int x, int y)
356 {
357     if(m_rotated)
358     {
359         if(y+m_cells-1 < brows-1 && m_mycells[x][y+m_cells].type == BOAT)
360         {
361             return false;
362         }
363         for(int i=0; i<m_cells; i++)
364         {
365             if(y+i > brows-1)
366             {
367                 return false;
368             }
369             if(m_mycells[x][y+i].type == BOAT)
370             {
371                 return false;
372             }
373             if(x > 0 && m_mycells[x-1][y+i].type == BOAT)
374             {
375                 return false;
376             }
377             if(x < bcolumns-1 && m_mycells[x+1][y+i].type == BOAT)
378             {
379                 return false;
380             }
381             if(y > 0 && m_mycells[x][y-1].type == BOAT)
382             {
383                 return false;
384             }
385             if(y < brows-1 && m_mycells[x][y+1].type == BOAT)
386             {
387                 return false;
388             }
389         }
390     }
391     else
392     {
393         if(x+m_cells-1 < bcolumns-1 && m_mycells[x+m_cells][y].type == BOAT)
394         {
395             return false;
396         }
397         for(int i=0; i<m_cells; i++)
398         {
399             if(x+i > bcolumns-1)
400             {
401                 return false;
402             }
403             if(m_mycells[x+i][y].type == BOAT)
404             {
405                 return false;
406             }
407             if(x > 0 && m_mycells[x-1][y].type == BOAT)
408             {
409                 return false;
410             }
411             if(x < bcolumns-1 && m_mycells[x+1][y].type == BOAT)
412             {
413                 return false;
414             }
415             if(y > 0 && m_mycells[x+i][y-1].type == BOAT)
416             {
417                 return false;
418             }
419             if(y < brows-1 && m_mycells[x+i][y+1].type == BOAT)
420             {
421                 return false;
422             }
423         }
424     }
425     return true;
426 }
427 
clearCellsAndBoats()428 void Boats::clearCellsAndBoats()
429 {
430     for(int x=0; x<bcolumns; ++x)
431     {
432         for(int y=0; y<brows; ++y)
433         {
434             m_mycells[x][y].type = CLEAR;
435             m_hiscells[x][y].type = CLEAR;
436         }
437     }
438     for(int i=0; i<boats; ++i)
439     {
440         m_boats[i].x = -1;
441         m_boats[i].y = -1;
442     }
443     m_cells = 1;
444 }
445 
gameOver()446 bool Boats::gameOver()
447 {
448     for(int i=0; i<boats; ++i)
449     {
450         if(m_boats[i].rotated)
451         {
452             for(int y1=m_boats[i].y; y1<brows && y1<m_boats[i].y+m_boats[i].cells; ++y1)
453             {
454                 if(m_mycells[m_boats[i].x][y1].type != HIT)
455                     return false;
456             }
457         }
458         else
459         {
460             for(int x1=m_boats[i].x; x1<bcolumns && x1<m_boats[i].x+m_boats[i].cells; ++x1)
461             {
462                 if(m_mycells[x1][m_boats[i].y].type != HIT)
463                     return false;
464             }
465         }
466     }
467     return true;
468 }
469 
boatDestroyed(int x,int y)470 bool Boats::boatDestroyed(int x, int y)
471 {
472     for(int i=0; i<boats; ++i)
473     {
474         if(m_boats[i].constainsCell(x, y))
475         {
476             if(m_boats[i].rotated)
477             {
478                 for(int y1=m_boats[i].y; y1<brows && y1<m_boats[i].y+m_boats[i].cells; ++y1)
479                 {
480                     if(m_mycells[x][y1].type != HIT)
481                         return false;
482                 }
483             }
484             else
485             {
486                 for(int x1=m_boats[i].x; x1<bcolumns && x1<m_boats[i].x+m_boats[i].cells; ++x1)
487                 {
488                     if(m_mycells[x1][y].type != HIT)
489                         return false;
490                 }
491             }
492             return true;
493         }
494     }
495     return false;
496 }
497 
BoatsTabItem(const QString & name,bool first,TabWidget * tabbook,int id,IrcEngine * engine,QWidget * parent)498 BoatsTabItem::BoatsTabItem(const QString &name, bool first, TabWidget *tabbook, int id, IrcEngine *engine, QWidget *parent)
499     : dxTabItem(tabbook, id, parent), m_engine(engine), m_type(BOATS), m_name(name)
500 {
501     m_gamecanvas = new Boats(first, this);
502     m_gamecanvas->setFocus();
503 
504     m_newGame = new QPushButton(_("&New game"));
505     m_newGame->setDisabled(true);
506     QHBoxLayout *game = new QHBoxLayout;
507     game->addWidget(m_newGame);
508     game->addStretch(1);
509 
510     m_status = new QLabel(_("Place boats"));
511 
512     QVBoxLayout *mainLayout = new QVBoxLayout(this);
513     mainLayout->addWidget(m_gamecanvas, 1);
514     mainLayout->addLayout(game);
515     mainLayout->addWidget(m_status);
516     setLayout(mainLayout);
517 
518     connect(m_gamecanvas, SIGNAL(fire(int,int)), this, SLOT(slotFire(int,int)));
519     connect(m_gamecanvas, SIGNAL(statusText(QString)), this, SLOT(slotStatusText(QString)));
520     connect(m_gamecanvas, SIGNAL(ready()), this, SLOT(slotReady()));
521     connect(m_newGame, SIGNAL(clicked()), this, SLOT(slotNewGame()));
522     if(m_engine)
523     {
524         connect(m_engine, SIGNAL(ircNick(QString,QString)), this, SLOT(slotIrcNick(QString,QString)));
525         connect(m_engine, SIGNAL(ircQuit(QString,QString)), this, SLOT(slotIrcQuit(QString)));
526         connect(m_engine, SIGNAL(irc401(QString)), this, SLOT(slotIrc401(QString)));
527         connect(m_engine, SIGNAL(ircBoats(QString,QString,QString)), this, SLOT(slotIrcBoats(QString,QString,QString)));
528         connect(m_engine, SIGNAL(ircBoatsReady(QString)), this, SLOT(slotIrcBoatsReady(QString)));
529         connect(m_engine, SIGNAL(ircBoatsLeft(QString)), this, SLOT(slotIrcBoatsLeft(QString)));
530         connect(m_engine, SIGNAL(ircBoatsDestroyed(QString)), this, SLOT(slotIrcBoatsDestoyed(QString)));
531         connect(m_engine, SIGNAL(ircBoatsNewGame(QString)), this, SLOT(slotIrcBoatsNewGame(QString)));
532         connect(m_engine, SIGNAL(ircBoatsWin(QString)), this, SLOT(slotIrcBoatsWin(QString)));
533     }
534 }
535 
~BoatsTabItem()536 BoatsTabItem::~BoatsTabItem()
537 {
538 }
539 
leftGame()540 void BoatsTabItem::leftGame()
541 {
542     sendCtcp("BOATS LEFT");
543 }
544 
isSameServer(IrcEngine * engine)545 bool BoatsTabItem::isSameServer(IrcEngine* engine)
546 {
547     return engine == m_engine;
548 }
549 
sendCtcp(const QString & msg)550 void BoatsTabItem::sendCtcp(const QString &msg)
551 {
552     if(m_engine && m_engine->getConnected())
553         m_engine->sendCtcp(m_name, msg);
554 }
555 
slotIrcNick(QString nick,QString newnick)556 void BoatsTabItem::slotIrcNick(QString nick, QString newnick)
557 {
558     if(nick == m_name)
559     {
560         m_name = newnick;
561         emit newname(m_name);
562     }
563 }
564 
slotIrcQuit(QString nick)565 void BoatsTabItem::slotIrcQuit(QString nick)
566 {
567     if(nick == m_name)
568     {
569         m_gamecanvas->setPlaceBoats(false);
570         m_gamecanvas->setReadyToPlay(false);
571         m_gamecanvas->setOnFire(false);
572         m_status->setText(_("%1 has quit").arg(nick));
573     }
574 }
575 
slotIrc401(QString nick)576 void BoatsTabItem::slotIrc401(QString nick)
577 {
578     if(nick == m_name)
579     {
580         m_gamecanvas->setPlaceBoats(false);
581         m_gamecanvas->setReadyToPlay(false);
582         m_gamecanvas->setOnFire(false);
583         m_status->setText(_("%1 isn't online").arg(nick));
584     }
585 }
586 
slotIrcBoats(QString nick,QString position,QString status)587 void BoatsTabItem::slotIrcBoats(QString nick, QString position, QString status)
588 {
589     if(nick == m_name)
590     {
591         //position
592         if(position.length()!=2)
593             return;
594         if(position[0].toLatin1()<65 || position[0].toLatin1()>74)
595             return;
596         if(position[1].toLatin1()<48 || position[1].toLatin1()>57)
597             return;
598         int x = position[0].toLatin1()-65;
599         int y = position[1].toLatin1()-48;
600         //redraw cell
601         if(status == "FIRE")
602         {
603             if(m_gamecanvas->getCellType(x, y, true) == BOAT)
604             {
605                 m_gamecanvas->setCellType(x, y, true, HIT);
606                 sendCtcp(QString("BOATS %1 HIT").arg(position));
607                 if(m_gamecanvas->boatDestroyed(x, y))
608                     sendCtcp("BOATS DESTROYED");
609                 if(m_gamecanvas->gameOver())
610                 {
611                     m_gamecanvas->setReadyToPlay(false);
612                     m_gamecanvas->setOnFire(false);
613                     m_status->setText(_("You LOST."));
614                     m_newGame->setEnabled(true);
615                     sendCtcp("BOATS WIN");
616                     m_gamecanvas->update();
617                     return;
618                 }
619             }
620             else
621             {
622                 m_gamecanvas->setCellType(x, y, true, WATER);
623                 sendCtcp(QString("BOATS %1 FAIL").arg(position));
624             }
625             m_gamecanvas->update();
626             m_status->setText(_("Adversary fired. You fire NOW!"));
627             m_gamecanvas->setOnFire(true);
628             return;
629         }
630         if(status == "HIT")
631         {
632             m_gamecanvas->setCellType(x, y, false, HIT);
633             m_gamecanvas->update();
634             m_status->setText(_("Waiting for adversary fire."));
635             return;
636         }
637         if(status == "FAIL")
638         {
639             m_gamecanvas->setCellType(x, y, false, WATER);
640             m_gamecanvas->update();
641             m_status->setText(_("Waiting for adversary fire."));
642             return;
643         }
644     }
645 }
646 
slotIrcBoatsReady(QString nick)647 void BoatsTabItem::slotIrcBoatsReady(QString nick)
648 {
649     if(nick == m_name)
650     {
651         m_gamecanvas->setReadyToPlay(true);
652         if(m_gamecanvas->first())
653         {
654             m_gamecanvas->setOnFire(true);
655             if(!m_gamecanvas->placeBoats()) m_status->setText(_("Fire NOW!"));
656         }
657         else
658         {
659             m_gamecanvas->setOnFire(false);
660             if(!m_gamecanvas->placeBoats()) m_status->setText(_("Waiting for adversary fire."));
661         }
662     }
663 }
664 
slotIrcBoatsLeft(QString nick)665 void BoatsTabItem::slotIrcBoatsLeft(QString nick)
666 {
667     if(nick == m_name)
668     {
669         m_gamecanvas->setPlaceBoats(false);
670         m_gamecanvas->setReadyToPlay(false);
671         m_gamecanvas->setOnFire(false);
672         m_status->setText(_("Adversary left game."));
673     }
674 }
675 
slotIrcBoatsDestoyed(QString nick)676 void BoatsTabItem::slotIrcBoatsDestoyed(QString nick)
677 {
678     if(nick == m_name)
679     {
680         m_status->setText(_("Boat was destroyed. Waiting for adversary fire."));
681     }
682 }
683 
slotIrcBoatsNewGame(QString nick)684 void BoatsTabItem::slotIrcBoatsNewGame(QString nick)
685 {
686     if(nick == m_name)
687     {
688         m_gamecanvas->clearCellsAndBoats();
689         m_gamecanvas->setPlaceBoats(true);
690         m_gamecanvas->setReadyToPlay(false);
691         m_gamecanvas->setOnFire(false);
692         m_status->setText(_("Place boats"));
693         m_newGame->setDisabled(true);
694     }
695 }
696 
slotIrcBoatsWin(QString nick)697 void BoatsTabItem::slotIrcBoatsWin(QString nick)
698 {
699     if(nick == m_name)
700     {
701         m_gamecanvas->setReadyToPlay(false);
702         m_gamecanvas->setOnFire(false);
703         m_status->setText(_("You WIN."));
704         m_newGame->setEnabled(true);
705     }
706 }
707 
slotFire(int x,int y)708 void BoatsTabItem::slotFire(int x, int y)
709 {
710     if(m_engine->getConnected())
711     {
712         sendCtcp(QString("BOATS %1%2 FIRE").arg(static_cast<char>(x+65)).arg(static_cast<char>(y+48)));
713         m_status->setText(_("Waiting for response of fire"));
714     }
715 }
716 
slotStatusText(QString text)717 void BoatsTabItem::slotStatusText(QString text)
718 {
719     m_status->setText(text);
720 }
721 
slotReady()722 void BoatsTabItem::slotReady()
723 {
724     if(m_engine->getConnected())
725     {
726         sendCtcp("BOATS READY");
727         if(m_gamecanvas->readyToPlay())
728         {
729             if(m_gamecanvas->first())
730             {
731                 m_status->setText(_("Fire NOW!"));
732             }
733             else
734             {
735                 m_status->setText(_("Waiting for adversary fire."));
736             }
737         }
738     }
739 }
740 
slotNewGame()741 void BoatsTabItem::slotNewGame()
742 {
743     if(m_engine->getConnected())
744     {
745         sendCtcp("BOATS NEWGAME");
746         m_gamecanvas->clearCellsAndBoats();
747         m_gamecanvas->setPlaceBoats(true);
748         m_gamecanvas->setReadyToPlay(false);
749         m_gamecanvas->setOnFire(false);
750         m_status->setText(_("Place boats"));
751         m_newGame->setDisabled(true);
752     }
753 }
754