...
 
Commits (5)
......@@ -324,6 +324,7 @@
<CommandoRank_Veteran ENG="Veteran"/>
<Dated ENG="dated"/>
<Defeated ENG="defeated"/>
<Wins ENG="wins"/>
<Description ENG="Description"/>
<Destroyed ENG="destroyed"/>
<Detected ENG="detected"/>
......
......@@ -324,6 +324,7 @@
<CommandoRank_Veteran ENG="Veteran" localized="Veteran"/>
<Dated ENG="dated" localized="veraltet"/>
<Defeated ENG="defeated" localized="besiegt"/>
<Wins ENG="wins" localized="gewinnt"/>
<Description ENG="Description" localized="Beschreibung"/>
<Destroyed ENG="destroyed" localized="zerstört"/>
<Detected ENG="detected" localized="entdeckt"/>
......
......@@ -33,6 +33,8 @@
#include "game/logic/jobs/destroyjob.h"
#include "map/mapview.h"
#include "game/logic/casualtiestracker.h"
#include <set>
#include "player/playerbasicdata.h"
//------------------------------------------------------------------------------
cModel::cModel() :
......@@ -224,7 +226,7 @@ void cModel::setPlayerList(const std::vector<cPlayerBasicData>& splayers)
{
assert(playerList.size() == 0);
for (auto playerInfo : splayers)
for (const auto& playerInfo : splayers)
{
auto player = std::make_shared<cPlayer>(playerInfo, *unitsData);
if (map) player->initMaps(*map);
......@@ -793,7 +795,6 @@ void cModel::handleTurnEnd()
if (activeTurnPlayer == playerList.front().get())
{
//TODO: checkDefeats();
turnCounter->increaseTurn();
}
......@@ -802,6 +803,13 @@ void cModel::handleTurnEnd()
// don't execute turn start action in turn 1, because model is already completely initialized for turn 1
activeTurnPlayer->makeTurnStart(*this);
}
if (activeTurnPlayer == playerList.front().get())
{
// check game end conditions, after turn start, so generated points from this turn are also counted
// and only check when first player starts the turn. So all players have played the same amount of turns.
checkDefeats();
}
}
else
{
......@@ -812,6 +820,9 @@ void cModel::handleTurnEnd()
player->makeTurnStart(*this);
}
// check game end conditions, after turn start, so generated points from this turn are also counted
checkDefeats();
}
turnTimeClock->restartFromNow();
......@@ -952,3 +963,106 @@ void cModel::sideStepStealthUnit(const cPosition& position, const cStaticUnitDat
// sidestepping failed. Uncover the vehicle.
stealthVehicle->setDetectedByPlayer(vehicleOwner);
}
//------------------------------------------------------------------------------
bool cModel::isVictoryConditionMet() const
{
// if there is only one active player left, the game is over
// but only, if there have been other players.
int activePlayers = 0;
for (const auto& player : playerList)
{
if (player->isDefeated) continue;
activePlayers++;
}
if (activePlayers == 1 && playerList.size() > 1) return true;
switch (gameSettings->getVictoryCondition())
{
case eGameSettingsVictoryCondition::Turns:
{
return turnCounter->getTurn() > static_cast<int> (gameSettings->getVictoryTurns());
}
case eGameSettingsVictoryCondition::Points:
{
for (const auto& player : playerList)
{
if (player->isDefeated) continue;
if (player->getScore() >= static_cast<int> (gameSettings->getVictoryPoints())) return true;
}
return false;
}
case eGameSettingsVictoryCondition::Death:
// The victory condition for this mode is already checked.
return false;
}
return false;
}
//------------------------------------------------------------------------------
void cModel::defeatLoserPlayers()
{
for (size_t i = 0; i != playerList.size(); ++i)
{
cPlayer& player = *playerList[i];
if (player.isDefeated) continue;
if (player.mayHaveOffensiveUnit()) continue;
player.isDefeated = true;
playerHasLost(player);
}
}
//------------------------------------------------------------------------------
void cModel::checkDefeats()
{
defeatLoserPlayers();
if (!isVictoryConditionMet()) return;
std::set<cPlayer*> winners;
int best_score = -1;
// find player(s) with highest score
for (const auto& player : playerList)
{
if (player->isDefeated) continue;
const int score = player->getScore();
if (score < best_score) continue;
if (score > best_score)
{
winners.clear();
best_score = score;
}
winners.insert(player.get());
}
// Handle the case where there is more than one winner.
// Original MAX calls a draw and displays the results screen.
// For now we will have sudden death,
// i.e. first player to get ahead in score wins.
if (winners.size() > 1)
{
suddenDeathMode();
}
else
{
assert(winners.size() == 1);
for (const auto& player : playerList)
{
if (player->isDefeated) continue;
if (winners.find(player.get()) != winners.end())
{
playerHasWon(*player);
}
else
{
player->isDefeated = true;
playerHasLost(*player);
}
}
}
}
......@@ -142,6 +142,10 @@ public:
mutable cSignal<void(const cVehicle& plane)> planeLanding;
mutable cSignal<void(const cVehicle& plane)> planeTakeoff;
mutable cSignal<void(const cPlayer& player)> playerHasLost;
mutable cSignal<void(const cPlayer& player)> playerHasWon;
mutable cSignal<void()> suddenDeathMode;
template<typename T>
void save(T& archive)
......@@ -283,6 +287,10 @@ private:
void runAttackJobs();
void handleTurnEnd();
bool isVictoryConditionMet() const;
void defeatLoserPlayers();
void checkDefeats();
//------------------------------------------------------------------------------
unsigned int gameId; //this id can be used to check, which log files, and save file belong to the same game.
......@@ -316,9 +324,6 @@ private:
/** little helper jobs, that do some time dependent actions */
cJobContainer helperJobs;
//casualtiesTracker
};
#endif
......@@ -38,11 +38,12 @@ using namespace std;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
cPlayer::cPlayer (const cPlayerBasicData& splayer_, const cUnitsData& unitsData) :
splayer (splayer_),
cPlayer::cPlayer (const cPlayerBasicData& splayer, const cUnitsData& unitsData) :
color(splayer.getColor()),
id(splayer.getNr()),
name(splayer.getName()),
clan (-1),
hasFinishedTurn (false),
isRemovedFromGame (false),
base(*this)
{
// get the default (no clan) unit data
......@@ -54,9 +55,6 @@ cPlayer::cPlayer (const cPlayerBasicData& splayer_, const cUnitsData& unitsData)
credits = 0;
isDefeated = false;
splayer.nameChanged.connect ([this]() { nameChanged(); });
splayer.colorChanged.connect ([this]() { colorChanged(); });
}
//------------------------------------------------------------------------------
......@@ -451,6 +449,8 @@ bool cPlayer::canSeeUnit(const cUnit& unit, const cMap& map) const
//------------------------------------------------------------------------------
bool cPlayer::canSeeUnit(const cUnit& unit, const cMapField& field, const sTerrain& terrain) const
{
if (isDefeated) return true;
if (unit.isAVehicle() && static_cast<const cVehicle*>(&unit)->isUnitLoaded()) return false;
if (unit.getOwner() == this) return true;
......@@ -741,7 +741,7 @@ void cPlayer::makeTurnStart(cModel& model)
vehicle->proceedClearing(model);
}
//just to prevent, that an error in scanmap updates have an permanent impact
//just to prevent, that an error in scanmap updates have a permanent impact
refreshScanMaps();
refreshSentryMaps();
......@@ -767,7 +767,9 @@ void cPlayer::makeTurnStart(cModel& model)
//------------------------------------------------------------------------------
uint32_t cPlayer::getChecksum(uint32_t crc) const
{
crc = calcCheckSum(splayer, crc);
crc = calcCheckSum(name, crc);
crc = calcCheckSum(id, crc);
crc = calcCheckSum(color, crc);
crc = calcCheckSum(dynamicUnitsData, crc);
crc = calcCheckSum(base, crc);
for (const auto& v : vehicles)
......@@ -789,7 +791,6 @@ uint32_t cPlayer::getChecksum(uint32_t crc) const
crc = calcCheckSum(credits, crc);
crc = calcCheckSum(currentTurnResearchAreasFinished, crc);
crc = calcCheckSum(hasFinishedTurn, crc);
crc = calcCheckSum(isRemovedFromGame, crc);
crc = calcCheckSum(researchState, crc);
for (int i = 0; i < cResearch::kNrResearchAreas; i++)
crc = calcCheckSum(researchCentersWorkingOnArea[i], crc);
......@@ -888,6 +889,8 @@ int cPlayer::getResearchCentersWorkingOnArea (cResearch::ResearchArea area) cons
//------------------------------------------------------------------------------
bool cPlayer::canSeeAt (const cPosition& position) const
{
if (isDefeated) return true;
return scanMap.get(position);
}
......@@ -903,16 +906,3 @@ void cPlayer::setHasFinishedTurn (bool value)
std::swap (hasFinishedTurn, value);
if (hasFinishedTurn != value) hasFinishedTurnChanged();
}
//------------------------------------------------------------------------------
bool cPlayer::getIsRemovedFromGame() const
{
return isRemovedFromGame;
}
//------------------------------------------------------------------------------
void cPlayer::setIsRemovedFromGame (bool value)
{
std::swap (isRemovedFromGame, value);
if (isRemovedFromGame != value) isRemovedFromGameChanged();
}
......@@ -35,16 +35,17 @@
#include "utility/position.h"
#include "utility/signal/signal.h"
#include "utility/flatset.h"
#include "game/data/player/playerbasicdata.h"
#include "utility/serialization/serialization.h"
#include "utility/arraycrc.h"
#include "game/data/rangemap.h"
#include "playercolor.h"
class cHud;
class cMapField;
class cUnit;
class cPosition;
struct sTerrain;
class cPlayerBasicData;
/**
* Structure for generating the report about finished units at turn start
......@@ -71,17 +72,15 @@ class cPlayer
{
cPlayer (const cPlayer&) MAXR_DELETE_FUNCTION;
public:
explicit cPlayer(const cPlayerBasicData& splayer_, const cUnitsData& unitsData);
explicit cPlayer(const cPlayerBasicData& splayer, const cUnitsData& unitsData);
~cPlayer();
const std::string& getName() const { return splayer.getName(); }
void setName (const std::string& name) { splayer.setName (name); }
const std::string& getName() const { return name; }
bool isHuman() const { return true; } // only human players are implemented yet.
const cPlayerColor& getColor() const { return splayer.getColor(); }
void setColor (cPlayerColor color) { return splayer.setColor (std::move (color)); }
int getId() const { return splayer.getNr(); }
const cPlayerColor& getColor() const { return color; }
int getId() const { return id; }
int getCredits() const;
void setCredits (int credits);
......@@ -168,9 +167,6 @@ public:
bool getHasFinishedTurn() const;
void setHasFinishedTurn (bool value);
bool getIsRemovedFromGame() const;
void setIsRemovedFromGame (bool value);
void exploreResource (const cPosition& pos) { resourceMap.set(getOffset (pos), 1); }
bool hasResourceExplored (const cPosition& pos) const { return resourceMap[getOffset (pos)] != 0; }
bool hasSentriesAir (const cPosition& pos) const { return sentriesMapAir.get(pos); }
......@@ -210,11 +206,8 @@ public:
uint32_t getChecksum(uint32_t crc) const;
mutable cSignal<void ()> nameChanged;
mutable cSignal<void ()> colorChanged;
mutable cSignal<void ()> creditsChanged;
mutable cSignal<void ()> hasFinishedTurnChanged;
mutable cSignal<void ()> isRemovedFromGameChanged;
mutable cSignal<void (cResearch::ResearchArea)> researchCentersWorkingOnAreaChanged;
mutable cSignal<void ()> researchCentersWorkingTotalChanged;
mutable cSignal<void ()> turnEndMovementsStarted;
......@@ -230,7 +223,9 @@ public:
template <typename T>
void save(T& archive)
{
archive & NVP(splayer);
archive & NVP(name);
archive & NVP(id);
archive & NVP(color);
archive & NVP(dynamicUnitsData);
archive & serialization::makeNvp("vehicleNum", (int)vehicles.size());
for (auto vehicle : vehicles)
......@@ -252,13 +247,14 @@ public:
archive & NVP(credits);
archive & NVP(currentTurnResearchAreasFinished);
archive & NVP(hasFinishedTurn);
archive & NVP(isRemovedFromGame);
archive & NVP(researchState);
}
template<typename T>
void load(T& archive)
{
archive & NVP(splayer);
archive & NVP(name);
archive & NVP(id);
archive & NVP(color);
dynamicUnitsData.clear();
archive & NVP(dynamicUnitsData);
......@@ -301,7 +297,6 @@ public:
archive & NVP(credits);
archive & NVP(currentTurnResearchAreasFinished);
archive & NVP(hasFinishedTurn);
archive & NVP(isRemovedFromGame);
archive & NVP(researchState);
hasFinishedTurnChanged(); //FIXME: deserialization does not trigger signals on changed data members. But this signal is needed for the gui after loading a save game...
......@@ -322,7 +317,9 @@ private:
void refreshScanMaps();
cPlayerBasicData splayer;
std::string name;
cPlayerColor color;
int id;
cFlatSet<std::shared_ptr<cVehicle>, sUnitLess<cVehicle>> vehicles;
cFlatSet<std::shared_ptr<cBuilding>, sUnitLess<cBuilding>> buildings;
......@@ -343,11 +340,10 @@ private:
int clan;
int credits;
std::vector<sTurnstartReport> currentTurnUnitReports; //TODO: remove. Shouldn't be part of the game model
std::vector<sTurnstartReport> currentTurnUnitReports; //TODO: move somewhere else. Shouldn't be part of the game model
std::vector<int> currentTurnResearchAreasFinished;
bool hasFinishedTurn;
bool isRemovedFromGame;
cResearch researchState; ///< stores the current research level of the player
int researchCentersWorkingOnArea[cResearch::kNrResearchAreas]; ///< counts the number of research centers that are currently working on each area
......
......@@ -23,24 +23,27 @@
//------------------------------------------------------------------------------
cPlayerBasicData::cPlayerBasicData() :
Nr(0),
ready(false)
nr(0),
ready(false),
defeated(false)
{}
//------------------------------------------------------------------------------
cPlayerBasicData::cPlayerBasicData (const std::string& name_, cPlayerColor color_, int nr_) :
name (name_),
color (std::move (color_)),
Nr (nr_),
ready (false)
cPlayerBasicData::cPlayerBasicData (const std::string& name, cPlayerColor color, int nr, bool defeated) :
name (name),
color (std::move (color)),
nr (nr),
ready (false),
defeated(defeated)
{}
//------------------------------------------------------------------------------
cPlayerBasicData::cPlayerBasicData (const cPlayerBasicData& other) :
name (other.name),
color (other.color),
Nr (other.Nr),
ready (other.ready)
nr (other.nr),
ready (other.ready),
defeated(other.defeated)
{}
//------------------------------------------------------------------------------
......@@ -48,8 +51,9 @@ cPlayerBasicData& cPlayerBasicData::operator= (const cPlayerBasicData& other)
{
name = other.name;
color = other.color;
Nr = other.Nr;
nr = other.nr;
ready = other.ready;
defeated = other.defeated;
return *this;
}
......@@ -69,14 +73,14 @@ void cPlayerBasicData::setName (std::string name_)
//------------------------------------------------------------------------------
int cPlayerBasicData::getNr() const
{
return Nr;
return nr;
}
//------------------------------------------------------------------------------
void cPlayerBasicData::setNr (int nr)
void cPlayerBasicData::setNr (int newNr)
{
std::swap (Nr, nr);
if (Nr != nr) numberChanged();
std::swap (newNr, nr);
if (newNr != nr) numberChanged();
}
//------------------------------------------------------------------------------
void cPlayerBasicData::setColor (cPlayerColor color_)
......@@ -99,12 +103,14 @@ bool cPlayerBasicData::isReady() const
}
//------------------------------------------------------------------------------
uint32_t cPlayerBasicData::getChecksum(uint32_t crc) const
void cPlayerBasicData::setDefeated(bool defeated_)
{
crc = calcCheckSum(name, crc);
crc = calcCheckSum(color, crc);
crc = calcCheckSum(Nr, crc);
crc = calcCheckSum(ready, crc);
std::swap(defeated_, defeated);
if (defeated != defeated_) isDefeatedChanged();
}
return crc;
//------------------------------------------------------------------------------
bool cPlayerBasicData::isDefeated() const
{
return defeated;
}
......@@ -32,7 +32,7 @@ class cPlayerBasicData
{
public:
cPlayerBasicData();
cPlayerBasicData (const std::string& name_, cPlayerColor color, int Nr_);
cPlayerBasicData (const std::string& name, cPlayerColor color, int nr, bool defeated);
cPlayerBasicData (const cPlayerBasicData& other);
cPlayerBasicData& operator= (const cPlayerBasicData& other);
......@@ -44,27 +44,30 @@ public:
void setNr (int index);
void setReady (bool ready);
bool isReady() const;
uint32_t getChecksum(uint32_t crc) const;
void setDefeated(bool defeated);
bool isDefeated() const;
mutable cSignal<void ()> nameChanged;
mutable cSignal<void ()> numberChanged;
mutable cSignal<void ()> colorChanged;
mutable cSignal<void ()> readyChanged;
mutable cSignal<void ()> isDefeatedChanged;
template <typename T>
void serialize(T& archive)
{
archive & NVP(name);
archive & NVP(color);
archive & NVP(Nr);
archive & NVP(nr);
archive & NVP(ready);
archive & NVP(defeated);
}
private:
std::string name;
cPlayerColor color;
int Nr;
int nr;
bool ready;
bool defeated;
};
#endif // game_data_player_playerbasicdataH
......@@ -36,6 +36,7 @@
#include "game/data/report/special/savedreportlostconnection.h"
#include "game/data/report/special/savedreportplayerendedturn.h"
#include "game/data/report/special/savedreportplayerdefeated.h"
#include "game/data/report/special/savedreportplayerwins.h"
#include "game/data/report/special/savedreportplayerleft.h"
#include "game/data/report/special/savedreportupgraded.h"
#include "game/data/report/special/savedreportturnstart.h"
......@@ -78,6 +79,8 @@ std::unique_ptr<cSavedReport> cSavedReport::createFromImpl (T& archive)
return std::make_unique<cSavedReportLostConnection>(archive);
case eSavedReportType::PlayerDefeated:
return std::make_unique<cSavedReportPlayerDefeated>(archive);
case eSavedReportType::PlayerWins:
return std::make_unique<cSavedReportPlayerWins>(archive);
case eSavedReportType::PlayerLeft:
return std::make_unique<cSavedReportPlayerLeft>(archive);
case eSavedReportType::Upgraded:
......@@ -103,7 +106,7 @@ std::unique_ptr<cSavedReport> cSavedReport::createFromImpl (T& archive)
case eSavedReportType::TurnAutoMove:
return std::make_unique<cSavedReportSimple>(type);
default:
//TODO: throw
assert(false);
return nullptr;
}
}
......
......@@ -71,6 +71,8 @@ enum class eSavedReportType
PlayerLeft = 21,
Upgraded = 22,
TurnStart = 23,
PlayerWins = 35,
SuddenDeath = 36,
// Unit reports
Attacked = 24,
......
......@@ -80,6 +80,9 @@ std::string cSavedReportSimple::getMessage(const cUnitsData& unitsData) const
return lngPack.i18n ("Text~Comp~Turn_Wait");
case eSavedReportType::TurnAutoMove:
return lngPack.i18n ("Text~Comp~Turn_Automove");
case eSavedReportType::SuddenDeath:
return lngPack.i18n("Text~Comp~SuddenDeath");
default: break;
}
return "";
......
/***************************************************************************
* Mechanized Assault and Exploration Reloaded Projectfile *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "game/data/report/special/savedreportplayerwins.h"
#include "netmessage.h"
#include "game/data/player/player.h"
//------------------------------------------------------------------------------
cSavedReportPlayerWins::cSavedReportPlayerWins (const cPlayer& player) :
playerName (player.getName())
{}
//------------------------------------------------------------------------------
eSavedReportType cSavedReportPlayerWins::getType() const
{
return eSavedReportType::PlayerWins;
}
//------------------------------------------------------------------------------
std::string cSavedReportPlayerWins::getMessage(const cUnitsData& unitsData) const
{
return lngPack.i18n ("Text~Multiplayer~Player") + " " + playerName + " " + lngPack.i18n ("Text~Comp~Wins");
}
//------------------------------------------------------------------------------
bool cSavedReportPlayerWins::isAlert() const
{
return false;
}
/***************************************************************************
* Mechanized Assault and Exploration Reloaded Projectfile *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef game_data_reports_special_savedreportplayerwinsH
#define game_data_reports_special_savedreportplayerwinsH
#include "maxrconfig.h"
#include "game/data/report/savedreport.h"
class cPlayer;
class cSavedReportPlayerWins : public cSavedReport
{
public:
cSavedReportPlayerWins (const cPlayer& player);
template <typename T, ENABLE_ARCHIVE_OUT>
explicit cSavedReportPlayerWins(T& archive)
{
serializeThis(archive);
}
virtual void serialize(cBinaryArchiveIn& archive) { cSavedReport::serialize(archive); serializeThis(archive); }
virtual void serialize(cXmlArchiveIn& archive) { cSavedReport::serialize(archive); serializeThis(archive); }
virtual void serialize(cTextArchiveIn& archive) { cSavedReport::serialize(archive); serializeThis(archive); }
virtual eSavedReportType getType() const MAXR_OVERRIDE_FUNCTION;
virtual std::string getMessage(const cUnitsData& unitsData) const MAXR_OVERRIDE_FUNCTION;
virtual bool isAlert() const MAXR_OVERRIDE_FUNCTION;
private:
template <typename T>
void serializeThis(T& archive)
{
archive & NVP(playerName);
}
std::string playerName;
};
#endif // game_data_reports_special_savedreportplayerwinsH
......@@ -166,7 +166,18 @@ cSaveGameInfo cSavegame::loadSaveInfo(int slot)
for (int i = 0; i < numPlayers; i++)
{
archive.enterChild("player");
archive >> serialization::makeNvp("splayer", info.players[i]);
std::string name;
cPlayerColor color;
int id;
bool isDefeated;
archive >> NVP(name);
archive >> NVP(color);
archive >> NVP(id);
archive >> NVP(isDefeated);
info.players[i] = cPlayerBasicData(name, color, id, isDefeated);
archive.leaveChild(); // player
}
archive.enterChild("map");
......
......@@ -725,14 +725,6 @@ cSubBase* cClient::getSubBaseFromID (int iID)
return nullptr;
}
//------------------------------------------------------------------------------
void cClient::deletePlayer (cPlayer& player)
{
player.setIsRemovedFromGame (true);
auto playerList = model.getPlayerList();
playerList.erase (std::remove_if (playerList.begin(), playerList.end(), [&player] (const std::shared_ptr<cPlayer>& entry) { return entry.get() == &player; }), playerList.end());
}
//------------------------------------------------------------------------------
void cClient::enableFreezeMode(eFreezeMode mode)
{
......
......@@ -123,9 +123,6 @@ public:
void addFx (std::shared_ptr<cFx> fx, bool playSound = true);
void deletePlayer (cPlayer& player);
const std::shared_ptr<cGameTimerClient>& getGameTimer() const { return gameTimer; }
void loadModel(int saveGameNumber, int playerNr);
......
......@@ -128,7 +128,7 @@ void cLocalSingleplayerGameNew::setLandingPosition (const cPosition& landingPosi
//------------------------------------------------------------------------------
cPlayerBasicData cLocalSingleplayerGameNew::createPlayer()
{
cPlayerBasicData player (cSettings::getInstance().getPlayerName(), cPlayerColor(), 0);
cPlayerBasicData player (cSettings::getInstance().getPlayerName(), cPlayerColor(), 0, false);
return player;
}
......@@ -151,7 +151,7 @@ cNetMessageGameAlreadyRunning::cNetMessageGameAlreadyRunning(const cModel& model
cNetMessage2(eNetMessageType::GAME_ALREADY_RUNNING)
{
for (const auto& p : model.getPlayerList())
playerList.push_back(cPlayerBasicData(p->getName(), p->getColor(), p->getId()));
playerList.push_back(cPlayerBasicData(p->getName(), p->getColor(), p->getId(), p->isDefeated));
mapName = model.getMap()->getName();
mapCrc = MapDownload::calculateCheckSum(mapName);
}
......@@ -127,6 +127,8 @@
#include "game/logic/action/actionupgradevehicle.h"
#include "game/logic/action/actionupgradebuilding.h"
#include "game/data/report/unit/savedreportsurveyoraiconfused.h"
#include "game/data/report/special/savedreportplayerdefeated.h"
#include "game/data/report/special/savedreportplayerwins.h"
//------------------------------------------------------------------------------
cGameGuiController::cGameGuiController (cApplication& application_, std::shared_ptr<const cStaticMap> staticMap) :
......@@ -1536,6 +1538,18 @@ void cGameGuiController::connectReportSources(cClient& client)
{
addSavedReport(std::make_unique<cSavedReportSimple>(eSavedReportType::EnergyIsNeeded), player.getId());
});
allClientsSignalConnectionManager.connect(model.playerHasLost, [&](const cPlayer& looser)
{
addSavedReport(std::make_unique<cSavedReportPlayerDefeated>(looser), player.getId());
});
allClientsSignalConnectionManager.connect(model.playerHasWon, [&](const cPlayer& winner)
{
addSavedReport(std::make_unique<cSavedReportPlayerWins>(winner), player.getId());
});
allClientsSignalConnectionManager.connect(model.suddenDeathMode, [&]()
{
addSavedReport(std::make_unique<cSavedReportSimple>(eSavedReportType::SuddenDeath), player.getId());
});
}
//------------------------------------------------------------------------------
......
......@@ -39,10 +39,7 @@ cChatBoxPlayerListViewItem::cChatBoxPlayerListViewItem (const cPlayer& player_)
fitToChildren();
signalConnectionManager.connect (player->nameChanged, std::bind (&cChatBoxPlayerListViewItem::updatePlayerName, this));
signalConnectionManager.connect (player->colorChanged, std::bind (&cChatBoxPlayerListViewItem::updatePlayerColor, this));
signalConnectionManager.connect (player->hasFinishedTurnChanged, std::bind (&cChatBoxPlayerListViewItem::updatePlayerFinishedTurn, this));
signalConnectionManager.connect (player->isRemovedFromGameChanged, std::bind (&cChatBoxPlayerListViewItem::updatePlayerName, this));
}
//------------------------------------------------------------------------------
......@@ -60,9 +57,8 @@ int cChatBoxPlayerListViewItem::getPlayerNumber() const
//------------------------------------------------------------------------------
void cChatBoxPlayerListViewItem::updatePlayerName()
{
// TODO: find better way to show removed/lost/may be waiting/... players
// TODO: else at least: translate
nameLabel->setText (player->getIsRemovedFromGame() ? player->getName() + " (out)" : player->getName());
// TODO: show player status (removed/lost/may be waiting/...)?
nameLabel->setText (player->getName());
}
//------------------------------------------------------------------------------
......
......@@ -324,7 +324,7 @@ void cMenuControllerMultiplayerHost::checkGameStart()
for (size_t i = 0; i < savegamePlayers.size(); ++i)
{
auto iter = std::find_if (menuPlayers.begin(), menuPlayers.end(), [&] (const std::shared_ptr<cPlayerBasicData>& player) { return player->getName() == savegamePlayers[i].getName(); });
if (iter == menuPlayers.end())
if (iter == menuPlayers.end() && !savegamePlayers[i].isDefeated())
{
windowNetworkLobby->addInfoEntry (lngPack.i18n ("Text~Multiplayer~Player_Wrong"));
return;
......@@ -731,7 +731,7 @@ void cMenuControllerMultiplayerHost::handleNetMessage_TCP_WANT_CONNECT(cNetMessa
if (!connectionManager || !windowNetworkLobby) return;
//add player
auto newPlayer = std::make_shared<cPlayerBasicData>(message.playerName, cPlayerColor(message.playerColor), nextPlayerNumber++);
auto newPlayer = std::make_shared<cPlayerBasicData>(message.playerName, cPlayerColor(message.playerColor), nextPlayerNumber++, false);
windowNetworkLobby->addPlayer(newPlayer);
windowNetworkLobby->addInfoEntry(lngPack.i18n("Text~Multiplayer~Player_Joined", newPlayer->getName()));
......
......@@ -138,7 +138,7 @@ void cMenuControllerMultiplayerHotSeat::selectPlayers()
{
if (playerTypes[i] == ePlayerType::Human)
{
cPlayerBasicData player (lngPack.i18n (playerNames[i]), cPlayerColor (cPlayerColor::predefinedColors[i]), playerNum++);
cPlayerBasicData player (lngPack.i18n (playerNames[i]), cPlayerColor (cPlayerColor::predefinedColors[i]), playerNum++, false);
players.push_back (player);
}
}
......
......@@ -20,7 +20,7 @@
#include "ui/graphical/menu/widgets/special/lobbyplayerlistviewitem.h"
#include "ui/graphical/menu/widgets/label.h"
#include "ui/graphical/menu/widgets/image.h"
#include "game/data/player/player.h"
#include "game/data/player/playerbasicdata.h"
//------------------------------------------------------------------------------
cLobbyPlayerListViewItem::cLobbyPlayerListViewItem (std::shared_ptr<cPlayerBasicData> player_) :
......
......@@ -29,11 +29,12 @@
#include "ui/graphical/menu/widgets/listview.h"
#include "ui/graphical/menu/widgets/special/unitlistviewitembuy.h"
#include "ui/graphical/menu/widgets/special/unitdetails.h"
#include "game/data/player/playerbasicdata.h"
//------------------------------------------------------------------------------
cWindowHangar::cWindowHangar (AutoSurface surface, std::shared_ptr<const cUnitsData> unitsData, cPlayerColor playerColor, int playerClan) :
cWindow (std::move (surface)),
temporaryPlayer (new cPlayer (cPlayerBasicData ("unnamed", std::move (playerColor), 0), *unitsData)),
temporaryPlayer (new cPlayer (cPlayerBasicData ("unnamed", std::move (playerColor), 0, false), *unitsData)),
player (*temporaryPlayer),
unitsData (unitsData)
{
......
......@@ -40,7 +40,7 @@
cWindowNetworkLobby::cWindowNetworkLobby (const std::string title, bool disableIp) :
cWindow (LoadPCX (GFXOD_MULT)),
saveGameInfo(-1),
localPlayer (std::make_shared<cPlayerBasicData> (cSettings::getInstance().getPlayerName(), cPlayerColor (cSettings::getInstance().getPlayerColor()), 1))
localPlayer (std::make_shared<cPlayerBasicData> (cSettings::getInstance().getPlayerName(), cPlayerColor (cSettings::getInstance().getPlayerColor()), 1, false))
{
addChild (std::make_unique<cLabel> (cBox<cPosition> (getPosition() + cPosition (0, 11), getPosition() + cPosition (getArea().getMaxCorner().x(), 11 + 10)), title, FONT_LATIN_NORMAL, eAlignmentType::CenterHorizontal));
......