File indexing completed on 2024-10-06 06:48:48

0001 /* This file is part of KsirK.
0002    Copyright (C) 2001-2007 Gaƫl de Chalendar <kleag@free.fr>
0003 
0004    KsirK is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU General Public
0006    License as published by the Free Software Foundation, either version 2
0007    of the License, or (at your option) any later version.
0008 
0009    This program is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    General Public License for more details.
0013 
0014    You should have received a copy of the GNU General Public License
0015    along with this program; if not, write to the Free Software
0016    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0017    02110-1301, USA
0018 */
0019 
0020 /*  begin                : Wed Jul 18 2001 */
0021 
0022 #include "player.h"
0023 #include "Sprites/backgnd.h"
0024 #include "Sprites/skinSpritesData.h"
0025 #include "GameLogic/onu.h"
0026 #include "kgamewin.h"
0027 
0028 #include "ksirk_debug.h"
0029 #include <KLocalizedString>
0030 #include <KMessageBox>
0031 #include <KStringHandler>
0032 
0033 namespace Ksirk
0034 {
0035 
0036 namespace GameLogic
0037 {
0038 
0039 Player::Player(
0040     GameAutomaton* automaton,
0041     const QString& playerName, 
0042     unsigned int nbArmies, 
0043     Nationality* nation) :
0044   KPlayer(),
0045   m_automaton(automaton),
0046   m_nation(nation),
0047   m_goal(automaton),
0048   m_delayedInitNationName(""),
0049   m_waitedAck(""),
0050   m_flag(nullptr)
0051 {
0052   qCDebug(KSIRK_LOG) << "Player constructor";
0053   setAsyncInput(true);
0054   dataHandler()->setPolicy(KGamePropertyBase::PolicyClean,false);
0055   m_nbAttack.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_nbAttack"));
0056   m_nbCountries.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_nbCountries"));
0057 //   m_nbAvailArmies.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_nbAvailArmies"));
0058   m_nbDefense.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_nbDefense"));
0059   m_password.registerData(dataHandler(),KGamePropertyBase::PolicyClean,QString("m_password"));
0060   
0061   m_nbAttack = 0;
0062   m_nbDefense = 0;
0063   m_nbCountries = 0;
0064   m_distributionData.init(nbArmies, m_automaton->game()->theWorld()->getNbCountries());
0065 //   m_nbAvailArmies = nbArmies;
0066   m_password = "";
0067   
0068   setName(playerName);
0069   setFlag();
0070   qCDebug(KSIRK_LOG) << "Done creating player";
0071 }
0072 
0073 bool Player::operator==(const Player& player) const
0074 {
0075   return (name() == player.name());
0076 }
0077 
0078 void Player::reset()
0079 {
0080   m_distributionData.init(0, m_automaton->game()->theWorld()->getNbCountries());
0081 }
0082 
0083 
0084 /**  */
0085 unsigned int Player::getNbAvailArmies()
0086 {
0087   return (m_distributionData.nbToPlace());
0088 //   return (m_nbAvailArmies);
0089 }
0090 
0091 /**  */
0092 void Player::setNbAvailArmies(unsigned int nb, bool transmit)
0093 {
0094   qCDebug(KSIRK_LOG) << name() << " setNbAvailArmies: " << nb << " transmit=" << transmit ;
0095   m_distributionData.setNbToPlace(nb);
0096   if (transmit)
0097   {
0098     QByteArray buffer;
0099     QDataStream stream(&buffer, QIODevice::WriteOnly);
0100     stream << name() << m_distributionData.nbToPlace();
0101     m_automaton->sendMessage(buffer, PlayerAvailArmies);
0102   }
0103 }
0104 
0105 /**  */
0106 unsigned int Player::getNbAttack()
0107 {
0108   qCDebug(KSIRK_LOG) << m_nbAttack;
0109   return (m_nbAttack);
0110 }
0111 
0112 /**  */
0113 void Player::setNbAttack(unsigned int nb)
0114 {
0115   qCDebug(KSIRK_LOG) << name() << nb;
0116   m_nbAttack = nb;
0117 }
0118 
0119 /**  */
0120 unsigned int Player::getNbDefense()
0121 {
0122   qCDebug(KSIRK_LOG) << m_nbDefense;
0123   return (m_nbDefense);
0124 }
0125 
0126 /**  */
0127 void Player::setNbDefense(unsigned int nb)
0128 {
0129   qCDebug(KSIRK_LOG) << name() << nb;
0130   m_nbDefense = nb;
0131 }
0132 
0133 /** */
0134 unsigned int Player::getNbCountries() const
0135 {
0136   return (m_nbCountries);
0137 }
0138 
0139 /** add nb armies to the number of available armies */
0140 void Player::incrNbAvailArmies(unsigned int nb)
0141 {
0142   m_distributionData.setNbToPlace(m_distributionData.nbToPlace() + nb);
0143 }
0144 
0145 /** remove nb armies to the number of available armies */
0146 void Player::decrNbAvailArmies(unsigned int nb)
0147 {
0148 //   qCDebug(KSIRK_LOG) << "Player::decrNbAvailArmies " << name() << " " << nb ;
0149   if (nb > (unsigned)m_distributionData.nbToPlace()/*m_nbAvailArmies*/)
0150   {
0151     qCCritical(KSIRK_LOG) << "Removing " << nb << " armies while owning " << m_distributionData.nbToPlace()/*m_nbAvailArmies*/;
0152     Q_ASSERT(false);
0153   }
0154   m_distributionData.setNbToPlace(m_distributionData.nbToPlace() - nb);
0155 }
0156 
0157 void Player::putArmiesInto(int nb, int country)
0158 {
0159   qCDebug(KSIRK_LOG) << nb << country << m_distributionData[country];
0160   if (nb > m_distributionData.nbToPlace()/*m_nbAvailArmies*/)
0161   {
0162     qCCritical(KSIRK_LOG) << "Removing " << nb << " armies while owning " << m_distributionData.nbToPlace()/*m_nbAvailArmies*/;
0163     exit(1);
0164   }
0165   m_distributionData.setNbToPlace(m_distributionData.nbToPlace() - nb);
0166   m_distributionData[country] = m_distributionData[country] + nb;
0167 }
0168 
0169 void Player::removeArmiesFrom(int nb, int country)
0170 {
0171   qCDebug(KSIRK_LOG) << nb << m_distributionData[country];
0172   if (nb > m_distributionData[country])
0173   {
0174     qCCritical(KSIRK_LOG) << "Trying to remove " << nb << " armies while x were added: x=" << m_distributionData[country];
0175     exit(1);
0176   }
0177   m_distributionData.setNbToPlace(m_distributionData.nbToPlace() + nb);
0178   m_distributionData[country] = m_distributionData[country] - nb;
0179 }
0180 
0181 bool Player::canRemoveArmiesFrom(int nb, int country)
0182 {
0183   qCDebug(KSIRK_LOG) << nb << m_distributionData[country];
0184   return (nb <= m_distributionData[country]);
0185 }
0186 
0187 
0188 /**  */
0189 void Player::setNbCountries(unsigned int nb)
0190 {
0191   m_nbCountries = nb;
0192 }
0193 
0194 /** add nb countries to the player */
0195 void Player::incrNbCountries(unsigned int nb)
0196 {
0197   setNbCountries(m_nbCountries + nb);
0198 }
0199 
0200 /** Enleve nb pays au player */
0201 void Player::decrNbCountries(unsigned int nb)
0202 {
0203     if (nb > m_nbCountries)
0204     {
0205       qCCritical(KSIRK_LOG) << "Removing " << nb << " countries to " << name() << " while owning " << m_nbCountries ;
0206       exit(1);
0207     }
0208   setNbCountries(m_nbCountries - nb);
0209 }
0210 
0211 /**
0212   * This function returns the flag associated to the nationality of the player
0213   */
0214 const AnimSprite* Player::getFlag() const
0215 {
0216 //   qCDebug(KSIRK_LOG) << "Player::getFlag";
0217   return m_flag;
0218 }
0219 
0220 /**
0221   * This function returns the filename of the flag associated to the nationality of the player
0222   */
0223 const QString& Player::flagFileName() const
0224 {
0225     return m_nation-> flagFileName();
0226 }
0227 
0228 /**
0229   * Returns false (a Player is not an AI)
0230   */
0231 bool Player::isAI() const
0232 {
0233     return false;
0234 }
0235 
0236 void Player::saveXml(QTextStream& xmlStream)
0237 {
0238   xmlStream << "<player ai=\"false\" ";
0239   innerSaveXml(xmlStream);
0240   xmlStream << " />";
0241 }
0242 
0243 void Player::innerSaveXml(QTextStream& xmlStream)
0244 {
0245   QString theName = name();
0246   theName = theName.replace("&","&amp;");
0247   theName = theName.replace("<","&lt;");
0248   theName = theName.replace(">","&gt;");
0249   xmlStream << " name=\"" << theName << "\"";
0250   xmlStream << " nbCountries=\"" << m_nbCountries << "\"";
0251   xmlStream << " nbAvailArmies=\"" << m_distributionData.nbToPlace() << "\"";
0252   xmlStream << " nbAttack=\"" << m_nbAttack << "\"";
0253   xmlStream << " nbDefense=\"" << m_nbDefense << "\"";
0254   QString nationName = m_nation->name();
0255   nationName = nationName.replace("&","&amp;");
0256   nationName = nationName.replace("<","&lt;");
0257   nationName = nationName.replace(">","&gt;");
0258   xmlStream << " nation=\"" << nationName << "\"";
0259   xmlStream << " password=\"" << KStringHandler::obscure(m_password.value()) << "\"";
0260   xmlStream << " local=\"" << (isVirtual()?"false":"true") << "\"";
0261 }
0262 
0263 bool Player::load (QDataStream &stream)
0264 {
0265 //   qCDebug(KSIRK_LOG) << "Player::load";
0266   if (!KPlayer::load(stream)) return false;
0267   QString nationName;
0268   stream >> nationName;
0269 //   qCDebug(KSIRK_LOG) << "Player::load nationName=" << nationName ;
0270   setNation(nationName);
0271   stream >> m_goal;
0272   int nbToPlace;
0273   stream >> nbToPlace;
0274   int nbCountries;
0275   stream >> nbCountries;
0276   m_distributionData.init(nbToPlace, nbCountries);
0277   for (int i = 0; i < nbCountries; i++)
0278   {
0279     int nb;
0280     stream >> nb;
0281     m_distributionData[i] = nb;
0282   }
0283   return true;
0284 }
0285 
0286 bool Player::save (QDataStream &stream)
0287 {
0288 //   qCDebug(KSIRK_LOG) << "Player::save";
0289   if (!KPlayer::save(stream)) return false;
0290   stream << m_nation->name();
0291   stream << m_goal;
0292   stream << m_distributionData.nbToPlace();
0293   stream << m_distributionData.size();
0294   for (int i = 0; i < m_distributionData.size(); i++)
0295   {
0296     stream << m_distributionData[i];
0297   }
0298   return true;
0299 }
0300 
0301 Nationality* Player::getNation() 
0302 {
0303   qCDebug(KSIRK_LOG) << "Player::getNation for " << name();
0304   if (m_nation == nullptr && !m_delayedInitNationName.isEmpty())
0305   {
0306     qCCritical(KSIRK_LOG) << "  retrieving delayed nation " << m_delayedInitNationName ;
0307     setNation(m_delayedInitNationName);
0308   }
0309   return m_nation;
0310 }
0311 
0312 void Player::setNation(const QString& nationName)
0313 {
0314   m_nation = m_automaton->game()->theWorld()-> nationNamed(nationName);
0315   if (m_nation == nullptr)
0316   {
0317 //     qCDebug(KSIRK_LOG) << "Delaying nation initialization ("<<nationName<<") for " << name();
0318     m_delayedInitNationName = nationName;
0319   }
0320   setFlag();
0321 }
0322 
0323 void Player::setFlag()
0324 {
0325 /*  if (m_flag != 0)
0326     delete m_flag;*/
0327   m_flag = nullptr;
0328   if (m_nation != nullptr)
0329   {
0330     m_flag = new AnimSprite(
0331                             m_nation->flagFileName(), 
0332                             Sprites::SkinSpritesData::single().intData("flag-width"),
0333                             Sprites::SkinSpritesData::single().intData("flag-height"),
0334                             Sprites::SkinSpritesData::single().intData("flag-frames"), 
0335                             Sprites::SkinSpritesData::single().intData("flag-versions"),
0336                             m_automaton->game()->backGnd()->onu()->zoom(),
0337                             m_automaton->game()->backGnd());
0338     m_flag->hide();
0339   }
0340 }
0341 
0342 void Player::goal(const Goal& goal)
0343 {
0344   qCDebug(KSIRK_LOG) << "Player::goal (setter) " << name();
0345 /*  if (m_goal)
0346   {
0347     delete m_goal;
0348   }*/
0349   m_goal = Goal(goal);
0350   m_goal.player(this);
0351 /*  if (!isVirtual() && !isAI())
0352   {
0353     KMessageBox::information(
0354       GameAutomaton::changeable().game(),
0355       i18n("%1, your goal will be displayed. Please make sure that no other player can see it !",name()),
0356       i18n("KsirK - Displaying Goal"));
0357     m_goal->show();
0358   }*/
0359 }
0360 
0361 bool Player::checkGoal()
0362 {
0363   return m_goal.checkFor(this);
0364 }
0365 
0366 /**
0367   * Returns the list of the countries owned by this player
0368   */
0369 QList<Country*> Player::countries() const
0370 {
0371 //   qCDebug(KSIRK_LOG) << name() << ": Player::countries()";
0372   QList<Country*> list;
0373   foreach (Country* c, m_automaton->game()->theWorld()->getCountries())
0374   {
0375     if (c-> owner() == static_cast< const Player * >(this))
0376     {
0377 //            qCDebug(KSIRK_LOG) << "\t" << c-> name();
0378       
0379       list.push_back(c);
0380     }
0381   }
0382 //    qCDebug(KSIRK_LOG) << name() << ": OUT AIPlayer::countries()";
0383   return list;
0384 }
0385 
0386 bool Player::acknowledge(const QString& ack)
0387 {
0388   QMutexLocker locker(&m_waitedAckMutex);
0389   
0390   if (ack == m_waitedAck)
0391   {
0392     m_waitedAck = "";
0393     qCDebug(KSIRK_LOG) << ack << true;
0394     return true;
0395   }
0396   else
0397   {
0398     qCDebug(KSIRK_LOG) << ack << false;
0399     return false;
0400   }
0401 }
0402 
0403 QDataStream& operator<<(QDataStream& stream, PlayerMatrix& p)
0404 {
0405   stream << p.name << quint32(p.nbAttack) << quint32(p.nbCountries) << quint32(p.nbAvailArmies)
0406     << quint32(p.nbDefense) << p.nation << quint32(p.isAI) << quint32(p.countries.size());
0407   foreach (const QString& s, p.countries)
0408   {
0409     stream << s;
0410   }
0411   stream << p.goal;
0412 /*  stream << m_distributionData.nbToPlace();
0413   stream << m_distributionData.size();
0414   for (int i = 0; i < m_distributionData.size(); i++)
0415   {
0416     stream << m_distributionData[i];
0417   }*/
0418   return stream;
0419 }
0420 
0421 QDataStream& operator>>(QDataStream& stream, PlayerMatrix& p)
0422 {
0423   quint32 nbCountries;
0424   stream >> p.name >> p.nbAttack >> p.nbCountries >> p.nbAvailArmies >> p.nbDefense >> p.nation;
0425   quint32 isAI;
0426   stream >> isAI;
0427   p.isAI = (bool)isAI;
0428   stream >> nbCountries;
0429   for (quint32 i = 0 ; i < nbCountries; i++)
0430   {
0431     QString country;
0432     stream >> country;
0433     p.countries.push_back(country);
0434   }
0435   stream >> p.goal;
0436 /*  int nbToPlace;
0437   stream >> nbToPlace;
0438   int nbCountries;
0439   stream >> nbCountries;
0440   m_distributionData.init(nbToPlace, nbCountries);
0441   for (int i = 0; i < nbCountries; i++)
0442   {
0443     int nb;
0444     stream >> nb;
0445     m_distributionData[i] = nb;
0446   }*/
0447   return stream;
0448 }
0449 
0450 } // closing namespace GameLogic
0451 
0452 } // closing namespace Ksirk
0453 
0454 #include "moc_player.cpp"