diff --git a/players.c b/players.c --- a/players.c +++ b/players.c @@ -721,6 +721,108 @@ int32 CmdPlayerCtrl(int x, int y, uint32 return 0; } +static const StringID _endgame_performance_titles[16] = { + STR_0213_BUSINESSMAN, + STR_0213_BUSINESSMAN, + STR_0213_BUSINESSMAN, + STR_0213_BUSINESSMAN, + STR_0213_BUSINESSMAN, + STR_0214_ENTREPRENEUR, + STR_0214_ENTREPRENEUR, + STR_0215_INDUSTRIALIST, + STR_0215_INDUSTRIALIST, + STR_0216_CAPITALIST, + STR_0216_CAPITALIST, + STR_0217_MAGNATE, + STR_0217_MAGNATE, + STR_0218_MOGUL, + STR_0218_MOGUL, + STR_0219_TYCOON_OF_THE_CENTURY, +}; + +inline StringID EndGameGetPerformanceTitleFromValue(uint value) +{ + return _endgame_performance_titles[minu(value, 1000) >> 6]; +} + +/* Save the highscore for the player */ +int SaveHighScoreValue(const Player *p) +{ + HighScore *hs = _highscore_table[_opt.diff_level]; + uint i; + uint16 score = p->old_economy[0].performance_history; + + for (i = 0; i < lengthof(_highscore_table[0]); i++) { + /* You are in the TOP5. Move all values one down and save us there */ + if (hs[i].score <= score) { + byte buf[sizeof(hs[i].company)]; + + // move all elements one down starting from the replaced one + memmove(&hs[i + 1], &hs[i], sizeof(HighScore) * (lengthof(_highscore_table[0]) - i - 1)); + SetDParam(0, p->president_name_1); + SetDParam(1, p->president_name_2); + SetDParam(2, p->name_1); + SetDParam(3, p->name_1); + GetString(buf, STR_HIGHSCORE_NAME); // get manager/company name string + ttd_strlcpy(hs[i].company, buf, sizeof(buf)); + hs[i].score = score; + hs[i].title = EndGameGetPerformanceTitleFromValue(score); + return i; + } + } + + return -1; // too bad; we did not make it into the top5 +} + +/* Save HighScore table to file */ +void SaveToHighScore(void) +{ + FILE *fp = fopen(_highscore_file, "w"); + + if (fp != NULL) { + uint i; + HighScore *hs; + + for (i = 0; i < lengthof(_highscore_table); i++) { + for (hs = _highscore_table[i]; hs != endof(_highscore_table[i]); hs++) { + /* First character is a command character, so strlen will fail on that */ + byte length = min(sizeof(hs->company), (hs->company[0] == '\0') ? 0 : strlen(&hs->company[1]) + 1); + + fwrite(&length, sizeof(length), 1, fp); // write away string length + fwrite(hs->company, length, 1, fp); + fwrite(&hs->score, sizeof(hs->score), 1, fp); + fwrite(&hs->title, sizeof(hs->title), 1, fp); + } + } + fclose(fp); + } +} + +/* Initialize the highscore table to 0 and if any file exists, load in values */ +void LoadFromHighScore(void) +{ + FILE *fp = fopen(_highscore_file, "r"); + + memset(_highscore_table, 0, sizeof(_highscore_table)); + + if (fp != NULL) { + uint i; + HighScore *hs; + + for (i = 0; i < lengthof(_highscore_table); i++) { + for (hs = _highscore_table[i]; hs != endof(_highscore_table[i]); hs++) { + byte length; + fread(&length, sizeof(length), 1, fp); + + fread(hs->company, 1, length, fp); + fread(&hs->score, sizeof(hs->score), 1, fp); + fread(&hs->title, sizeof(hs->title), 1, fp); + } + } + fclose(fp); + } +} + // Save/load of players static const byte _player_desc[] = { SLE_VAR(Player,name_2, SLE_UINT32),