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("&","&amp;");
248   theName = theName.replace("<","&lt;");
249   theName = theName.replace(">","&gt;");
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("&","&amp;");
257   nationName = nationName.replace("<","&lt;");
258   nationName = nationName.replace(">","&gt;");
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