1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Merge pull request #4332 from Laserlicht/campaign_highscores

fix campaign highscores
This commit is contained in:
Ivan Savenko 2024-08-01 21:16:50 +03:00 committed by GitHub
commit 88eff2609b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 63 additions and 36 deletions

View File

@ -161,11 +161,6 @@ CServerHandler::CServerHandler()
registerTypesLobbyPacks(*applier);
}
void CServerHandler::setHighScoreCalc(const std::shared_ptr<HighScoreCalculation> &newHighScoreCalc)
{
campaignScoreCalculator = newHighScoreCalc;
}
void CServerHandler::threadRunNetwork()
{
logGlobal->info("Starting network thread");
@ -655,7 +650,7 @@ void CServerHandler::startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameSta
break;
case EStartMode::CAMPAIGN:
if(si->campState->conqueredScenarios().empty())
campaignScoreCalculator.reset();
si->campState->highscoreParameters.clear();
client->newGame(gameState);
break;
case EStartMode::LOAD_GAME:
@ -686,12 +681,12 @@ HighScoreParameter CServerHandler::prepareHighScores(PlayerColor player, bool vi
for(const CGTownInstance * t : playerState->towns)
if(t->builtBuildings.count(BuildingID::GRAIL))
param.hasGrail = true;
param.allDefeated = true;
param.allEnemiesDefeated = true;
for (PlayerColor otherPlayer(0); otherPlayer < PlayerColor::PLAYER_LIMIT; ++otherPlayer)
{
auto ps = gs->getPlayerState(otherPlayer, false);
if(ps && otherPlayer != player && !ps->checkVanquished())
param.allDefeated = false;
param.allEnemiesDefeated = false;
}
param.scenarioName = gs->getMapHeader()->name.toString();
param.playerName = gs->getStartInfo()->playerInfos.find(player)->second.name;
@ -756,19 +751,16 @@ void CServerHandler::startCampaignScenario(HighScoreParameter param, std::shared
if (!cs)
ourCampaign = si->campState;
if(campaignScoreCalculator == nullptr)
{
campaignScoreCalculator = std::make_shared<HighScoreCalculation>();
campaignScoreCalculator->isCampaign = true;
campaignScoreCalculator->parameters.clear();
}
param.campaignName = cs->getNameTranslated();
campaignScoreCalculator->parameters.push_back(param);
cs->highscoreParameters.push_back(param);
auto campaignScoreCalculator = std::make_shared<HighScoreCalculation>();
campaignScoreCalculator->isCampaign = true;
campaignScoreCalculator->parameters = cs->highscoreParameters;
endGameplay();
auto & epilogue = ourCampaign->scenario(*ourCampaign->lastScenario()).epilog;
auto finisher = [this, ourCampaign]()
auto finisher = [ourCampaign, campaignScoreCalculator]()
{
if(ourCampaign->campaignSet != "" && ourCampaign->isCampaignFinished())
{

View File

@ -28,6 +28,8 @@ struct CPack;
struct CPackForLobby;
struct CPackForClient;
class HighScoreParameter;
template<typename T> class CApplier;
VCMI_LIB_NAMESPACE_END
@ -39,7 +41,6 @@ class GameChatHandler;
class IServerRunner;
class HighScoreCalculation;
class HighScoreParameter;
enum class ESelectionScreen : ui8;
enum class ELoadMode : ui8;
@ -105,7 +106,6 @@ class CServerHandler final : public IServerAPI, public LobbyInfo, public INetwor
std::unique_ptr<IServerRunner> serverRunner;
std::shared_ptr<CMapInfo> mapToStart;
std::vector<std::string> localPlayerNames;
std::shared_ptr<HighScoreCalculation> campaignScoreCalculator;
boost::thread threadNetwork;
@ -219,7 +219,6 @@ public:
void visitForLobby(CPackForLobby & lobbyPack);
void visitForClient(CPackForClient & clientPack);
void setHighScoreCalc(const std::shared_ptr<HighScoreCalculation> &newHighScoreCalc);
};
extern CServerHandler * CSH;

View File

@ -32,6 +32,7 @@
#include "../../lib/CConfigHandler.h"
#include "../../lib/CCreatureHandler.h"
#include "../../lib/constants/EntityIdentifiers.h"
#include "../../lib/gameState/HighScore.h"
auto HighScoreCalculation::calculate()
{
@ -48,7 +49,7 @@ auto HighScoreCalculation::calculate()
const std::array<double, 5> difficultyMultipliers{0.8, 1.0, 1.3, 1.6, 2.0};
for(auto & param : parameters)
{
double tmp = 200 - (param.day + 10) / (param.townAmount + 5) + (param.allDefeated ? 25 : 0) + (param.hasGrail ? 25 : 0);
double tmp = 200 - (param.day + 10) / (param.townAmount + 5) + (param.allEnemiesDefeated ? 25 : 0) + (param.hasGrail ? 25 : 0);
firstResult = Result{static_cast<int>(tmp), static_cast<int>(tmp * difficultyMultipliers.at(param.difficulty)), param.day, param.usedCheat};
summary.basic += firstResult.basic * 5.0 / parameters.size();
summary.total += firstResult.total * 5.0 / parameters.size();

View File

@ -9,6 +9,7 @@
*/
#pragma once
#include "../windows/CWindowObject.h"
#include "../../lib/gameState/HighScore.h"
class CButton;
class CLabel;
@ -20,24 +21,10 @@ class CFilledTexture;
class TransparentFilledRectangle;
class HighScoreParameter
{
public:
int difficulty;
int day;
int townAmount;
bool usedCheat;
bool hasGrail;
bool allDefeated;
std::string campaignName;
std::string scenarioName;
std::string playerName;
};
class HighScoreCalculation
{
public:
std::vector<HighScoreParameter> parameters = std::vector<HighScoreParameter>();
std::vector<HighScoreParameter> parameters;
bool isCampaign = false;
auto calculate();

View File

@ -463,6 +463,7 @@ set(lib_MAIN_HEADERS
gameState/CGameState.h
gameState/CGameStateCampaign.h
gameState/EVictoryLossCheckResult.h
gameState/HighScore.h
gameState/InfoAboutArmy.h
gameState/RumorState.h
gameState/SThievesGuildInfo.h

View File

@ -15,6 +15,7 @@
#include "../texts/TextLocalizationContainer.h"
#include "CampaignConstants.h"
#include "CampaignScenarioPrologEpilog.h"
#include "../gameState/HighScore.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -318,6 +319,8 @@ public:
std::string campaignSet;
std::vector<HighScoreParameter> highscoreParameters;
template <typename Handler> void serialize(Handler &h)
{
h & static_cast<Campaign&>(*this);
@ -330,6 +333,8 @@ public:
h & campaignSet;
if (h.version >= Handler::Version::CAMPAIGN_MAP_TRANSLATIONS)
h & mapTranslations;
if (h.version >= Handler::Version::HIGHSCORE_PARAMETERS)
h & highscoreParameters;
}
};

41
lib/gameState/HighScore.h Normal file
View File

@ -0,0 +1,41 @@
/*
* HighScore.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE HighScoreParameter
{
public:
int difficulty;
int day;
int townAmount;
bool usedCheat;
bool hasGrail;
bool allEnemiesDefeated;
std::string campaignName;
std::string scenarioName;
std::string playerName;
template <typename Handler> void serialize(Handler &h)
{
h & difficulty;
h & day;
h & townAmount;
h & usedCheat;
h & hasGrail;
h & allEnemiesDefeated;
h & campaignName;
h & scenarioName;
h & playerName;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -57,6 +57,7 @@ enum class ESerializationVersion : int32_t
SIMPLE_TEXT_CONTAINER_SERIALIZATION, // 847 - text container is serialized using common routine instead of custom approach
MAP_FORMAT_ADDITIONAL_INFOS, // 848 - serialize new infos in map format
REMOVE_LIB_RNG, // 849 - removed random number generators from library classes
HIGHSCORE_PARAMETERS, // 850 - saves parameter for campaign
CURRENT = REMOVE_LIB_RNG
CURRENT = HIGHSCORE_PARAMETERS
};