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("&","&"); 0247 theName = theName.replace("<","<"); 0248 theName = theName.replace(">",">"); 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("&","&"); 0256 nationName = nationName.replace("<","<"); 0257 nationName = nationName.replace(">",">"); 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"