1 /*------------------------------------------------------------------------------- 2 3 BARONY 4 File: scores.hpp 5 Desc: header file for scores.cpp 6 7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved. 8 See LICENSE for details. 9 10 -------------------------------------------------------------------------------*/ 11 12 #pragma once 13 #include "monster.hpp" 14 15 #define SCORESFILE "scores.dat" 16 #define SCORESFILE_MULTIPLAYER "scores_multiplayer.dat" 17 18 // game score structure 19 #define MAXTOPSCORES 30 20 #define NUM_CONDUCT_CHALLENGES 32 21 #define NUM_GAMEPLAY_STATISTICS 64 22 23 // indexes for new game conducts 24 static const int CONDUCT_HARDCORE = 0; // 2 state, 1 = hardcore, 0 = not. 25 static const int CONDUCT_CHEATS_ENABLED = 1; // 2 state, 1 = cheats enabled, 0 = not. 26 static const int CONDUCT_MULTIPLAYER = 2; // 2 state, 1 = multiplayer, 0 = not. 27 static const int CONDUCT_CLASSIC_MODE = 3; // 2 state, 1 = classic maps, 0 = not. 28 static const int CONDUCT_MODDED = 4; // 2 state, 1 = modded, 0 = not. 29 static const int CONDUCT_BRAWLER = 5; // 2 state, 1 = brawler, no weapons used, 0 = not brawler, weapons used. 30 static const int CONDUCT_BLESSED_BOOTS_SPEED = 6; // 2 state, 1 = reached Sanctum in < 45 mins, 0 = not. 31 static const int CONDUCT_BOOTS_SPEED = 7; // 2 state, 1 = beat Herx/Baphy in < 20 mins, 0 = not. 32 static const int CONDUCT_KEEPINVENTORY = 8; // 1 = keep inventory server flag, 0 = not. 33 static const int CONDUCT_LIFESAVING = 9; // 1 = lifesaving server flag, 0 = not. 34 static const int CONDUCT_ACCURSED = 10; // 1 = cursed, 0 = not 35 static const int CONDUCT_RANGED_ONLY = 11; // 1 = ranged only, 0 = not. 36 37 static const int STATISTICS_BOMB_SQUAD = 0; 38 static const int STATISTICS_SITTING_DUCK = 1; 39 static const int STATISTICS_YES_WE_CAN = 2; 40 static const int STATISTICS_FIRE_MAYBE_DIFFERENT = 3; 41 static const int STATISTICS_HOT_TUB_TIME_MACHINE = 4; 42 static const int STATISTICS_HEAL_BOT = 5; 43 static const int STATISTICS_TEMPT_FATE = 6; 44 static const int STATISTICS_ALCHEMY_RECIPES = 7; 45 static const int STATISTICS_FUNCTIONAL = 8; 46 static const int STATISTICS_OHAI_MARK = 9; 47 static const int STATISTICS_ITS_A_LIVING = 10; 48 static const int STATISTICS_FORUM_TROLL = 11; 49 static const int STATISTICS_PIMPING_AINT_EASY = 12; 50 static const int STATISTICS_TRIBE_SUBSCRIBE = 13; 51 static const int STATISTICS_POP_QUIZ_1 = 14; 52 static const int STATISTICS_POP_QUIZ_2 = 15; 53 static const int STATISTICS_DISABLE_UPLOAD = 31; 54 55 enum SteamStatIndexes : int 56 { 57 STEAM_STAT_BOULDER_DEATHS, 58 STEAM_STAT_RHINESTONE_COWBOY, 59 STEAM_STAT_TOUGH_AS_NAILS, 60 STEAM_STAT_UNSTOPPABLE_FORCE, 61 STEAM_STAT_GAMES_STARTED, 62 STEAM_STAT_GAMES_WON, 63 STEAM_STAT_BOMBARDIER, 64 STEAM_STAT_IN_THE_MIX, 65 STEAM_STAT_FREE_REFILLS, 66 STEAM_STAT_TAKE_THIS_OUTSIDE, 67 STEAM_STAT_ALTER_EGO, 68 STEAM_STAT_BLOOD_SPORT, 69 STEAM_STAT_BAD_BLOOD, 70 STEAM_STAT_IRON_GUT, 71 STEAM_STAT_BOTTLE_NOSED, 72 STEAM_STAT_BARFIGHT_CHAMP, 73 STEAM_STAT_VOLATILE, 74 STEAM_STAT_SURROGATES, 75 STEAM_STAT_KILL_COMMAND, 76 STEAM_STAT_TRASH_COMPACTOR, 77 STEAM_STAT_SPICY, 78 STEAM_STAT_SERIAL_THRILLA, 79 STEAM_STAT_TRADITION, 80 STEAM_STAT_POP_QUIZ, 81 STEAM_STAT_DYSLEXIA, 82 STEAM_STAT_BOOKWORM, 83 STEAM_STAT_MONARCH, 84 STEAM_STAT_SUPER_SHREDDER, 85 STEAM_STAT_FIXER_UPPER, 86 STEAM_STAT_TORCHERER, 87 STEAM_STAT_MANY_PEDI_PALP, 88 STEAM_STAT_5000_SECOND_RULE, 89 STEAM_STAT_SOCIAL_BUTTERFLY, 90 STEAM_STAT_ROLL_THE_BONES, 91 STEAM_STAT_COWBOY_FROM_HELL, 92 STEAM_STAT_SELF_FLAGELLATION, 93 STEAM_STAT_CHOPPING_BLOCK, 94 STEAM_STAT_IF_YOU_LOVE_SOMETHING, 95 STEAM_STAT_RAGE_AGAINST, 96 STEAM_STAT_GUERILLA_RADIO, 97 STEAM_STAT_FASCIST, 98 STEAM_STAT_ITS_A_LIVING, 99 STEAM_STAT_OVERCLOCKED, 100 STEAM_STAT_BACK_TO_BASICS, 101 STEAM_STAT_EXTRA_CREDIT, 102 STEAM_STAT_EXTRA_CREDIT_LVLS, 103 STEAM_STAT_DIPLOMA, 104 STEAM_STAT_DIPLOMA_LVLS, 105 STEAM_STAT_TUTORIAL_ENTERED 106 }; 107 108 enum SteamGlobalStatIndexes : int 109 { 110 STEAM_GSTAT_INVALID = -1, 111 STEAM_GSTAT_GAMES_STARTED = 0, 112 STEAM_GSTAT_GAMES_WON, 113 STEAM_GSTAT_BOULDER_DEATHS, 114 STEAM_GSTAT_HERX_SLAIN, 115 STEAM_GSTAT_BAPHOMET_SLAIN, 116 STEAM_GSTAT_TWINSFIRE_SLAIN, 117 STEAM_GSTAT_DEATHS_HUMAN, 118 STEAM_GSTAT_DEATHS_RAT, 119 STEAM_GSTAT_DEATHS_GOBLIN, 120 STEAM_GSTAT_DEATHS_SLIME, 121 STEAM_GSTAT_DEATHS_TROLL, 122 STEAM_GSTAT_DEATHS_SPIDER, 123 STEAM_GSTAT_DEATHS_GHOUL, 124 STEAM_GSTAT_DEATHS_SKELETON, 125 STEAM_GSTAT_DEATHS_SCORPION, 126 STEAM_GSTAT_DEATHS_IMP, 127 STEAM_GSTAT_DEATHS_GNOME, 128 STEAM_GSTAT_DEATHS_DEMON, 129 STEAM_GSTAT_DEATHS_SUCCUBUS, 130 STEAM_GSTAT_DEATHS_LICH, 131 STEAM_GSTAT_DEATHS_MINOTAUR, 132 STEAM_GSTAT_DEATHS_DEVIL, 133 STEAM_GSTAT_DEATHS_SHOPKEEPER, 134 STEAM_GSTAT_DEATHS_KOBOLD, 135 STEAM_GSTAT_DEATHS_SCARAB, 136 STEAM_GSTAT_DEATHS_CRYSTALGOLEM, 137 STEAM_GSTAT_DEATHS_INCUBUS, 138 STEAM_GSTAT_DEATHS_VAMPIRE, 139 STEAM_GSTAT_DEATHS_SHADOW, 140 STEAM_GSTAT_DEATHS_COCKATRICE, 141 STEAM_GSTAT_DEATHS_INSECTOID, 142 STEAM_GSTAT_DEATHS_GOATMAN, 143 STEAM_GSTAT_DEATHS_AUTOMATON, 144 STEAM_GSTAT_DEATHS_LICHICE, 145 STEAM_GSTAT_DEATHS_LICHFIRE, 146 STEAM_GSTAT_DEATHS_SENTRYBOT, 147 STEAM_GSTAT_DEATHS_SPELLBOT, 148 STEAM_GSTAT_DEATHS_GYROBOT, 149 STEAM_GSTAT_DEATHS_DUMMYBOT, 150 STEAM_GSTAT_TWINSICE_SLAIN, 151 STEAM_GSTAT_SHOPKEEPERS_SLAIN, 152 STEAM_GSTAT_MINOTAURS_SLAIN, 153 STEAM_GSTAT_TUTORIAL_ENTERED, 154 STEAM_GSTAT_TUTORIAL1_COMPLETED, 155 STEAM_GSTAT_TUTORIAL2_COMPLETED, 156 STEAM_GSTAT_TUTORIAL3_COMPLETED, 157 STEAM_GSTAT_TUTORIAL4_COMPLETED, 158 STEAM_GSTAT_TUTORIAL5_COMPLETED, 159 STEAM_GSTAT_TUTORIAL6_COMPLETED, 160 STEAM_GSTAT_TUTORIAL7_COMPLETED, 161 STEAM_GSTAT_TUTORIAL8_COMPLETED, 162 STEAM_GSTAT_TUTORIAL9_COMPLETED, 163 STEAM_GSTAT_TUTORIAL10_COMPLETED, 164 STEAM_GSTAT_TUTORIAL1_ATTEMPTS, 165 STEAM_GSTAT_TUTORIAL2_ATTEMPTS, 166 STEAM_GSTAT_TUTORIAL3_ATTEMPTS, 167 STEAM_GSTAT_TUTORIAL4_ATTEMPTS, 168 STEAM_GSTAT_TUTORIAL5_ATTEMPTS, 169 STEAM_GSTAT_TUTORIAL6_ATTEMPTS, 170 STEAM_GSTAT_TUTORIAL7_ATTEMPTS, 171 STEAM_GSTAT_TUTORIAL8_ATTEMPTS, 172 STEAM_GSTAT_TUTORIAL9_ATTEMPTS, 173 STEAM_GSTAT_TUTORIAL10_ATTEMPTS, 174 STEAM_GSTAT_DISABLE, 175 STEAM_GSTAT_PROMO, 176 STEAM_GSTAT_PROMO_INTERACT 177 }; 178 179 SteamGlobalStatIndexes getIndexForDeathType(int type); 180 181 static const std::pair<std::string, int> steamStatAchStringsAndMaxVals[] = 182 { 183 std::make_pair("BARONY_ACH_NONE", 999999), // STEAM_STAT_BOULDER_DEATHS, 184 std::make_pair("BARONY_ACH_RHINESTONE_COWBOY", 50), // STEAM_STAT_RHINESTONE_COWBOY, 185 std::make_pair("BARONY_ACH_TOUGH_AS_NAILS", 50), // STEAM_STAT_TOUGH_AS_NAILS, 186 std::make_pair("BARONY_ACH_UNSTOPPABLE_FORCE",50), // STEAM_STAT_UNSTOPPABLE_FORCE, 187 std::make_pair("BARONY_ACH_NONE", 999999), // STEAM_STAT_GAMES_STARTED, 188 std::make_pair("BARONY_ACH_NONE", 999999), // STEAM_STAT_GAMES_WON, 189 std::make_pair("BARONY_ACH_BOMBARDIER", 50), // STEAM_STAT_BOMBARDIER, 190 std::make_pair("BARONY_ACH_IN_THE_MIX", 50), // STEAM_STAT_IN_THE_MIX, 191 std::make_pair("BARONY_ACH_FREE_REFILLS", 50), // STEAM_STAT_FREE_REFILLS, 192 std::make_pair("BARONY_ACH_TAKE_THIS_OUTSIDE", 10), // STEAM_STAT_TAKE_THIS_OUTSIDE, 193 std::make_pair("BARONY_ACH_RICH_ALTER_EGO", 50000), // STEAM_STAT_ALTER_EGO, 194 std::make_pair("BARONY_ACH_BLOOD_SPORT", 50), // STEAM_STAT_BLOOD_SPORT, 195 std::make_pair("BARONY_ACH_BAD_BLOOD", 500), // STEAM_STAT_BAD_BLOOD, 196 std::make_pair("BARONY_ACH_IRON_GUT", 20), // STEAM_STAT_IRON_GUT, 197 std::make_pair("BARONY_ACH_BOTTLE_NOSED", 20), // STEAM_STAT_BOTTLE_NOSED, 198 std::make_pair("BARONY_ACH_BARFIGHT_CHAMP", 50), // STEAM_STAT_BARFIGHT_CHAMP, 199 std::make_pair("BARONY_ACH_VOLATILE", 20), // STEAM_STAT_VOLATILE, 200 std::make_pair("BARONY_ACH_SURROGATES", 50), // STEAM_STAT_SURROGATES, 201 std::make_pair("BARONY_ACH_KILL_COMMAND", 50), // STEAM_STAT_KILL_COMMAND 202 std::make_pair("BARONY_ACH_TRASH_COMPACTOR", 100), // STEAM_STAT_TRASH_COMPACTOR 203 std::make_pair("BARONY_ACH_SPICY", 10), // STEAM_STAT_SPICY 204 std::make_pair("BARONY_ACH_SERIAL_THRILLA", 100), // STEAM_STAT_SERIAL_THRILLA 205 std::make_pair("BARONY_ACH_TRADITION", 20), // STEAM_STAT_TRADITION 206 std::make_pair("BARONY_ACH_POP_QUIZ", 20), // STEAM_STAT_POP_QUIZ 207 std::make_pair("BARONY_ACH_DYSLEXIA", 50), // STEAM_STAT_DYSLEXIA 208 std::make_pair("BARONY_ACH_BOOKWORM", 50), // STEAM_STAT_BOOKWORM 209 std::make_pair("BARONY_ACH_MONARCH", 20), // STEAM_STAT_MONARCH 210 std::make_pair("BARONY_ACH_SUPER_SHREDDER", 1000), // STEAM_STAT_SUPER_SHREDDER 211 std::make_pair("BARONY_ACH_FIXER_UPPER", 100), // STEAM_STAT_FIXER_UPPER 212 std::make_pair("BARONY_ACH_TORCHERER", 100), // STEAM_STAT_TORCHERER 213 std::make_pair("BARONY_ACH_MANY_PEDI_PALP", 50), // STEAM_STAT_MANY_PEDI_PALP 214 std::make_pair("BARONY_ACH_5000_SECOND_RULE", 50), // STEAM_STAT_5000_SECOND_RULE 215 std::make_pair("BARONY_ACH_SOCIAL_BUTTERFLY", 50), // STEAM_STAT_SOCIAL_BUTTERFLY 216 std::make_pair("BARONY_ACH_ROLL_THE_BONES", 50), // STEAM_STAT_ROLL_THE_BONES 217 std::make_pair("BARONY_ACH_COWBOY_FROM_HELL", 50), // STEAM_STAT_COWBOY_FROM_HELL 218 std::make_pair("BARONY_ACH_SELF_FLAGELLATION", 30), // STEAM_STAT_SELF_FLAGELLATION 219 std::make_pair("BARONY_ACH_CHOPPING_BLOCK", 50), // STEAM_STAT_CHOPPING_BLOCK 220 std::make_pair("BARONY_ACH_IF_YOU_LOVE_SOMETHING", 100),// STEAM_STAT_IF_YOU_LOVE_SOMETHING 221 std::make_pair("BARONY_ACH_RAGE_AGAINST", 20), // STEAM_STAT_RAGE_AGAINST 222 std::make_pair("BARONY_ACH_GUERILLA_RADIO", 20), // STEAM_STAT_GUERILLA_RADIO 223 std::make_pair("BARONY_ACH_FASCIST", 50), // STEAM_STAT_FASCIST, 224 std::make_pair("BARONY_ACH_ITS_A_LIVING", 50), // STEAM_STAT_ITS_A_LIVING, 225 std::make_pair("BARONY_ACH_OVERCLOCKED", 600), // STEAM_STAT_OVERCLOCKED 226 std::make_pair("BARONY_ACH_NONE", 1), // STEAM_STAT_BACK_TO_BASICS, 227 std::make_pair("BARONY_ACH_EXTRA_CREDIT", 10), // STEAM_STAT_EXTRA_CREDIT 228 std::make_pair("BARONY_ACH_NONE", 1023), // STEAM_STAT_EXTRA_CREDIT_LVLS, 229 std::make_pair("BARONY_ACH_DIPLOMA", 10), // STEAM_STAT_DIPLOMA 230 std::make_pair("BARONY_ACH_NONE", 1023), // STEAM_STAT_DIPLOMA_LVLS, 231 std::make_pair("BARONY_ACH_NONE", 1) // STEAM_STAT_TUTORIAL_ENTERED, 232 }; 233 234 typedef struct score_t 235 { 236 Sint32 kills[NUMMONSTERS]; 237 Stat* stats; 238 Sint32 classnum; 239 Sint32 dungeonlevel; 240 int victory; 241 242 Uint32 completionTime; 243 bool conductPenniless; 244 bool conductFoodless; 245 bool conductVegetarian; 246 bool conductIlliterate; 247 Sint32 conductGameChallenges[NUM_CONDUCT_CHALLENGES]; 248 Sint32 gameStatistics[NUM_GAMEPLAY_STATISTICS]; 249 } score_t; 250 extern list_t topscores; 251 extern list_t topscoresMultiplayer; 252 extern int victory; 253 254 extern Uint32 completionTime; 255 extern bool conductPenniless; 256 extern bool conductFoodless; 257 extern bool conductVegetarian; 258 extern bool conductIlliterate; 259 extern list_t booksRead; 260 extern bool usedClass[NUMCLASSES]; 261 extern bool usedRace[NUMRACES]; 262 extern Uint32 loadingsavegame; 263 extern Sint32 conductGameChallenges[NUM_CONDUCT_CHALLENGES]; 264 extern Sint32 gameStatistics[NUM_GAMEPLAY_STATISTICS]; 265 extern std::vector<std::pair<Uint32, Uint32>> achievementRhythmOfTheKnightVec[MAXPLAYERS]; 266 extern bool achievementStatusRhythmOfTheKnight[MAXPLAYERS]; 267 extern std::pair<Uint32, Uint32> achievementThankTheTankPair[MAXPLAYERS]; 268 extern bool achievementStatusBaitAndSwitch[MAXPLAYERS]; 269 extern Uint32 achievementBaitAndSwitchTimer[MAXPLAYERS]; 270 extern std::unordered_set<int> clientLearnedAlchemyIngredients; 271 extern bool achievementStatusThankTheTank[MAXPLAYERS]; 272 extern std::vector<Uint32> achievementStrobeVec[MAXPLAYERS]; 273 extern bool achievementStatusStrobe[MAXPLAYERS]; 274 extern bool playerFailedRangedOnlyConduct[MAXPLAYERS]; 275 extern bool achievementBrawlerMode; 276 extern bool achievementRangedMode[MAXPLAYERS]; 277 278 score_t* scoreConstructor(); 279 void scoreDeconstructor(void* data); 280 int saveScore(); 281 int totalScore(score_t* score); 282 void loadScore(int score); 283 void saveAllScores(const std::string& scoresfilename); 284 void loadAllScores(const std::string& scoresfilename); 285 extern int savegameCurrentFileIndex; 286 std::string setSaveGameFileName(bool singleplayer, bool followersFile, int saveIndex = savegameCurrentFileIndex); 287 int saveGame(int saveIndex = savegameCurrentFileIndex); 288 int loadGame(int player, int saveIndex = savegameCurrentFileIndex); 289 list_t* loadGameFollowers(int saveIndex = savegameCurrentFileIndex); 290 int deleteSaveGame(int gametype, int saveIndex = savegameCurrentFileIndex); 291 bool saveGameExists(bool singleplayer, int saveIndex = savegameCurrentFileIndex); 292 bool anySaveFileExists(); 293 294 char* getSaveGameName(bool singleplayer, int saveIndex = savegameCurrentFileIndex); 295 int getSaveGameType(bool singleplayer, int saveIndex = savegameCurrentFileIndex); 296 int getSaveGameClientnum(bool singleplayer, int saveIndex = savegameCurrentFileIndex); 297 Uint32 getSaveGameMapSeed(bool singleplayer, int saveIndex = savegameCurrentFileIndex); 298 Uint32 getSaveGameUniqueGameKey(bool singleplayer, int saveIndex = savegameCurrentFileIndex); 299 int getSaveGameVersionNum(bool singleplayer, int saveIndex = savegameCurrentFileIndex); 300 int getSavegameVersion(char checkstr[64]); // returns -1 on invalid version, otherwise converts to 3 digit int 301 void setDefaultPlayerConducts(); // init values for foodless, penniless etc. 302 void updatePlayerConductsInMainLoop(); // check and update conduct flags throughout game that don't require a specific action. (tracking gold, server flags etc...) 303 void updateGameplayStatisticsInMainLoop(); // check for achievement values for gameplay statistics. 304 void updateAchievementRhythmOfTheKnight(int player, Entity* target, bool playerIsHit); 305 void updateAchievementThankTheTank(int player, Entity* target, bool targetKilled); 306 void updateAchievementBaitAndSwitch(int player, bool isTeleporting); 307 static const int SAVE_GAMES_MAX = 10; 308 309 class AchievementObserver 310 { 311 int levelObserved = -1; 312 public: 313 Uint32 playerUids[MAXPLAYERS] = { 0 }; 314 void getCurrentPlayerUids(); 315 bool updateOnLevelChange(); 316 void updateData(); 317 int checkUidIsFromPlayer(Uint32 uid); 318 std::unordered_map<Uint32, std::unordered_map<int, std::pair<int,int>>> entityAchievementsToProcess; // uid of entity, achievement int, <ticks remaining, optional counter> 319 320 bool addEntityAchievementTimer(Entity* entity, int achievement, int ticks, bool resetTimerIfActive, int optionalIncrement); 321 322 void achievementTimersTickDown(); 323 void awardAchievementIfActive(int player, Entity* entity, int achievement); 324 void awardAchievement(int player, int achievement); 325 void printActiveAchievementTimers(); 326 327 enum Achievement : int 328 { 329 BARONY_ACH_TELEFRAG = 1, 330 BARONY_ACH_REAL_BOY, 331 BARONY_ACH_COOP_ESCAPE_MINES, 332 BARONY_ACH_SWINGERS, 333 BARONY_ACH_COLD_BLOODED, 334 BARONY_ACH_SOULLESS, 335 BARONY_ACH_TRIBAL, 336 BARONY_ACH_MANAGEMENT_TEAM, 337 BARONY_ACH_SOCIOPATHS, 338 BARONY_ACH_FACES_OF_DEATH, 339 BARONY_ACH_SURVIVALISTS, 340 BARONY_ACH_BOMBTRACK, 341 BARONY_ACH_CALM_LIKE_A_BOMB, 342 BARONY_ACH_CAUGHT_IN_A_MOSH, 343 BARONY_ACH_PLEASE_HOLD, 344 BARONY_ACH_FELL_BEAST, 345 BARONY_ACH_STRUNG_OUT, 346 BARONY_ACH_OHAI_MARK, 347 BARONY_ACH_IRONIC_PUNISHMENT, 348 BARONY_ACH_LEVITANT_LACKEY, 349 BARONY_ACH_WONDERFUL_TOYS, 350 BARONY_ACH_FLUTTERSHY, 351 BARONY_ACH_IF_YOU_LOVE_SOMETHING, 352 BARONY_ACH_COWBOY_FROM_HELL, 353 BARONY_ACH_TRASH_COMPACTOR, 354 BARONY_ACH_EXTRA_CREDIT, 355 BARONY_ACH_DIPLOMA, 356 BARONY_ACH_BACK_TO_BASICS, 357 BARONY_ACH_FAST_LEARNER, 358 BARONY_ACH_MASTER 359 }; 360 enum AchievementEvent : int 361 { 362 ACH_EVENT_NONE, 363 REAL_BOY_HUMAN_RECRUIT, 364 REAL_BOY_SHOP, 365 FORUM_TROLL_BREAK_WALL, 366 FORUM_TROLL_RECRUIT_TROLL, 367 FORUM_TROLL_FEAR, 368 EXTRA_CREDIT_SECRET, 369 DIPLOMA_LEVEL_COMPLETE, 370 BACK_TO_BASICS_LEVEL_COMPLETE, 371 FAST_LEARNER_TIME_UPDATE 372 }; 373 void updatePlayerAchievement(int player, Achievement achievement, AchievementEvent achEvent); bIsAchievementAllowedDuringTutorial(std::string achievementStr)374 bool bIsAchievementAllowedDuringTutorial(std::string achievementStr) 375 { 376 if ( !achievementStr.compare("BARONY_ACH_TEACHABLE_MOMENT") ) 377 { 378 return true; 379 } 380 if ( !achievementStr.compare("BARONY_ACH_MASTER") ) 381 { 382 return true; 383 } 384 if ( !achievementStr.compare("BARONY_ACH_FAST_LEARNER") ) 385 { 386 return true; 387 } 388 if ( !achievementStr.compare("BARONY_ACH_BACK_TO_BASICS") ) 389 { 390 return true; 391 } 392 if ( !achievementStr.compare("BARONY_ACH_EXPELLED") ) 393 { 394 return true; 395 } 396 if ( !achievementStr.compare("BARONY_ACH_EXTRA_CREDIT") ) 397 { 398 return true; 399 } 400 if ( !achievementStr.compare("BARONY_ACH_DIPLOMA") ) 401 { 402 return true; 403 } 404 return false; 405 } bIsStatisticAllowedDuringTutorial(SteamStatIndexes statistic)406 bool bIsStatisticAllowedDuringTutorial(SteamStatIndexes statistic) 407 { 408 switch ( statistic ) 409 { 410 case STEAM_STAT_EXTRA_CREDIT: 411 case STEAM_STAT_EXTRA_CREDIT_LVLS: 412 case STEAM_STAT_DIPLOMA: 413 case STEAM_STAT_DIPLOMA_LVLS: 414 case STEAM_STAT_TUTORIAL_ENTERED: 415 return true; 416 break; 417 default: 418 return false; 419 break; 420 } 421 } 422 class PlayerAchievements 423 { 424 public: 425 bool caughtInAMosh = false; 426 bool bombTrack = false; 427 bool calmLikeABomb = false; 428 bool strungOut = false; 429 bool wonderfulToys = false; 430 bool levitantLackey = false; 431 bool flutterShy = false; 432 bool gastricBypass = false; 433 Uint32 ticksSpentOverclocked = 0; 434 bool tradition = false; 435 int traditionKills = 0; 436 int torchererScrap = 0; 437 int superShredder = 0; 438 int fixerUpper = 0; 439 int ifYouLoveSomething = 0; 440 int socialButterfly = 0; 441 int rollTheBones = 0; 442 int trashCompactor = 0; 443 444 std::pair<int, int> realBoy; 445 std::unordered_map<Uint32, int> caughtInAMoshTargets; 446 std::vector<Uint32> strungOutTicks; 447 std::unordered_set<Uint32> ironicPunishmentTargets; 448 std::pair<real_t, real_t> flutterShyCoordinates; 449 std::pair<int, Uint32> gastricBypassSpell; 450 std::unordered_set<Uint32> rat5000secondRule; 451 PlayerAchievements()452 PlayerAchievements() 453 { 454 realBoy = std::make_pair(0, 0); 455 gastricBypassSpell = std::make_pair(0, 0); 456 flutterShyCoordinates = std::make_pair(0.0, 0.0); 457 }; 458 bool checkPathBetweenObjects(Entity* player, Entity* target, int achievement); 459 bool checkTraditionKill(Entity* player, Entity* target); 460 } playerAchievements[MAXPLAYERS]; 461 462 void clearPlayerAchievementData(); 463 void checkMapScriptsOnVariableSet(); 464 void updateGlobalStat(int index, int value = 1); 465 }; 466 extern AchievementObserver achievementObserver; 467 468 #ifdef STEAMWORKS 469 bool steamLeaderboardSetScore(score_t* score); 470 bool steamLeaderboardReadScore(int tags[CSteamLeaderboards::k_numLeaderboardTags]); 471 #endif // STEAMWORKS 472