2
0

HighScore.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * HighScore.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "HighScore.h"
  12. #include "../CPlayerState.h"
  13. #include "../constants/StringConstants.h"
  14. #include "CGameState.h"
  15. #include "StartInfo.h"
  16. #include "../mapping/CMapHeader.h"
  17. #include "../mapObjects/CGHeroInstance.h"
  18. #include "../mapObjects/CGTownInstance.h"
  19. VCMI_LIB_NAMESPACE_BEGIN
  20. HighScoreParameter HighScore::prepareHighScores(const CGameState * gs, PlayerColor player, bool victory)
  21. {
  22. const auto * playerState = gs->getPlayerState(player);
  23. HighScoreParameter param;
  24. param.difficulty = gs->getStartInfo()->difficulty;
  25. param.day = gs->getDate();
  26. param.townAmount = gs->howManyTowns(player);
  27. param.usedCheat = gs->getPlayerState(player)->cheated;
  28. param.hasGrail = false;
  29. for(const CGHeroInstance * h : playerState->heroes)
  30. if(h->hasArt(ArtifactID::GRAIL))
  31. param.hasGrail = true;
  32. for(const CGTownInstance * t : playerState->towns)
  33. if(t->builtBuildings.count(BuildingID::GRAIL))
  34. param.hasGrail = true;
  35. param.allEnemiesDefeated = true;
  36. for (PlayerColor otherPlayer(0); otherPlayer < PlayerColor::PLAYER_LIMIT; ++otherPlayer)
  37. {
  38. auto ps = gs->getPlayerState(otherPlayer, false);
  39. if(ps && otherPlayer != player && !ps->checkVanquished())
  40. param.allEnemiesDefeated = false;
  41. }
  42. param.scenarioName = gs->getMapHeader()->name.toString();
  43. param.playerName = gs->getStartInfo()->playerInfos.find(player)->second.name;
  44. return param;
  45. }
  46. HighScoreCalculation::Result HighScoreCalculation::calculate()
  47. {
  48. Result firstResult;
  49. Result summary;
  50. const std::array<double, 5> difficultyMultipliers{0.8, 1.0, 1.3, 1.6, 2.0};
  51. for(const auto & param : parameters)
  52. {
  53. double tmp = 200 - (param.day + 10) / (param.townAmount + 5) + (param.allEnemiesDefeated ? 25 : 0) + (param.hasGrail ? 25 : 0);
  54. firstResult = Result{static_cast<int>(tmp), static_cast<int>(tmp * difficultyMultipliers.at(param.difficulty)), param.day, param.usedCheat};
  55. summary.basic += firstResult.basic * 5.0 / parameters.size();
  56. summary.total += firstResult.total * 5.0 / parameters.size();
  57. summary.sumDays += firstResult.sumDays;
  58. summary.cheater |= firstResult.cheater;
  59. }
  60. if(parameters.size() == 1)
  61. return firstResult;
  62. return summary;
  63. }
  64. struct HighScoreCreature
  65. {
  66. CreatureID creature;
  67. int min;
  68. int max;
  69. };
  70. static std::vector<HighScoreCreature> getHighscoreCreaturesList()
  71. {
  72. JsonNode configCreatures(JsonPath::builtin("CONFIG/highscoreCreatures.json"));
  73. std::vector<HighScoreCreature> ret;
  74. for(auto & json : configCreatures["creatures"].Vector())
  75. {
  76. HighScoreCreature entry;
  77. entry.creature = CreatureID::decode(json["creature"].String());
  78. entry.max = json["max"].isNull() ? std::numeric_limits<int>::max() : json["max"].Integer();
  79. entry.min = json["min"].isNull() ? std::numeric_limits<int>::min() : json["min"].Integer();
  80. ret.push_back(entry);
  81. }
  82. return ret;
  83. }
  84. CreatureID HighScoreCalculation::getCreatureForPoints(int points, bool campaign)
  85. {
  86. static const std::vector<HighScoreCreature> creatures = getHighscoreCreaturesList();
  87. int divide = campaign ? 5 : 1;
  88. for(auto & creature : creatures)
  89. if(points / divide <= creature.max && points / divide >= creature.min)
  90. return creature.creature;
  91. throw std::runtime_error("Unable to find creature for score " + std::to_string(points));
  92. }
  93. VCMI_LIB_NAMESPACE_END