1 /*------------------------------------------------------------------------------- 2 3 BARONY 4 File: game.hpp 5 Desc: header file for the game 6 7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved. 8 See LICENSE for details. 9 10 -------------------------------------------------------------------------------*/ 11 12 #pragma once 13 14 #include <vector> 15 #include <random> 16 #include <chrono> 17 18 #ifdef STEAMWORKS 19 #include <steam/steam_api.h> 20 #include "steam.hpp" 21 #endif 22 23 // REMEMBER TO CHANGE THIS WITH EVERY NEW OFFICIAL VERSION!!! 24 #define VERSION "v3.3.7" 25 #define GAME_CODE 26 27 //#define MAX_FPS_LIMIT 60 //TODO: Make this configurable. 28 class Entity; 29 30 #define DEBUG 1 31 #define ENTITY_PACKET_LENGTH 46 32 #define NET_PACKET_SIZE 512 33 34 // impulses (bound keystrokes, mousestrokes, and joystick/game controller strokes) //TODO: Player-by-player basis. 35 extern Uint32 impulses[NUMIMPULSES]; 36 extern Uint32 joyimpulses[NUM_JOY_IMPULSES]; //Joystick/gamepad only impulses. 37 extern int reversemouse; 38 extern real_t mousespeed; 39 40 void handleEvents(void); 41 void startMessages(); 42 43 // net packet send 44 typedef struct packetsend_t 45 { 46 UDPsocket sock; 47 int channel; 48 UDPpacket* packet; 49 int num; 50 int tries; 51 int hostnum; 52 } packetsend_t; 53 extern list_t safePacketsSent; 54 extern std::unordered_map<int, Uint32> safePacketsReceivedMap[MAXPLAYERS]; 55 extern bool receivedclientnum; 56 57 extern Entity* hudweapon, *hudarm; 58 59 extern Uint32 clientplayer; 60 extern Sint32 numplayers; 61 extern Sint32 clientnum; 62 extern bool intro; 63 extern int introstage; 64 extern bool gamePaused; 65 extern bool fadeout, fadefinished; 66 extern int fadealpha; 67 extern Entity* client_selected[MAXPLAYERS]; 68 extern bool inrange[MAXPLAYERS]; 69 extern bool deleteallbuttons; 70 extern Sint32 client_classes[MAXPLAYERS]; 71 extern Uint32 client_keepalive[MAXPLAYERS]; 72 extern Uint16 portnumber; 73 extern list_t messages; 74 extern list_t command_history; 75 extern node_t* chosen_command; 76 extern bool command; 77 extern bool noclip, godmode, buddhamode; 78 extern bool everybodyfriendly; 79 extern bool combat, combattoggle; 80 extern bool assailant[MAXPLAYERS]; 81 extern bool oassailant[MAXPLAYERS]; 82 extern int assailantTimer[MAXPLAYERS]; 83 static const int COMBAT_MUSIC_COOLDOWN = 200; // 200 ticks of combat music before it fades away. 84 extern list_t removedEntities; 85 extern list_t entitiesToDelete[MAXPLAYERS]; 86 extern char maptoload[256], configtoload[256]; 87 extern bool loadingmap, loadingconfig; 88 extern int startfloor; 89 extern bool skipintro; 90 extern Uint32 uniqueGameKey; 91 92 // definitions 93 extern bool showfps; 94 extern real_t t, ot, frameval[AVERAGEFRAMES]; 95 extern Uint32 cycles, pingtime; 96 extern Uint32 timesync; 97 extern real_t fps; 98 extern bool shootmode; 99 static const int NUMCLASSES = 21; 100 #define NUMRACES 13 101 #define NUMPLAYABLERACES 9 102 extern char address[64]; 103 extern bool loadnextlevel; 104 extern int skipLevelsOnLoad; 105 extern bool loadingSameLevelAsCurrent; 106 extern std::string loadCustomNextMap; 107 extern Uint32 forceMapSeed; 108 extern int currentlevel; 109 extern bool secretlevel; 110 extern bool darkmap; 111 extern int shaking, bobbing; 112 extern int musvolume; 113 extern SDL_Surface* title_bmp; 114 extern SDL_Surface* titleDefault_bmp; 115 extern SDL_Surface* logo_bmp; 116 extern SDL_Surface* cursor_bmp; 117 extern SDL_Surface* cross_bmp; 118 119 enum PlayerClasses : int 120 { 121 CLASS_BARBARIAN, 122 CLASS_WARRIOR, 123 CLASS_HEALER, 124 CLASS_ROGUE, 125 CLASS_WANDERER, 126 CLASS_CLERIC, 127 CLASS_MERCHANT, 128 CLASS_WIZARD, 129 CLASS_ARCANIST, 130 CLASS_JOKER, 131 CLASS_SEXTON, 132 CLASS_NINJA, 133 CLASS_MONK, 134 CLASS_CONJURER, 135 CLASS_ACCURSED, 136 CLASS_MESMER, 137 CLASS_BREWER, 138 CLASS_MACHINIST, 139 CLASS_PUNISHER, 140 CLASS_SHAMAN, 141 CLASS_HUNTER 142 }; 143 144 static const int CLASS_SHAMAN_NUM_STARTING_SPELLS = 15; 145 146 enum PlayerRaces : int 147 { 148 RACE_HUMAN, 149 RACE_SKELETON, 150 RACE_VAMPIRE, 151 RACE_SUCCUBUS, 152 RACE_GOATMAN, 153 RACE_AUTOMATON, 154 RACE_INCUBUS, 155 RACE_GOBLIN, 156 RACE_INSECTOID, 157 RACE_RAT, 158 RACE_TROLL, 159 RACE_SPIDER, 160 RACE_IMP 161 }; 162 163 enum ESteamLeaderboardTitles : int 164 { 165 LEADERBOARD_NONE, 166 LEADERBOARD_NORMAL_TIME, 167 LEADERBOARD_NORMAL_SCORE, 168 LEADERBOARD_MULTIPLAYER_TIME, 169 LEADERBOARD_MULTIPLAYER_SCORE, 170 LEADERBOARD_HELL_TIME, 171 LEADERBOARD_HELL_SCORE, 172 LEADERBOARD_HARDCORE_TIME, 173 LEADERBOARD_HARDCORE_SCORE, 174 LEADERBOARD_CLASSIC_TIME, 175 LEADERBOARD_CLASSIC_SCORE, 176 LEADERBOARD_CLASSIC_HARDCORE_TIME, 177 LEADERBOARD_CLASSIC_HARDCORE_SCORE, 178 LEADERBOARD_MULTIPLAYER_CLASSIC_TIME, 179 LEADERBOARD_MULTIPLAYER_CLASSIC_SCORE, 180 LEADERBOARD_MULTIPLAYER_HELL_TIME, 181 LEADERBOARD_MULTIPLAYER_HELL_SCORE, 182 LEADERBOARD_DLC_NORMAL_TIME, 183 LEADERBOARD_DLC_NORMAL_SCORE, 184 LEADERBOARD_DLC_MULTIPLAYER_TIME, 185 LEADERBOARD_DLC_MULTIPLAYER_SCORE, 186 LEADERBOARD_DLC_HELL_TIME, 187 LEADERBOARD_DLC_HELL_SCORE, 188 LEADERBOARD_DLC_HARDCORE_TIME, 189 LEADERBOARD_DLC_HARDCORE_SCORE, 190 LEADERBOARD_DLC_CLASSIC_TIME, 191 LEADERBOARD_DLC_CLASSIC_SCORE, 192 LEADERBOARD_DLC_CLASSIC_HARDCORE_TIME, 193 LEADERBOARD_DLC_CLASSIC_HARDCORE_SCORE, 194 LEADERBOARD_DLC_MULTIPLAYER_CLASSIC_TIME, 195 LEADERBOARD_DLC_MULTIPLAYER_CLASSIC_SCORE, 196 LEADERBOARD_DLC_MULTIPLAYER_HELL_TIME, 197 LEADERBOARD_DLC_MULTIPLAYER_HELL_SCORE 198 }; 199 200 bool achievementUnlocked(const char* achName); 201 void steamAchievement(const char* achName); 202 void steamUnsetAchievement(const char* achName); 203 void steamAchievementClient(int player, const char* achName); 204 void steamAchievementEntity(Entity* my, const char* achName); // give steam achievement to an entity, and check for valid player info. 205 void steamStatisticUpdate(int statisticNum, ESteamStatTypes type, int value); 206 void steamStatisticUpdateClient(int player, int statisticNum, ESteamStatTypes type, int value); 207 void steamIndicateStatisticProgress(int statisticNum, ESteamStatTypes type); 208 void freePlayerEquipment(int x); 209 void pauseGame(int mode, int ignoreplayer); 210 int initGame(); 211 void deinitGame(); 212 Uint32 timerCallback(Uint32 interval, void* param); 213 void handleButtons(void); 214 void gameLogic(void); 215 216 // behavior function prototypes: 217 void actAnimator(Entity* my); 218 void actRotate(Entity* my); 219 void actLiquid(Entity* my); 220 void actEmpty(Entity* my); 221 void actFurniture(Entity* my); 222 void actMCaxe(Entity* my); 223 void actDoorFrame(Entity* my); 224 void actDeathCam(Entity* my); 225 void actPlayerLimb(Entity* my); 226 void actTorch(Entity* my); 227 void actCrystalShard(Entity* my); 228 void actDoor(Entity* my); 229 void actHudWeapon(Entity* my); 230 void actHudShield(Entity* my); 231 void actHudAdditional(Entity* my); 232 void actHudArrowModel(Entity* my); 233 void actItem(Entity* my); 234 void actGoldBag(Entity* my); 235 void actGib(Entity* my); 236 Entity* spawnGib(Entity* parentent, int customGibSprite = -1); 237 Entity* spawnGibClient(Sint16 x, Sint16 y, Sint16 z, Sint16 sprite); 238 void serverSpawnGibForClient(Entity* gib); 239 void actLadder(Entity* my); 240 void actLadderUp(Entity* my); 241 void actPortal(Entity* my); 242 void actWinningPortal(Entity* my); 243 void actFlame(Entity* my); 244 void actCampfire(Entity* my); 245 Entity* spawnFlame(Entity* parentent, Sint32 sprite); 246 void actMagic(Entity* my); 247 Entity* castMagic(Entity* parentent); 248 void actSprite(Entity* my); 249 void actSpriteNametag(Entity* my); 250 void actSleepZ(Entity* my); 251 Entity* spawnBang(Sint16 x, Sint16 y, Sint16 z); 252 Entity* spawnExplosion(Sint16 x, Sint16 y, Sint16 z); 253 Entity* spawnExplosionFromSprite(Uint16 sprite, Sint16 x, Sint16 y, Sint16 z); 254 Entity* spawnSleepZ(Sint16 x, Sint16 y, Sint16 z); 255 Entity* spawnFloatingSpriteMisc(int sprite, Sint16 x, Sint16 y, Sint16 z); 256 void actArrow(Entity* my); 257 void actBoulder(Entity* my); 258 void actBoulderTrap(Entity* my); 259 void actBoulderTrapEast(Entity* my); 260 void actBoulderTrapWest(Entity* my); 261 void actBoulderTrapSouth(Entity* my); 262 void actBoulderTrapNorth(Entity* my); 263 void actHeadstone(Entity* my); 264 void actThrown(Entity* my); 265 void actBeartrap(Entity* my); 266 void actBeartrapLaunched(Entity* my); 267 void actBomb(Entity* my); 268 void actDecoyBox(Entity* my); 269 void actDecoyBoxCrank(Entity* my); 270 void actSpearTrap(Entity* my); 271 void actWallBuster(Entity* my); 272 void actWallBuilder(Entity* my); 273 void actPowerCrystalBase(Entity* my); 274 void actPowerCrystal(Entity* my); 275 void actPowerCrystalParticleIdle(Entity* my); 276 void actPedestalBase(Entity* my); 277 void actPedestalOrb(Entity* my); 278 void actMidGamePortal(Entity* my); 279 void actCustomPortal(Entity* my); 280 void actTeleporter(Entity* my); 281 void actMagicTrapCeiling(Entity* my); 282 void actExpansionEndGamePortal(Entity* my); 283 void actSoundSource(Entity* my); 284 void actLightSource(Entity* my); 285 void actSignalTimer(Entity* my); 286 287 void startMessages(); 288 bool frameRateLimit(Uint32 maxFrameRate, bool resetAccumulator = true); 289 extern Uint32 networkTickrate; 290 extern bool gameloopFreezeEntities; 291 extern Uint32 serverSchedulePlayerHealthUpdate; 292 293 #define TOUCHRANGE 32 294 #define STRIKERANGE 24 295 #define XPSHARERANGE 256 296 297 // function prototypes for charclass.c: 298 void initClass(int player); 299 void initShapeshiftHotbar(); 300 void deinitShapeshiftHotbar(); 301 bool playerUnlockedShamanSpell(int player, Item* item); 302 303 extern char last_ip[64]; 304 extern char last_port[64]; 305 306 //TODO: Maybe increase with level or something? 307 //TODO: Pause health regen during combat? 308 #define HEAL_TIME 600 //10 seconds. //Original time: 3600 (1 minute) 309 #define MAGIC_REGEN_TIME 300 // 5 seconds 310 311 #define DEFAULT_HP 30 312 #define DEFAULT_MP 30 313 #define HP_MOD 5 314 #define MP_MOD 5 315 316 #define SPRITE_FLAME 13 317 #define SPRITE_CRYSTALFLAME 96 318 319 #define MAXCHARGE 30 // charging up weapons 320 321 static const int BASE_MELEE_DAMAGE = 8; 322 static const int BASE_RANGED_DAMAGE = 7; 323 static const int BASE_THROWN_DAMAGE = 6; 324 static const int BASE_PLAYER_UNARMED_DAMAGE = 8; 325 326 extern bool spawn_blood; 327 extern bool capture_mouse; //Useful for debugging when the game refuses to release the mouse when it's crashed. 328 329 #define LEVELSFILE "maps/levels.txt" 330 #define SECRETLEVELSFILE "maps/secretlevels.txt" 331 #define LENGTH_OF_LEVEL_REGION 5 332 333 #define TICKS_PER_SECOND 50 334 static const Uint8 TICKS_TO_PROCESS_FIRE = 30; // The amount of ticks needed until the 'BURNING' Status Effect is processed (char_fire % TICKS_TO_PROCESS_FIRE == 0) 335 static const int EFFECT_WITHDRAWAL_BASE_TIME = TICKS_PER_SECOND * 60 * 8; // 8 minutes base withdrawal time. 336 337 static const std::string PLAYERNAMES_MALE_FILE = "playernames-male.txt"; 338 static const std::string PLAYERNAMES_FEMALE_FILE = "playernames-female.txt"; 339 extern std::vector<std::string> randomPlayerNamesMale; 340 extern std::vector<std::string> randomPlayerNamesFemale; 341 extern bool enabledDLCPack1; 342 extern bool enabledDLCPack2; 343 extern std::vector<std::string> physFSFilesInDirectory; 344 void loadRandomNames(); 345 extern int monsterEmoteGimpTimer; 346 extern int selectedEntityGimpTimer; 347 void mapLevel(int player); 348 void mapFoodOnLevel(int player); 349 350 class TileEntityListHandler 351 { 352 private: 353 static const int kMaxMapDimension = 256; 354 public: 355 list_t gridEntities[kMaxMapDimension][kMaxMapDimension]; 356 357 void clearTile(int x, int y); 358 void emptyGridEntities(); 359 list_t* getTileList(int x, int y); 360 node_t* addEntity(Entity& entity); 361 node_t* updateEntity(Entity& entity); 362 std::vector<list_t*> getEntitiesWithinRadius(int u, int v, int radius); 363 std::vector<list_t*> getEntitiesWithinRadiusAroundEntity(Entity* entity, int radius); 364 TileEntityListHandler()365 TileEntityListHandler() 366 { 367 for ( int i = 0; i < kMaxMapDimension; ++i ) 368 { 369 for ( int j = 0; j < kMaxMapDimension; ++j ) 370 { 371 gridEntities[i][j].first = nullptr; 372 gridEntities[i][j].last = nullptr; 373 } 374 } 375 }; 376 ~TileEntityListHandler()377 ~TileEntityListHandler() 378 { 379 for ( int i = 0; i < kMaxMapDimension; ++i ) 380 { 381 for ( int j = 0; j < kMaxMapDimension; ++j ) 382 { 383 clearTile(i, j); 384 } 385 } 386 }; 387 }; 388 extern TileEntityListHandler TileEntityList; 389 390 extern float framerateAccumulatedTime; 391 392 class DebugStatsClass 393 { 394 public: 395 std::chrono::high_resolution_clock::time_point t1StartLoop; 396 std::chrono::high_resolution_clock::time_point t2PostEvents; 397 std::chrono::high_resolution_clock::time_point t21PostHandleMessages; 398 std::chrono::high_resolution_clock::time_point t3SteamCallbacks; 399 std::chrono::high_resolution_clock::time_point t4Music; 400 std::chrono::high_resolution_clock::time_point t5MainDraw; 401 std::chrono::high_resolution_clock::time_point t6Messages; 402 std::chrono::high_resolution_clock::time_point t7Inputs; 403 std::chrono::high_resolution_clock::time_point t8Status; 404 std::chrono::high_resolution_clock::time_point t9GUI; 405 std::chrono::high_resolution_clock::time_point t10FrameLimiter; 406 std::chrono::high_resolution_clock::time_point t11End; 407 408 std::chrono::high_resolution_clock::time_point eventsT1; 409 std::chrono::high_resolution_clock::time_point eventsT2; 410 std::chrono::high_resolution_clock::time_point eventsT3; 411 std::chrono::high_resolution_clock::time_point eventsT4; 412 std::chrono::high_resolution_clock::time_point eventsT5; 413 std::chrono::high_resolution_clock::time_point eventsT6; 414 415 std::chrono::high_resolution_clock::time_point messagesT1; 416 417 std::chrono::high_resolution_clock::time_point t1Stored; 418 std::chrono::high_resolution_clock::time_point t2Stored; 419 std::chrono::high_resolution_clock::time_point t21Stored; 420 std::chrono::high_resolution_clock::time_point t3Stored; 421 std::chrono::high_resolution_clock::time_point t4Stored; 422 std::chrono::high_resolution_clock::time_point t5Stored; 423 std::chrono::high_resolution_clock::time_point t6Stored; 424 std::chrono::high_resolution_clock::time_point t7Stored; 425 std::chrono::high_resolution_clock::time_point t8Stored; 426 std::chrono::high_resolution_clock::time_point t9Stored; 427 std::chrono::high_resolution_clock::time_point t10Stored; 428 std::chrono::high_resolution_clock::time_point t11Stored; 429 430 std::chrono::high_resolution_clock::time_point eventsT1stored; 431 std::chrono::high_resolution_clock::time_point eventsT2stored; 432 std::chrono::high_resolution_clock::time_point eventsT3stored; 433 std::chrono::high_resolution_clock::time_point eventsT4stored; 434 std::chrono::high_resolution_clock::time_point eventsT5stored; 435 std::chrono::high_resolution_clock::time_point eventsT6stored; 436 437 std::chrono::high_resolution_clock::time_point messagesT1stored; 438 439 std::chrono::high_resolution_clock::time_point messagesT2WhileLoop; 440 bool handlePacketStartLoop = false; 441 442 std::unordered_map<unsigned long, std::pair<std::string, int>> networkPackets; 443 std::unordered_map<int, int> entityUpdatePackets; 444 445 bool displayStats = false; 446 char debugOutput[1024]; 447 char debugEventOutput[1024]; 448 DebugStatsClass()449 DebugStatsClass() 450 {}; 451 storeOldTimePoints()452 void inline storeOldTimePoints() 453 { 454 t1Stored = t1StartLoop; 455 t2Stored = t2PostEvents; 456 t21Stored = t21PostHandleMessages; 457 t3Stored = t3SteamCallbacks; 458 t4Stored = t4Music; 459 t5Stored = t5MainDraw; 460 t6Stored = t6Messages; 461 t7Stored = t7Inputs; 462 t8Stored = t8Status; 463 t9Stored = t9GUI; 464 t10Stored = t10FrameLimiter; 465 t11Stored = t11End; 466 eventsT1stored = eventsT1; 467 eventsT2stored = eventsT2; 468 eventsT3stored = eventsT3; 469 eventsT4stored = eventsT4; 470 eventsT5stored = eventsT5; 471 eventsT6stored = eventsT6; 472 473 messagesT1stored = messagesT1; 474 }; 475 476 void storeStats(); 477 478 void storeEventStats(); 479 }; 480 extern DebugStatsClass DebugStats; 481 482