2 Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
10 #include "networkentity.h"
12 #include "battlefield.h"
18 NetworkEntity::NetworkEntity(Sea::Player player
, Sea
* sea
, Protocol
* protocol
, bool client
)
23 m_protocol
= protocol
;
26 NetworkEntity::~NetworkEntity()
30 void NetworkEntity::start(bool ask
)
32 connect(m_protocol
, SIGNAL(received(MessagePtr
)), this, SLOT(received(MessagePtr
)));
33 connect(m_protocol
, SIGNAL(disconnected()), this, SIGNAL(abortGame()));
35 m_protocol
->send(MessagePtr(new RestartMessage()));
38 m_protocol
->send(MessagePtr(new HeaderMessage()));
42 void NetworkEntity::notifyReady(Sea::Player player
)
44 if (player
!= m_player
) {
45 m_protocol
->send(MessagePtr(new BeginMessage()));
49 void NetworkEntity::notifyGameOver(Sea::Player
)
51 m_protocol
->send(MessagePtr(new GameOverMessage
));
54 void NetworkEntity::startPlaying()
59 void NetworkEntity::notify(Sea::Player player
, const Coord
& c
, const HitInfo
& info
)
61 if (info
.type
== HitInfo::INVALID
) {
65 if (player
== m_player
) {
66 bool hit
= info
.type
== HitInfo::HIT
;
67 bool death
= info
.shipDestroyed
!= 0;
68 Coord begin
= Coord::invalid();
69 Coord end
= Coord::invalid();
72 end
= begin
+ info
.shipDestroyed
->increment() * (info
.shipDestroyed
->size() - 1);
74 m_protocol
->send(MessagePtr(new NotificationMessage(c
, hit
, death
, begin
, end
)));
77 // the remote player already knows about the hit
78 // no need to notify it
82 void NetworkEntity::notifyNick(Sea::Player player
, const QString
& nick
)
84 if (player
!= m_player
) {
85 m_protocol
->send(MessagePtr(new NickMessage(nick
)));
89 void NetworkEntity::notifyChat(const Entity
* entity
, const QString
& text
)
92 m_protocol
->send(MessagePtr(new ChatMessage(entity
->nick(), text
)));
96 void NetworkEntity::notifyAbort()
98 // TODO: close connection
101 void NetworkEntity::hit(Shot
* shot
)
103 if (shot
->player() != m_player
104 && m_sea
->turn() == shot
->player()
105 && m_sea
->valid(m_player
, shot
->pos())) {
106 m_pending_shot
= shot
;
107 m_protocol
->send(MessagePtr(new MoveMessage(shot
->pos())));
110 shot
->execute(HitInfo::INVALID
);
114 void NetworkEntity::received(MessagePtr msg
)
119 void NetworkEntity::visit(const HeaderMessage
& msg
)
121 if (msg
.clientName() == "KBattleship" && msg
.clientVersion().toFloat() >= 4.0) {
122 // m_level = COMPAT_KBS4;
125 if (m_level
!= COMPAT_KBS3
) {
126 m_level
= COMPAT_KBS3
;
127 emit
compatibility(m_level
);
132 void NetworkEntity::visit(const RejectMessage
&)
137 void NetworkEntity::visit(const NickMessage
& msg
)
139 setNick(msg
.nickname());
140 emit
nick(m_player
, m_nick
);
143 void NetworkEntity::visit(const BeginMessage
&)
145 m_sea
->add(m_player
, 4);
146 emit
ready(m_player
);
149 void NetworkEntity::visit(const MoveMessage
& msg
)
151 emit
shoot(m_player
, msg
.move());
154 void NetworkEntity::visit(const NotificationMessage
& msg
)
156 if (m_pending_shot
) {
157 if (m_pending_shot
->pos() != msg
.move()) {
158 m_pending_shot
->execute(HitInfo::INVALID
);
161 HitInfo info
= msg
.hit() ? HitInfo::HIT
: HitInfo::MISS
;
164 Coord delta
= msg
.stop() - msg
.start();
165 int size
= abs(delta
.x
) + abs(delta
.y
) + 1;
166 Ship::Direction direction
= delta
.x
== 0 ? Ship::TOP_DOWN
: Ship::LEFT_TO_RIGHT
;
167 Coord shipPos
= (delta
.x
< 0 || delta
.y
< 0) ? msg
.stop() : msg
.start();
168 Ship
* ship
= new Ship(size
, direction
);
170 info
.shipDestroyed
= ship
;
171 info
.shipPos
= shipPos
;
174 m_sea
->forceHit(msg
.move(), info
);
175 if (m_level
== COMPAT_KBS3
&& info
.shipDestroyed
) {
176 m_sea
->addBorder(m_player
, info
.shipPos
);
178 m_pending_shot
->execute(info
);
185 void NetworkEntity::visit(const GameOverMessage
&)
190 void NetworkEntity::visit(const RestartMessage
&)
192 emit
restartRequested();
195 void NetworkEntity::visit(const ChatMessage
& msg
)
197 emit
chat(msg
.chat());
200 KIcon
NetworkEntity::icon() const
202 return KIcon("network-workgroup");
205 #include "networkentity.moc"