File indexing completed on 2024-10-06 06:48:48
0001 /* This file is part of KsirK. 0002 * Copyright (C) 2005-2007 Gael de Chalendar (aka Kleag) <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 #include "goal.h" 0020 #include "player.h" 0021 #include "onu.h" 0022 #include "kgamewin.h" 0023 #include "gameautomaton.h" 0024 0025 #include "ksirk_debug.h" 0026 #include <KLocalizedString> 0027 #include <KMessageBox> 0028 0029 namespace Ksirk { 0030 0031 namespace GameLogic { 0032 0033 Goal::Goal() : 0034 m_automaton(nullptr), 0035 m_type(NoGoal), 0036 m_description(""), 0037 m_nbCountries(0), 0038 m_nbArmiesByCountry(0), 0039 m_continents(), 0040 m_players(), 0041 m_player(nullptr) 0042 { 0043 } 0044 0045 Goal::Goal(GameAutomaton* automaton) : 0046 m_automaton(automaton), 0047 m_type(NoGoal), 0048 m_description(""), 0049 m_nbCountries(0), 0050 m_nbArmiesByCountry(0), 0051 m_continents(), 0052 m_players(), 0053 m_player(nullptr) 0054 { 0055 } 0056 0057 Goal::~Goal() 0058 { 0059 } 0060 0061 bool Goal::checkFor(const GameLogic::Player* player) const 0062 { 0063 qCDebug(KSIRK_LOG) << message(GoalAdvance); 0064 int diff = 0; 0065 switch (type()) 0066 { 0067 case Goal::GoalPlayer : 0068 if (m_automaton->playerNamed(*m_players.begin()) != nullptr) 0069 { 0070 return false; 0071 } 0072 else 0073 { 0074 diff = m_nbCountries-m_player->countries().size(); 0075 if (diff > 0) 0076 { 0077 return false; 0078 } 0079 else 0080 { 0081 return true; 0082 } 0083 } 0084 return false; 0085 break; 0086 case Goal::Countries: 0087 return checkCountriesFor(player); 0088 break; 0089 case Goal::Continents: 0090 return checkContinentsFor(player); 0091 break; 0092 default: 0093 return ((int) player->getNbCountries() >= m_automaton->game()->theWorld()->getCountries().size()); 0094 } 0095 } 0096 0097 bool Goal::checkCountriesFor(const GameLogic::Player* player) const 0098 { 0099 qCDebug(KSIRK_LOG) << player->name(); 0100 if (player->getNbCountries() >= m_nbCountries) 0101 { 0102 uint nbCountriesOk = 0; 0103 foreach (Country* country, player->countries()) 0104 { 0105 if (country->nbArmies() >= m_nbArmiesByCountry) 0106 { 0107 nbCountriesOk++; 0108 } 0109 } 0110 return (nbCountriesOk >= m_nbCountries); 0111 } 0112 else 0113 { 0114 return false; 0115 } 0116 } 0117 0118 bool Goal::checkContinentsFor(const GameLogic::Player* player) const 0119 { 0120 qCDebug(KSIRK_LOG) << "Goal::checkContinentsFor " << player->name(); 0121 foreach (const QString& continent, m_continents) 0122 { 0123 qCDebug(KSIRK_LOG) << "Should be owned continent id: " << continent; 0124 if ( m_automaton->game()->theWorld()->continentNamed(continent) == nullptr 0125 || m_automaton->game()->theWorld()->continentNamed(continent)->owner() != player) 0126 { 0127 return false; 0128 } 0129 } 0130 if (!m_continents.contains(QString())) 0131 { 0132 return true; 0133 } 0134 bool otherFound = false; 0135 QList<Continent*>& continents = m_automaton->game()->theWorld()->getContinents(); 0136 foreach (Continent* continent, continents) 0137 { 0138 if ( ( !m_continents.contains(continent->name()) ) 0139 && ( continent->owner() == player) ) 0140 { 0141 otherFound = true; 0142 break; 0143 } 0144 } 0145 return otherFound; 0146 } 0147 0148 QString Goal::message(int displayType) const 0149 { 0150 qCDebug(KSIRK_LOG); 0151 KLocalizedString res; 0152 0153 QList<QString>::const_iterator it, it_end, it_next; 0154 0155 if(type()==NoGoal) { 0156 QString mes = i18n("You must conquer the World!"); 0157 return mes; 0158 } 0159 else 0160 { 0161 if (displayType & GoalDesc) 0162 { 0163 res = ki18n(m_description.toUtf8().data()); 0164 if (m_player == nullptr) 0165 { 0166 res = res.subs(""); 0167 } 0168 else 0169 { 0170 res = res.subs(m_player->name()); 0171 } 0172 qCDebug(KSIRK_LOG) << "Goal type='" << m_type << "' mes = '" << res.toString() << "'"; 0173 0174 QList<unsigned int>::const_iterator it, it_end; 0175 switch (m_type) 0176 { 0177 case Goal::GoalPlayer : 0178 if (!m_players.empty()) 0179 { 0180 qCDebug(KSIRK_LOG) << " player name='" << *m_players.begin(); 0181 qCDebug(KSIRK_LOG) << " this is player='" << m_automaton->playerNamed(*m_players.begin()); 0182 if (m_automaton->playerNamed(*m_players.begin())==nullptr) 0183 { 0184 res = res.subs(i18n("%1 (already dead)",*m_players.begin())); 0185 } 0186 else 0187 { 0188 qCDebug(KSIRK_LOG) << " its name is='" << *m_players.begin(); 0189 res = res.subs(*m_players.begin()); 0190 } 0191 res = res.subs(m_nbCountries); 0192 } 0193 else 0194 { 0195 res = res.subs(i18n("Error: no player to destroy")); 0196 } 0197 break; 0198 case Goal::Countries: 0199 qCDebug(KSIRK_LOG) << " arg1 = '" << m_nbCountries << "'"; 0200 res=res.subs(m_nbCountries); 0201 if (m_nbArmiesByCountry > 0) 0202 { 0203 qCDebug(KSIRK_LOG) << " arg2 = '" << m_nbArmiesByCountry << "'"; 0204 res=res.subs(m_nbArmiesByCountry); 0205 } 0206 break; 0207 case Goal::Continents: 0208 foreach (const QString& continent, m_continents) 0209 { 0210 if (!continent.isEmpty()) 0211 { 0212 qCDebug(KSIRK_LOG) << " arg = '" << continent << "'"; 0213 res=res.subs(i18n(continent.toUtf8().data())); 0214 } 0215 } 0216 break; 0217 default:; 0218 } 0219 } 0220 } 0221 0222 QString mes = res.toString(); 0223 if (displayType & GoalAdvance) 0224 { 0225 int diff = 0; 0226 switch (m_type) 0227 { 0228 case Goal::GoalPlayer : 0229 if (m_automaton->playerNamed(*m_players.begin()) != nullptr) 0230 { 0231 mes += i18n("<br>%1 is still alive...",*m_players.begin()); 0232 } 0233 else 0234 { 0235 diff = m_nbCountries-m_player->countries().size(); 0236 if (diff > 0) 0237 { 0238 mes += i18np("<br>%2, you still have 1 country to conquer...","<br>%2, you still have %1 countries to conquer...",diff,m_player->name()); 0239 } 0240 else 0241 { 0242 mes += i18np("<br>Your goal is reached: %2 is dead and you possess %1 country.", 0243 "<br>Your goal is reached: %2 is dead and you possess %1 countries.", 0244 m_nbCountries, *m_players.begin()); 0245 } 0246 } 0247 break; 0248 case Goal::Countries: 0249 diff = m_nbCountries-m_player->countries().size(); 0250 if (diff > 0) 0251 { 0252 mes += i18np("<br>%2, you still have 1 country to conquer...","<br>%2, you still have %1 countries to conquer...",diff,m_player->name()); 0253 } 0254 else 0255 { 0256 int nbOk = 0; 0257 for (int i = 0; i < m_player->countries().size();++i) 0258 { 0259 if (m_player->countries().at(i)->nbArmies() >= m_nbArmiesByCountry) 0260 { 0261 nbOk++; 0262 } 0263 } 0264 mes += i18np("<br>%2, you have enough countries but you still have to put more than 1 army on %3 of them...","<br>%2, you have enough countries but you still have to put more than %1 armies on %3 of them...",m_nbArmiesByCountry,m_player->name(),m_nbCountries-nbOk); 0265 0266 } 0267 break; 0268 case Goal::Continents: 0269 mes += i18n("<br>%1, you still have to conquer ",m_player->name()); 0270 it = m_continents.begin(); it_end = m_continents.end(); 0271 if (*it != nullptr) 0272 { 0273 Continent* continent = const_cast<Continent*>(m_automaton->game()->theWorld()->continentNamed(*it)); 0274 int nb = continent->getMembers().size() - continent->countriesOwnedBy(m_player).size(); 0275 mes += i18np("1 country in %2","%1 countries in %2",nb,i18n(continent->name().toUtf8().data())); 0276 } 0277 it++; 0278 while (it != it_end) 0279 { 0280 it_next = it; 0281 it_next++; 0282 QString joint; 0283 if (it_next==it_end) 0284 { 0285 joint = i18n(" and "); 0286 } 0287 else 0288 { 0289 joint = i18n(", "); 0290 } 0291 if (*it != nullptr) 0292 { 0293 Continent* continent = const_cast<Continent*>(m_automaton->game()->theWorld()->continentNamed(*it)); 0294 int nb = continent->getMembers().size() - continent->countriesOwnedBy(m_player).size(); 0295 mes += joint + i18nc("@info An element of the enumeration of the number of countries in the given continent", "%1 in %2",nb,i18n(continent->name().toUtf8().data())); 0296 } 0297 it++; 0298 } 0299 mes += '.'; 0300 break; 0301 default: 0302 break; 0303 ; 0304 } 0305 } 0306 0307 return mes; 0308 } 0309 0310 void Goal::show(int displayType) 0311 { 0312 qCDebug(KSIRK_LOG) << message(displayType); 0313 // m_automaton->game()->showMessage(message(displayType),5, KGameWindow::ForceShowing); 0314 KMessageBox::information( 0315 m_automaton->game(), 0316 message(displayType), 0317 i18n("KsirK - Goal Display")); 0318 } 0319 0320 QDataStream& operator<<(QDataStream& stream, const Goal& goal) 0321 { 0322 qCDebug(KSIRK_LOG) << "Goal operator<< : type" << goal.type(); 0323 stream << quint32(goal.type()); 0324 if (goal.player() != nullptr) 0325 { 0326 qCDebug(KSIRK_LOG) << "Goal operator<< : player " << goal.player()->id(); 0327 stream << quint32(goal.player()->id()); 0328 } 0329 else 0330 { 0331 qCDebug(KSIRK_LOG) << "Goal operator<< : player " << 0 ; 0332 stream << quint32(0); 0333 } 0334 qCDebug(KSIRK_LOG) << "Goal operator<< : description " << goal.description(); 0335 stream << goal.description(); 0336 QList<QString>::ConstIterator it, it_end; 0337 QList<QString>::ConstIterator itc, itc_end; 0338 switch (goal.type()) 0339 { 0340 case Goal::GoalPlayer : 0341 qCDebug(KSIRK_LOG) << "Goal operator<< : players " << goal.players().size(); 0342 stream << quint32(goal.players().size()); 0343 it = goal.players().constBegin(); it_end = goal.players().constEnd(); 0344 for (; it != it_end; it++) 0345 { 0346 qCDebug(KSIRK_LOG) << "Goal operator<< : player " << (*it); 0347 stream << *it; 0348 } 0349 qCDebug(KSIRK_LOG) << "Goal operator<< : nbCountries " << goal.nbCountries(); 0350 stream << quint32(goal.nbCountries()); 0351 break; 0352 case Goal::Countries: 0353 qCDebug(KSIRK_LOG) << "Goal operator<< : nbCountries " << goal.nbCountries(); 0354 stream << quint32(goal.nbCountries()); 0355 qCDebug(KSIRK_LOG) << "Goal operator<< : nbArmiesByCountry " << goal.nbArmiesByCountry(); 0356 stream << quint32(goal.nbArmiesByCountry()); 0357 break; 0358 case Goal::Continents: 0359 qCDebug(KSIRK_LOG) << "Goal operator<< : continents " << goal.continents().size(); 0360 stream << quint32(goal.continents().size()); 0361 itc = goal.continents().constBegin(); itc_end = goal.continents().constEnd(); 0362 for (; itc != itc_end; itc++) 0363 { 0364 qCDebug(KSIRK_LOG) << "Goal operator<< : continent " << (*itc); 0365 stream << (*itc); 0366 } 0367 break; 0368 default: break; 0369 } 0370 return stream; 0371 } 0372 0373 QDataStream& operator>>(QDataStream& stream, Goal& goal) 0374 { 0375 qCDebug(KSIRK_LOG) << "Goal operator>>"; 0376 quint32 type; 0377 QString description; 0378 QString playerName; 0379 quint32 nb, nbp; 0380 QString id; 0381 quint32 ownerId; 0382 stream >> type; 0383 qCDebug(KSIRK_LOG) << "Goal operator>> type: " << type ; 0384 stream >> ownerId; 0385 qCDebug(KSIRK_LOG) << "Goal operator>> ownerId: " << ownerId ; 0386 goal.player(static_cast<Player*>(goal.m_automaton->findPlayer(ownerId))); 0387 goal.type(Goal::GoalType(type)); 0388 stream >> description; 0389 qCDebug(KSIRK_LOG) << "Goal operator>> description: " << description ; 0390 goal.description(description); 0391 switch (type) 0392 { 0393 case Goal::GoalPlayer : 0394 goal.players().clear(); 0395 stream >> nbp; 0396 qCDebug(KSIRK_LOG) << "Goal operator>> nbp: " << nbp ; 0397 for (quint32 i = 0; i < nbp; i++) 0398 { 0399 stream >> playerName; 0400 qCDebug(KSIRK_LOG) << "Goal operator>> player name: " << playerName ; 0401 goal.players().push_back(playerName); 0402 } 0403 stream >> nb; 0404 qCDebug(KSIRK_LOG) << "Goal operator>> nbCountries: " << nb ; 0405 goal.nbCountries(nb); 0406 break; 0407 case Goal::Countries: 0408 stream >> nb; 0409 qCDebug(KSIRK_LOG) << "Goal operator>> nbCountries: " << nb ; 0410 goal.nbCountries(nb); 0411 stream >> nb; 0412 goal.nbArmiesByCountry(nb); 0413 qCDebug(KSIRK_LOG) << "Goal operator>> nbArmiesByCountry: " << nb ; 0414 break; 0415 case Goal::Continents: 0416 stream >> nb; 0417 qCDebug(KSIRK_LOG) << "Goal operator>> nbContinents: " << nb ; 0418 goal.continents().clear(); 0419 for (quint32 i = 0; i < nb; i++) 0420 { 0421 stream >> id; 0422 qCDebug(KSIRK_LOG) << "Goal operator>> continent: " << id ; 0423 goal.continents().push_back(id); 0424 } 0425 break; 0426 default:; 0427 } 0428 return stream; 0429 } 0430 0431 void Goal::saveXml(QTextStream& xmlStream) const 0432 { 0433 0434 xmlStream << "<goal player=\""; 0435 if (m_player != nullptr) 0436 { 0437 xmlStream << m_player->name(); 0438 } 0439 xmlStream << "\" type=\"" << m_type << "\" description=\"" << m_description; 0440 xmlStream << "\" nbCountries=\"" << m_nbCountries << "\" nbArmiesByCountry=\"" << m_nbArmiesByCountry << "\">"; 0441 xmlStream << "<continents>"; 0442 QList<QString>::ConstIterator itc, itc_end; 0443 itc = continents().constBegin(); itc_end = continents().constEnd(); 0444 for (; itc != itc_end; itc++) 0445 { 0446 QString name = ((*itc).isEmpty())?"":(*itc); 0447 xmlStream << "<continent name=\"" << name << "\"/>"; 0448 } 0449 xmlStream << "</continents>"; 0450 xmlStream << "<players>"; 0451 QList<QString>::ConstIterator itp, itp_end; 0452 itp = m_players.constBegin(); itp_end = m_players.constEnd(); 0453 for (; itp != itp_end; itp++) 0454 { 0455 xmlStream << "<player name=\"" << (*itp) << "\"/>"; 0456 } 0457 xmlStream << "</players>"; 0458 xmlStream << "</goal>"; 0459 } 0460 0461 } 0462 0463 }