Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2020
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.05 KB | None | 0 0
  1. /**
  2. * The Forgotten Server - a free and open-source MMORPG server emulator
  3. * Copyright (C) 2016 Mark Samman <mark.samman@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. */
  19.  
  20. #ifndef FS_GAME_H_3EC96D67DD024E6093B3BAC29B7A6D7F
  21. #define FS_GAME_H_3EC96D67DD024E6093B3BAC29B7A6D7F
  22.  
  23. #include "account.h"
  24. #include "combat.h"
  25. #include "commands.h"
  26. #include "groups.h"
  27. #include "map.h"
  28. #include "position.h"
  29. #include "item.h"
  30. #include "container.h"
  31. #include "player.h"
  32. #include "raids.h"
  33. #include "npc.h"
  34. #include "wildcardtree.h"
  35. #include "quests.h"
  36.  
  37. class ServiceManager;
  38. class Creature;
  39. class Monster;
  40. class Npc;
  41. class CombatInfo;
  42.  
  43. enum stackPosType_t {
  44. STACKPOS_MOVE,
  45. STACKPOS_LOOK,
  46. STACKPOS_TOPDOWN_ITEM,
  47. STACKPOS_USEITEM,
  48. STACKPOS_USETARGET,
  49. };
  50.  
  51. enum WorldType_t {
  52. WORLD_TYPE_NO_PVP = 1,
  53. WORLD_TYPE_PVP = 2,
  54. WORLD_TYPE_PVP_ENFORCED = 3,
  55. };
  56.  
  57. enum GameState_t {
  58. GAME_STATE_STARTUP,
  59. GAME_STATE_INIT,
  60. GAME_STATE_NORMAL,
  61. GAME_STATE_CLOSED,
  62. GAME_STATE_SHUTDOWN,
  63. GAME_STATE_CLOSING,
  64. GAME_STATE_MAINTAIN,
  65. };
  66.  
  67. enum LightState_t {
  68. LIGHT_STATE_DAY,
  69. LIGHT_STATE_NIGHT,
  70. LIGHT_STATE_SUNSET,
  71. LIGHT_STATE_SUNRISE,
  72. };
  73.  
  74. #define EVENT_LIGHTINTERVAL 10000
  75. #define EVENT_DECAYINTERVAL 250
  76. #define EVENT_DECAY_BUCKETS 4
  77.  
  78. /**
  79. * Main Game class.
  80. * This class is responsible to control everything that happens
  81. */
  82.  
  83. class Game
  84. {
  85. public:
  86. Game();
  87. ~Game();
  88.  
  89. // non-copyable
  90. Game(const Game&) = delete;
  91. Game& operator=(const Game&) = delete;
  92.  
  93. void start(ServiceManager* manager);
  94.  
  95. void forceAddCondition(uint32_t creatureId, Condition* condition);
  96. void forceRemoveCondition(uint32_t creatureId, ConditionType_t type);
  97.  
  98. bool loadMainMap(const std::string& filename);
  99. void loadMap(const std::string& path);
  100.  
  101. /**
  102. * Get the map size - info purpose only
  103. * \param width width of the map
  104. * \param height height of the map
  105. */
  106. void getMapDimensions(uint32_t& width, uint32_t& height) const {
  107. width = map.width;
  108. height = map.height;
  109. }
  110.  
  111. void setWorldType(WorldType_t type);
  112. WorldType_t getWorldType() const {
  113. return worldType;
  114. }
  115.  
  116. Cylinder* internalGetCylinder(Player* player, const Position& pos) const;
  117. Thing* internalGetThing(Player* player, const Position& pos, int32_t index,
  118. uint32_t spriteId, stackPosType_t type) const;
  119. static void internalGetPosition(Item* item, Position& pos, uint8_t& stackpos);
  120.  
  121. static std::string getTradeErrorDescription(ReturnValue ret, Item* item);
  122.  
  123. /**
  124. * Returns a creature based on the unique creature identifier
  125. * \param id is the unique creature id to get a creature pointer to
  126. * \returns A Creature pointer to the creature
  127. */
  128. Creature* getCreatureByID(uint32_t id);
  129.  
  130. /**
  131. * Returns a monster based on the unique creature identifier
  132. * \param id is the unique monster id to get a monster pointer to
  133. * \returns A Monster pointer to the monster
  134. */
  135. Monster* getMonsterByID(uint32_t id);
  136.  
  137. /**
  138. * Returns a npc based on the unique creature identifier
  139. * \param id is the unique npc id to get a npc pointer to
  140. * \returns A NPC pointer to the npc
  141. */
  142. Npc* getNpcByID(uint32_t id);
  143.  
  144. /**
  145. * Returns a player based on the unique creature identifier
  146. * \param id is the unique player id to get a player pointer to
  147. * \returns A Pointer to the player
  148. */
  149. Player* getPlayerByID(uint32_t id);
  150.  
  151. /**
  152. * Returns a creature based on a string name identifier
  153. * \param s is the name identifier
  154. * \returns A Pointer to the creature
  155. */
  156. Creature* getCreatureByName(const std::string& s);
  157.  
  158. /**
  159. * Returns a npc based on a string name identifier
  160. * \param s is the name identifier
  161. * \returns A Pointer to the npc
  162. */
  163. Npc* getNpcByName(const std::string& s);
  164.  
  165. /**
  166. * Returns a player based on a string name identifier
  167. * \param s is the name identifier
  168. * \returns A Pointer to the player
  169. */
  170. Player* getPlayerByName(const std::string& s);
  171.  
  172. /**
  173. * Returns a player based on guid
  174. * \returns A Pointer to the player
  175. */
  176. Player* getPlayerByGUID(const uint32_t& guid);
  177.  
  178. /**
  179. * Returns a player based on a string name identifier, with support for the "~" wildcard.
  180. * \param s is the name identifier, with or without wildcard
  181. * \param player will point to the found player (if any)
  182. * \return "RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE" or "RETURNVALUE_NAMEISTOOAMBIGUOUS"
  183. */
  184. ReturnValue getPlayerByNameWildcard(const std::string& s, Player*& player);
  185.  
  186. /**
  187. * Returns a player based on an account number identifier
  188. * \param acc is the account identifier
  189. * \returns A Pointer to the player
  190. */
  191. Player* getPlayerByAccount(uint32_t acc);
  192.  
  193. /* Place Creature on the map without sending out events to the surrounding.
  194. * \param creature Creature to place on the map
  195. * \param pos The position to place the creature
  196. * \param extendedPos If true, the creature will in first-hand be placed 2 tiles away
  197. * \param forced If true, placing the creature will not fail because of obstacles (creatures/items)
  198. */
  199. bool internalPlaceCreature(Creature* creature, const Position& pos, bool extendedPos = false, bool forced = false);
  200.  
  201. /**
  202. * Place Creature on the map.
  203. * \param creature Creature to place on the map
  204. * \param pos The position to place the creature
  205. * \param extendedPos If true, the creature will in first-hand be placed 2 tiles away
  206. * \param force If true, placing the creature will not fail because of obstacles (creatures/items)
  207. */
  208. bool placeCreature(Creature* creature, const Position& pos, bool extendedPos = false, bool force = false);
  209.  
  210. /**
  211. * Remove Creature from the map.
  212. * Removes the Creature the map
  213. * \param c Creature to remove
  214. */
  215. bool removeCreature(Creature* creature, bool isLogout = true);
  216.  
  217. void addCreatureCheck(Creature* creature);
  218. static void removeCreatureCheck(Creature* creature);
  219.  
  220. size_t getPlayersOnline() const {
  221. return players.size();
  222. }
  223. size_t getMonstersOnline() const {
  224. return monsters.size();
  225. }
  226. size_t getNpcsOnline() const {
  227. return npcs.size();
  228. }
  229. uint32_t getPlayersRecord() const {
  230. return playersRecord;
  231. }
  232.  
  233. void getWorldLightInfo(LightInfo& lightInfo) const;
  234.  
  235. ReturnValue internalMoveCreature(Creature* creature, Direction direction, uint32_t flags = 0);
  236. ReturnValue internalMoveCreature(Creature& creature, Tile& toTile, uint32_t flags = 0);
  237.  
  238. ReturnValue internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, int32_t index,
  239. Item* item, uint32_t count, Item** _moveItem, uint32_t flags = 0, Creature* actor = nullptr, Item* tradeItem = nullptr);
  240.  
  241. ReturnValue internalAddItem(Cylinder* toCylinder, Item* item, int32_t index = INDEX_WHEREEVER,
  242. uint32_t flags = 0, bool test = false);
  243. ReturnValue internalAddItem(Cylinder* toCylinder, Item* item, int32_t index,
  244. uint32_t flags, bool test, uint32_t& remainderCount);
  245. ReturnValue internalRemoveItem(Item* item, int32_t count = -1, bool test = false, uint32_t flags = 0);
  246.  
  247. ReturnValue internalPlayerAddItem(Player* player, Item* item, bool dropOnMap = true, slots_t slot = CONST_SLOT_WHEREEVER);
  248.  
  249. /**
  250. * Find an item of a certain type
  251. * \param cylinder to search the item
  252. * \param itemId is the item to remove
  253. * \param subType is the extra type an item can have such as charges/fluidtype, default is -1
  254. * meaning it's not used
  255. * \param depthSearch if true it will check child containers aswell
  256. * \returns A pointer to the item to an item and nullptr if not found
  257. */
  258. Item* findItemOfType(Cylinder* cylinder, uint16_t itemId,
  259. bool depthSearch = true, int32_t subType = -1) const;
  260.  
  261. /**
  262. * Remove/Add item(s) with a monetary value
  263. * \param cylinder to remove the money from
  264. * \param money is the amount to remove
  265. * \param flags optional flags to modifiy the default behaviour
  266. * \returns true if the removal was successful
  267. */
  268. bool removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags = 0);
  269.  
  270. /**
  271. * Add item(s) with monetary value
  272. * \param cylinder which will receive money
  273. * \param money the amount to give
  274. * \param flags optional flags to modify default behavior
  275. */
  276. void addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags = 0);
  277.  
  278. /**
  279. * Transform one item to another type/count
  280. * \param item is the item to transform
  281. * \param newId is the new itemid
  282. * \param newCount is the new count value, use default value (-1) to not change it
  283. * \returns true if the tranformation was successful
  284. */
  285. Item* transformItem(Item* item, uint16_t newId, int32_t newCount = -1);
  286.  
  287. /**
  288. * Teleports an object to another position
  289. * \param thing is the object to teleport
  290. * \param newPos is the new position
  291. * \param pushMove force teleport if false
  292. * \param flags optional flags to modify default behavior
  293. * \returns true if the teleportation was successful
  294. */
  295. ReturnValue internalTeleport(Thing* thing, const Position& newPos, bool pushMove = true, uint32_t flags = 0);
  296.  
  297. /**
  298. * Turn a creature to a different direction.
  299. * \param creature Creature to change the direction
  300. * \param dir Direction to turn to
  301. */
  302. bool internalCreatureTurn(Creature* creature, Direction dir);
  303.  
  304. /**
  305. * Creature wants to say something.
  306. * \param creature Creature pointer
  307. * \param type Type of message
  308. * \param text The text to say
  309. */
  310. bool internalCreatureSay(Creature* creature, SpeakClasses type, const std::string& text,
  311. bool ghostMode, SpectatorVec* listPtr = nullptr, const Position* pos = nullptr);
  312.  
  313. void loadPlayersRecord();
  314. void checkPlayersRecord();
  315.  
  316. void sendGuildMotd(uint32_t playerId);
  317. void kickPlayer(uint32_t playerId, bool displayEffect);
  318. void playerReportBug(uint32_t playerId, const std::string& bug);
  319. void playerDebugAssert(uint32_t playerId, const std::string& assertLine, const std::string& date, const std::string& description, const std::string& comment);
  320.  
  321. bool internalStartTrade(Player* player, Player* partner, Item* tradeItem);
  322. void internalCloseTrade(Player* player);
  323. bool playerBroadcastMessage(Player* player, const std::string& text) const;
  324. void broadcastMessage(const std::string& text, MessageClasses type) const;
  325.  
  326. //Implementation of player invoked events
  327. void playerMoveThing(uint32_t playerId, const Position& fromPos, uint16_t spriteId, uint8_t fromStackPos,
  328. const Position& toPos, uint8_t count);
  329. void playerMoveCreatureByID(uint32_t playerId, uint32_t movingCreatureId, const Position& movingCreatureOrigPos, const Position& toPos);
  330. void playerMoveCreature(Player* playerId, Creature* movingCreature, const Position& movingCreatureOrigPos, Tile* toTile);
  331. void playerMoveItemByPlayerID(uint32_t playerId, const Position& fromPos, uint16_t spriteId, uint8_t fromStackPos, const Position& toPos, uint8_t count);
  332. void playerMoveItem(Player* player, const Position& fromPos,
  333. uint16_t spriteId, uint8_t fromStackPos, const Position& toPos, uint8_t count, Item* item, Cylinder* toCylinder);
  334. void playerMove(uint32_t playerId, Direction direction);
  335. void playerCreatePrivateChannel(uint32_t playerId);
  336. void playerChannelInvite(uint32_t playerId, const std::string& name);
  337. void playerChannelExclude(uint32_t playerId, const std::string& name);
  338. void playerRequestChannels(uint32_t playerId);
  339. void playerOpenChannel(uint32_t playerId, uint16_t channelId);
  340. void playerCloseChannel(uint32_t playerId, uint16_t channelId);
  341. void playerOpenPrivateChannel(uint32_t playerId, std::string& receiver);
  342. void playerReceivePing(uint32_t playerId);
  343. void playerAutoWalk(uint32_t playerId, const std::forward_list<Direction>& listDir);
  344. void playerStopAutoWalk(uint32_t playerId);
  345. void playerUseItemEx(uint32_t playerId, const Position& fromPos, uint8_t fromStackPos,
  346. uint16_t fromSpriteId, const Position& toPos, uint8_t toStackPos, uint16_t toSpriteId);
  347. void playerUseItem(uint32_t playerId, const Position& pos, uint8_t stackPos, uint8_t index, uint16_t spriteId);
  348. void playerUseWithCreature(uint32_t playerId, const Position& fromPos, uint8_t fromStackPos, uint32_t creatureId, uint16_t spriteId);
  349. void playerCloseContainer(uint32_t playerId, uint8_t cid);
  350. void playerMoveUpContainer(uint32_t playerId, uint8_t cid);
  351. void playerUpdateContainer(uint32_t playerId, uint8_t cid);
  352. void playerRotateItem(uint32_t playerId, const Position& pos, uint8_t stackPos, const uint16_t spriteId);
  353. void playerWriteItem(uint32_t playerId, uint32_t windowTextId, const std::string& text);
  354. void playerUpdateHouseWindow(uint32_t playerId, uint8_t listId, uint32_t windowTextId, const std::string& text);
  355. void playerRequestTrade(uint32_t playerId, const Position& pos, uint8_t stackPos,
  356. uint32_t tradePlayerId, uint16_t spriteId);
  357. void playerAcceptTrade(uint32_t playerId);
  358. void playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, uint8_t index);
  359. void playerCloseTrade(uint32_t playerId);
  360. void playerSetAttackedCreature(uint32_t playerId, uint32_t creatureId);
  361. void playerFollowCreature(uint32_t playerId, uint32_t creatureId);
  362. void playerCancelAttackAndFollow(uint32_t playerId);
  363. void playerSetFightModes(uint32_t playerId, fightMode_t fightMode, chaseMode_t chaseMode, bool secureMode);
  364. void playerLookAt(uint32_t playerId, const Position& pos, uint8_t stackPos);
  365. void playerLookInBattleList(uint32_t playerId, uint32_t creatureId);
  366. void playerRequestAddVip(uint32_t playerId, const std::string& name);
  367. void playerRequestRemoveVip(uint32_t playerId, uint32_t guid);
  368. void playerTurn(uint32_t playerId, Direction dir);
  369. void playerRequestOutfit(uint32_t playerId);
  370. void playerShowQuestLog(uint32_t playerId);
  371. void playerShowQuestLine(uint32_t playerId, uint16_t questId);
  372. void playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type,
  373. const std::string& receiver, const std::string& text);
  374. void playerChangeOutfit(uint32_t playerId, Outfit_t outfit);
  375. void playerInviteToParty(uint32_t playerId, uint32_t invitedId);
  376. void playerJoinParty(uint32_t playerId, uint32_t leaderId);
  377. void playerRevokePartyInvitation(uint32_t playerId, uint32_t invitedId);
  378. void playerPassPartyLeadership(uint32_t playerId, uint32_t newLeaderId);
  379. void playerLeaveParty(uint32_t playerId);
  380. void playerEnableSharedPartyExperience(uint32_t playerId, bool sharedExpActive);
  381.  
  382. void parsePlayerExtendedOpcode(uint32_t playerId, uint8_t opcode, const std::string& buffer);
  383.  
  384. static void updatePremium(Account& account);
  385.  
  386. void cleanup();
  387. void shutdown();
  388. void ReleaseCreature(Creature* creature);
  389. void ReleaseItem(Item* item);
  390.  
  391. bool canThrowObjectTo(const Position& fromPos, const Position& toPos, bool checkLineOfSight = true,
  392. int32_t rangex = Map::maxClientViewportX, int32_t rangey = Map::maxClientViewportY) const;
  393. bool isSightClear(const Position& fromPos, const Position& toPos, bool sameFloor) const;
  394.  
  395. void changeSpeed(Creature* creature, int32_t varSpeedDelta);
  396. void internalCreatureChangeOutfit(Creature* creature, const Outfit_t& oufit);
  397. void internalCreatureChangeVisible(Creature* creature, bool visible);
  398. void changeLight(const Creature* creature);
  399. void updateCreatureSkull(const Creature* player);
  400. void updatePlayerShield(Player* player);
  401.  
  402. GameState_t getGameState() const;
  403. void setGameState(GameState_t newState);
  404. void saveGameState();
  405.  
  406. //Events
  407. void checkCreatureWalk(uint32_t creatureId);
  408. void updateCreatureWalk(uint32_t creatureId);
  409. void checkCreatureAttack(uint32_t creatureId);
  410. void checkCreatures(size_t index);
  411. void checkLight();
  412.  
  413. bool combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field);
  414.  
  415. void combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColor_t& color, uint8_t& effect);
  416.  
  417. bool combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage);
  418. bool combatChangeMana(Creature* attacker, Creature* target, int32_t manaChange, CombatOrigin origin);
  419.  
  420. //animation help functions
  421. void addCreatureHealth(const Creature* target);
  422. static void addCreatureHealth(const SpectatorVec& list, const Creature* target);
  423. void addAnimatedText(const std::string& message, const Position& pos, TextColor_t color);
  424. static void addAnimatedText(const SpectatorVec& list, const std::string& message, const Position& pos, TextColor_t color);
  425. void addMagicEffect(const Position& pos, uint16_t effect);
  426. static void addMagicEffect(const SpectatorVec& list, const Position& pos, uint16_t effect);
  427. void addDistanceEffect(const Position& fromPos, const Position& toPos, uint8_t effect);
  428. static void addDistanceEffect(const SpectatorVec& list, const Position& fromPos, const Position& toPos, uint8_t effect);
  429.  
  430. void addCommandTag(char tag);
  431. void resetCommandTag();
  432.  
  433. void startDecay(Item* item);
  434. int32_t getLightHour() const {
  435. return lightHour;
  436. }
  437.  
  438. bool loadExperienceStages();
  439. uint64_t getExperienceStage(uint32_t level);
  440.  
  441. void loadMotdNum();
  442. void saveMotdNum() const;
  443. const std::string& getMotdHash() const { return motdHash; }
  444. uint32_t getMotdNum() const { return motdNum; }
  445. void incrementMotdNum() { motdNum++; }
  446.  
  447. const std::unordered_map<uint32_t, Player*>& getPlayers() const { return players; }
  448. const std::map<uint32_t, Npc*>& getNpcs() const { return npcs; }
  449.  
  450. void addPlayer(Player* player);
  451. void removePlayer(Player* player);
  452.  
  453. void addNpc(Npc* npc);
  454. void removeNpc(Npc* npc);
  455.  
  456. void addMonster(Monster* npc);
  457. void removeMonster(Monster* npc);
  458.  
  459. Guild* getGuild(uint32_t id) const;
  460. void addGuild(Guild* guild);
  461. void removeGuild(uint32_t guildId);
  462.  
  463. void internalRemoveItems(std::vector<Item*> itemList, uint32_t amount, bool stackable);
  464.  
  465. BedItem* getBedBySleeper(uint32_t guid) const;
  466. void setBedSleeper(BedItem* bed, uint32_t guid);
  467. void removeBedSleeper(uint32_t guid);
  468.  
  469. Item* getUniqueItem(uint16_t uniqueId);
  470. bool addUniqueItem(uint16_t uniqueId, Item* item);
  471. void removeUniqueItem(uint16_t uniqueId);
  472.  
  473. Groups groups;
  474. Map map;
  475. Raids raids;
  476. Quests quests;
  477.  
  478. protected:
  479. bool playerSayCommand(Player* player, const std::string& text);
  480. bool playerSaySpell(Player* player, SpeakClasses type, const std::string& text);
  481. void playerWhisper(Player* player, const std::string& text);
  482. bool playerYell(Player* player, const std::string& text);
  483. bool playerSpeakTo(Player* player, SpeakClasses type, const std::string& receiver, const std::string& text);
  484.  
  485. void checkDecay();
  486. void internalDecayItem(Item* item);
  487.  
  488. std::unordered_map<uint32_t, Player*> players;
  489. std::unordered_map<std::string, Player*> mappedPlayerNames;
  490. std::unordered_map<uint32_t, Player*> mappedPlayerGuids;
  491. std::unordered_map<uint32_t, Guild*> guilds;
  492. std::unordered_map<uint16_t, Item*> uniqueItems;
  493. std::map<uint32_t, uint32_t> stages;
  494.  
  495. std::list<Item*> decayItems[EVENT_DECAY_BUCKETS];
  496. std::list<Creature*> checkCreatureLists[EVENT_CREATURECOUNT];
  497.  
  498. std::forward_list<Item*> toDecayItems;
  499.  
  500. std::vector<Creature*> ToReleaseCreatures;
  501. std::vector<Item*> ToReleaseItems;
  502. std::vector<char> commandTags;
  503.  
  504. size_t lastBucket;
  505.  
  506. WildcardTreeNode wildcardTree;
  507.  
  508. std::map<uint32_t, Npc*> npcs;
  509. std::map<uint32_t, Monster*> monsters;
  510.  
  511. //list of items that are in trading state, mapped to the player
  512. std::map<Item*, uint32_t> tradeItems;
  513.  
  514. std::map<uint32_t, BedItem*> bedSleepersMap;
  515.  
  516. Commands commands;
  517.  
  518. static const int32_t LIGHT_LEVEL_DAY = 250;
  519. static const int32_t LIGHT_LEVEL_NIGHT = 40;
  520. static const int32_t SUNSET = 1305;
  521. static const int32_t SUNRISE = 430;
  522.  
  523. GameState_t gameState;
  524. WorldType_t worldType;
  525.  
  526. LightState_t lightState;
  527. uint8_t lightLevel;
  528. int32_t lightHour;
  529. int32_t lightHourDelta;
  530.  
  531. ServiceManager* serviceManager;
  532.  
  533. void updatePlayersRecord() const;
  534. uint32_t playersRecord;
  535.  
  536. std::string motdHash;
  537. uint32_t motdNum;
  538.  
  539. uint32_t lastStageLevel;
  540. bool stagesEnabled;
  541. bool useLastStageLevel;
  542. std::vector<uint32_t> noExhaust = { 3081, 3088 };
  543. };
  544.  
  545. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement