1 /* This file is part of KsirK.
2 Copyright (C) 2001-2007 Gaël de Chalendar <kleag@free.fr>
3
4 KsirK is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public
6 License as published by the Free Software Foundation, either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA
18 */
19
20 /* begin : Wed Jul 18 2001 */
21
22 #define KDE_NO_COMPAT
23 #include "player.h"
24 #include "Sprites/backgnd.h"
25 #include "Sprites/skinSpritesData.h"
26 #include "GameLogic/onu.h"
27 #include "kgamewin.h"
28
29 #include "ksirk_debug.h"
30 #include <KLocalizedString>
31 #include <KMessageBox>
32 #include <KStringHandler>
33
34 namespace Ksirk
35 {
36
37 namespace GameLogic
38 {
39
Player(GameAutomaton * automaton,const QString & playerName,unsigned int nbArmies,Nationality * nation)40 Player::Player(
41 GameAutomaton* automaton,
42 const QString& playerName,
43 unsigned int nbArmies,
44 Nationality* nation) :
45 KPlayer(),
46 m_automaton(automaton),
47 m_nation(nation),
48 m_goal(automaton),
49 m_delayedInitNationName(""),
50 m_waitedAck(""),
51 m_flag(0)
52 {
53 qCDebug(KSIRK_LOG) << "Player constructor";
54 setAsyncInput(true);
55 dataHandler()->setPolicy(KGamePropertyBase::PolicyClean,false);
56 m_nbAttack.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_nbAttack"));
57 m_nbCountries.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_nbCountries"));
58 // m_nbAvailArmies.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_nbAvailArmies"));
59 m_nbDefense.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_nbDefense"));
60 m_password.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_password"));
61
62 m_nbAttack = 0;
63 m_nbDefense = 0;
64 m_nbCountries = 0;
65 m_distributionData.init(nbArmies, m_automaton->game()->theWorld()->getNbCountries());
66 // m_nbAvailArmies = nbArmies;
67 m_password = "";
68
69 setName(playerName);
70 setFlag();
71 qCDebug(KSIRK_LOG) << "Done creating player";
72 }
73
operator ==(const Player & player) const74 bool Player::operator==(const Player& player) const
75 {
76 return (name() == player.name());
77 }
78
reset()79 void Player::reset()
80 {
81 m_distributionData.init(0, m_automaton->game()->theWorld()->getNbCountries());
82 }
83
84
85 /** */
getNbAvailArmies()86 unsigned int Player::getNbAvailArmies()
87 {
88 return (m_distributionData.nbToPlace());
89 // return (m_nbAvailArmies);
90 }
91
92 /** */
setNbAvailArmies(unsigned int nb,bool transmit)93 void Player::setNbAvailArmies(unsigned int nb, bool transmit)
94 {
95 qCDebug(KSIRK_LOG) << name() << " setNbAvailArmies: " << nb << " transmit=" << transmit ;
96 m_distributionData.setNbToPlace(nb);
97 if (transmit)
98 {
99 QByteArray buffer;
100 QDataStream stream(&buffer, QIODevice::WriteOnly);
101 stream << name() << m_distributionData.nbToPlace();
102 m_automaton->sendMessage(buffer, PlayerAvailArmies);
103 }
104 }
105
106 /** */
getNbAttack()107 unsigned int Player::getNbAttack()
108 {
109 qCDebug(KSIRK_LOG) << m_nbAttack;
110 return (m_nbAttack);
111 }
112
113 /** */
setNbAttack(unsigned int nb)114 void Player::setNbAttack(unsigned int nb)
115 {
116 qCDebug(KSIRK_LOG) << name() << nb;
117 m_nbAttack = nb;
118 }
119
120 /** */
getNbDefense()121 unsigned int Player::getNbDefense()
122 {
123 qCDebug(KSIRK_LOG) << m_nbDefense;
124 return (m_nbDefense);
125 }
126
127 /** */
setNbDefense(unsigned int nb)128 void Player::setNbDefense(unsigned int nb)
129 {
130 qCDebug(KSIRK_LOG) << name() << nb;
131 m_nbDefense = nb;
132 }
133
134 /** */
getNbCountries() const135 unsigned int Player::getNbCountries() const
136 {
137 return (m_nbCountries);
138 }
139
140 /** add nb armies to the number of available armies */
incrNbAvailArmies(unsigned int nb)141 void Player::incrNbAvailArmies(unsigned int nb)
142 {
143 m_distributionData.setNbToPlace(m_distributionData.nbToPlace() + nb);
144 }
145
146 /** remove nb armies to the number of available armies */
decrNbAvailArmies(unsigned int nb)147 void Player::decrNbAvailArmies(unsigned int nb)
148 {
149 // qCDebug(KSIRK_LOG) << "Player::decrNbAvailArmies " << name() << " " << nb ;
150 if (nb > (unsigned)m_distributionData.nbToPlace()/*m_nbAvailArmies*/)
151 {
152 qCCritical(KSIRK_LOG) << "Removing " << nb << " armies while owning " << m_distributionData.nbToPlace()/*m_nbAvailArmies*/;
153 Q_ASSERT(false);
154 }
155 m_distributionData.setNbToPlace(m_distributionData.nbToPlace() - nb);
156 }
157
putArmiesInto(int nb,int country)158 void Player::putArmiesInto(int nb, int country)
159 {
160 qCDebug(KSIRK_LOG) << nb << country << m_distributionData[country];
161 if (nb > m_distributionData.nbToPlace()/*m_nbAvailArmies*/)
162 {
163 qCCritical(KSIRK_LOG) << "Removing " << nb << " armies while owning " << m_distributionData.nbToPlace()/*m_nbAvailArmies*/;
164 exit(1);
165 }
166 m_distributionData.setNbToPlace(m_distributionData.nbToPlace() - nb);
167 m_distributionData[country] = m_distributionData[country] + nb;
168 }
169
removeArmiesFrom(int nb,int country)170 void Player::removeArmiesFrom(int nb, int country)
171 {
172 qCDebug(KSIRK_LOG) << nb << m_distributionData[country];
173 if (nb > m_distributionData[country])
174 {
175 qCCritical(KSIRK_LOG) << "Trying to remove " << nb << " armies while x were added: x=" << m_distributionData[country];
176 exit(1);
177 }
178 m_distributionData.setNbToPlace(m_distributionData.nbToPlace() + nb);
179 m_distributionData[country] = m_distributionData[country] - nb;
180 }
181
canRemoveArmiesFrom(int nb,int country)182 bool Player::canRemoveArmiesFrom(int nb, int country)
183 {
184 qCDebug(KSIRK_LOG) << nb << m_distributionData[country];
185 return (nb <= m_distributionData[country]);
186 }
187
188
189 /** */
setNbCountries(unsigned int nb)190 void Player::setNbCountries(unsigned int nb)
191 {
192 m_nbCountries = nb;
193 }
194
195 /** add nb countries to the player */
incrNbCountries(unsigned int nb)196 void Player::incrNbCountries(unsigned int nb)
197 {
198 setNbCountries(m_nbCountries + nb);
199 }
200
201 /** Enleve nb pays au player */
decrNbCountries(unsigned int nb)202 void Player::decrNbCountries(unsigned int nb)
203 {
204 if (nb > m_nbCountries)
205 {
206 qCCritical(KSIRK_LOG) << "Removing " << nb << " countries to " << name() << " while owning " << m_nbCountries ;
207 exit(1);
208 }
209 setNbCountries(m_nbCountries - nb);
210 }
211
212 /**
213 * This function returns the flag associated to the nationality of the player
214 */
getFlag() const215 const AnimSprite* Player::getFlag() const
216 {
217 // qCDebug(KSIRK_LOG) << "Player::getFlag";
218 return m_flag;
219 }
220
221 /**
222 * This function returns the filename of the flag associated to the nationality of the player
223 */
flagFileName() const224 const QString& Player::flagFileName() const
225 {
226 return m_nation-> flagFileName();
227 }
228
229 /**
230 * Returns false (a Player is not an AI)
231 */
isAI() const232 bool Player::isAI() const
233 {
234 return false;
235 }
236
saveXml(QTextStream & xmlStream)237 void Player::saveXml(QTextStream& xmlStream)
238 {
239 xmlStream << "<player ai=\"false\" ";
240 innerSaveXml(xmlStream);
241 xmlStream << " />";
242 }
243
innerSaveXml(QTextStream & xmlStream)244 void Player::innerSaveXml(QTextStream& xmlStream)
245 {
246 QString theName = name();
247 theName = theName.replace("&","&");
248 theName = theName.replace("<","<");
249 theName = theName.replace(">",">");
250 xmlStream << " name=\"" << theName << "\"";
251 xmlStream << " nbCountries=\"" << m_nbCountries << "\"";
252 xmlStream << " nbAvailArmies=\"" << m_distributionData.nbToPlace() << "\"";
253 xmlStream << " nbAttack=\"" << m_nbAttack << "\"";
254 xmlStream << " nbDefense=\"" << m_nbDefense << "\"";
255 QString nationName = m_nation->name();
256 nationName = nationName.replace("&","&");
257 nationName = nationName.replace("<","<");
258 nationName = nationName.replace(">",">");
259 xmlStream << " nation=\"" << nationName << "\"";
260 xmlStream << " password=\"" << KStringHandler::obscure(m_password.value()) << "\"";
261 xmlStream << " local=\"" << (isVirtual()?"false":"true") << "\"";
262 }
263
load(QDataStream & stream)264 bool Player::load (QDataStream &stream)
265 {
266 // qCDebug(KSIRK_LOG) << "Player::load";
267 if (!KPlayer::load(stream)) return false;
268 QString nationName;
269 stream >> nationName;
270 // qCDebug(KSIRK_LOG) << "Player::load nationName=" << nationName ;
271 setNation(nationName);
272 stream >> m_goal;
273 int nbToPlace;
274 stream >> nbToPlace;
275 int nbCountries;
276 stream >> nbCountries;
277 m_distributionData.init(nbToPlace, nbCountries);
278 for (int i = 0; i < nbCountries; i++)
279 {
280 int nb;
281 stream >> nb;
282 m_distributionData[i] = nb;
283 }
284 return true;
285 }
286
save(QDataStream & stream)287 bool Player::save (QDataStream &stream)
288 {
289 // qCDebug(KSIRK_LOG) << "Player::save";
290 if (!KPlayer::save(stream)) return false;
291 stream << m_nation->name();
292 stream << m_goal;
293 stream << m_distributionData.nbToPlace();
294 stream << m_distributionData.size();
295 for (int i = 0; i < m_distributionData.size(); i++)
296 {
297 stream << m_distributionData[i];
298 }
299 return true;
300 }
301
getNation()302 Nationality* Player::getNation()
303 {
304 qCDebug(KSIRK_LOG) << "Player::getNation for " << name();
305 if (m_nation == 0 && !m_delayedInitNationName.isEmpty())
306 {
307 qCCritical(KSIRK_LOG) << " retrieving delayed nation " << m_delayedInitNationName ;
308 setNation(m_delayedInitNationName);
309 }
310 return m_nation;
311 }
312
setNation(const QString & nationName)313 void Player::setNation(const QString& nationName)
314 {
315 m_nation = m_automaton->game()->theWorld()-> nationNamed(nationName);
316 if (m_nation == 0)
317 {
318 // qCDebug(KSIRK_LOG) << "Delaying nation initialization ("<<nationName<<") for " << name();
319 m_delayedInitNationName = nationName;
320 }
321 setFlag();
322 }
323
setFlag()324 void Player::setFlag()
325 {
326 /* if (m_flag != 0)
327 delete m_flag;*/
328 m_flag = 0;
329 if (m_nation != 0)
330 {
331 m_flag = new AnimSprite(
332 m_nation->flagFileName(),
333 Sprites::SkinSpritesData::single().intData("flag-width"),
334 Sprites::SkinSpritesData::single().intData("flag-height"),
335 Sprites::SkinSpritesData::single().intData("flag-frames"),
336 Sprites::SkinSpritesData::single().intData("flag-versions"),
337 m_automaton->game()->backGnd()->onu()->zoom(),
338 m_automaton->game()->backGnd());
339 m_flag->hide();
340 }
341 }
342
goal(const Goal & goal)343 void Player::goal(const Goal& goal)
344 {
345 qCDebug(KSIRK_LOG) << "Player::goal (setter) " << name();
346 /* if (m_goal)
347 {
348 delete m_goal;
349 }*/
350 m_goal = Goal(goal);
351 m_goal.player(this);
352 /* if (!isVirtual() && !isAI())
353 {
354 KMessageBox::information(
355 GameAutomaton::changeable().game(),
356 i18n("%1, your goal will be displayed. Please make sure that no other player can see it !",name()),
357 i18n("KsirK - Displaying Goal"));
358 m_goal->show();
359 }*/
360 }
361
checkGoal()362 bool Player::checkGoal()
363 {
364 return m_goal.checkFor(this);
365 }
366
367 /**
368 * Returns the list of the countries owned by this player
369 */
countries() const370 QList<Country*> Player::countries() const
371 {
372 // qCDebug(KSIRK_LOG) << name() << ": Player::countries()";
373 QList<Country*> list;
374 foreach (Country* c, m_automaton->game()->theWorld()->getCountries())
375 {
376 if (c-> owner() == static_cast< const Player * >(this))
377 {
378 // qCDebug(KSIRK_LOG) << "\t" << c-> name();
379
380 list.push_back(c);
381 }
382 }
383 // qCDebug(KSIRK_LOG) << name() << ": OUT AIPlayer::countries()";
384 return list;
385 }
386
acknowledge(const QString & ack)387 bool Player::acknowledge(const QString& ack)
388 {
389 QMutexLocker locker(&m_waitedAckMutex);
390
391 if (ack == m_waitedAck)
392 {
393 m_waitedAck = "";
394 qCDebug(KSIRK_LOG) << ack << true;
395 return true;
396 }
397 else
398 {
399 qCDebug(KSIRK_LOG) << ack << false;
400 return false;
401 }
402 }
403
operator <<(QDataStream & stream,PlayerMatrix & p)404 QDataStream& operator<<(QDataStream& stream, PlayerMatrix& p)
405 {
406 stream << p.name << quint32(p.nbAttack) << quint32(p.nbCountries) << quint32(p.nbAvailArmies)
407 << quint32(p.nbDefense) << p.nation << quint32(p.isAI) << quint32(p.countries.size());
408 foreach (const QString& s, p.countries)
409 {
410 stream << s;
411 }
412 stream << p.goal;
413 /* stream << m_distributionData.nbToPlace();
414 stream << m_distributionData.size();
415 for (int i = 0; i < m_distributionData.size(); i++)
416 {
417 stream << m_distributionData[i];
418 }*/
419 return stream;
420 }
421
operator >>(QDataStream & stream,PlayerMatrix & p)422 QDataStream& operator>>(QDataStream& stream, PlayerMatrix& p)
423 {
424 quint32 nbCountries;
425 stream >> p.name >> p.nbAttack >> p.nbCountries >> p.nbAvailArmies >> p.nbDefense >> p.nation;
426 quint32 isAI;
427 stream >> isAI;
428 p.isAI = (bool)isAI;
429 stream >> nbCountries;
430 for (quint32 i = 0 ; i < nbCountries; i++)
431 {
432 QString country;
433 stream >> country;
434 p.countries.push_back(country);
435 }
436 stream >> p.goal;
437 /* int nbToPlace;
438 stream >> nbToPlace;
439 int nbCountries;
440 stream >> nbCountries;
441 m_distributionData.init(nbToPlace, nbCountries);
442 for (int i = 0; i < nbCountries; i++)
443 {
444 int nb;
445 stream >> nb;
446 m_distributionData[i] = nb;
447 }*/
448 return stream;
449 }
450
451 } // closing namespace GameLogic
452
453 } // closing namespace Ksirk
454
455
456