tron@2186: /* $Id$ */ tron@2186: glx@9505: /** @file player.h */ glx@9505: truelight@0: #ifndef PLAYER_H truelight@0: #define PLAYER_H truelight@0: matthijs@5216: #include "oldpool.h" truelight@84: #include "aystar.h" celestar@2147: #include "rail.h" peter1138@2573: #include "engine.h" peter1138@4603: #include "livery.h" truelight@84: rubidium@6574: struct PlayerEconomyEntry { truelight@0: int32 income; truelight@0: int32 expenses; truelight@0: int32 delivered_cargo; glx@9505: int32 performance_history; ///< player score (scale 0-1000) truelight@200: int64 company_value; rubidium@6574: }; truelight@0: rubidium@6516: typedef uint32 PlayerFace; truelight@84: rubidium@9374: enum { rubidium@9374: /** The stepping in pounds for loans */ rubidium@9374: LOAN_INTERVAL = 10000, rubidium@9374: }; rubidium@9374: rubidium@6574: struct Player { truelight@0: uint32 name_2; truelight@0: uint16 name_1; truelight@0: truelight@0: uint16 president_name_1; truelight@0: uint32 president_name_2; truelight@0: rubidium@6516: PlayerFace face; truelight@0: truelight@0: int32 player_money; truelight@0: int32 current_loan; glx@9505: int64 money64; ///< internal 64-bit version of the money. the 32-bit field will be clamped to plus minus 2 billion truelight@0: truelight@0: byte player_color; peter1138@4603: Livery livery[LS_END]; truelight@0: byte player_money_fraction; celestar@2147: byte avail_railtypes; rubidium@9625: byte avail_roadtypes; truelight@0: byte block_preview; rubidium@5838: PlayerByte index; truelight@0: glx@9505: uint16 cargo_types; ///< which cargo types were transported the last year truelight@0: truelight@0: TileIndex location_of_house; truelight@0: TileIndex last_build_coordinate; truelight@145: rubidium@5838: PlayerByte share_owners[4]; truelight@145: rubidium@4326: Year inaugurated_year; truelight@0: byte num_valid_stat_ent; truelight@145: truelight@0: byte quarters_of_bankrupcy; glx@9505: byte bankrupt_asked; ///< which players were asked about buying it? truelight@0: int16 bankrupt_timeout; truelight@0: int32 bankrupt_value; truelight@0: truelight@0: bool is_active; Darkvater@3345: bool is_ai; rubidium@9598: bool is_noai; ///< This is a NoAI player (for loading old savegames properly). Part of the NoAI 'hack' to retain savegame compatability with trunk. truelight@145: truelight@0: int64 yearly_expenses[3][13]; truelight@0: PlayerEconomyEntry cur_economy; truelight@0: PlayerEconomyEntry old_economy[24]; glx@9505: EngineRenewList engine_renew_list; ///< Defined later bjarni@2293: bool engine_renew; bjarni@2617: bool renew_keep_length; bjarni@2293: int16 engine_renew_months; bjarni@2293: uint32 engine_renew_money; glx@9505: uint16 num_engines[TOTAL_NUM_ENGINES]; ///< caches the number of engines of each type the player owns (no need to save this) rubidium@6574: }; truelight@0: tron@4428: uint16 GetDrawStringPlayerColor(PlayerID player); tron@4428: Darkvater@2436: void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player); Darkvater@4849: void GetNameOfOwner(Owner owner, TileIndex tile); tron@2475: int64 CalculateCompanyValue(const Player* p); tron@2475: void InvalidatePlayerWindows(const Player* p); truelight@0: void UpdatePlayerMoney32(Player *p); rubidium@5564: void SetLocalPlayer(PlayerID new_player); tron@2952: #define FOR_ALL_PLAYERS(p) for (p = _players; p != endof(_players); p++) truelight@0: Darkvater@2425: VARDEF PlayerID _local_player; Darkvater@2425: VARDEF PlayerID _current_player; tron@2154: truelight@0: VARDEF Player _players[MAX_PLAYERS]; glx@9505: /* NOSAVE: can be determined from player structs */ tron@2154: VARDEF byte _player_colors[MAX_PLAYERS]; truelight@0: rubidium@6573: static inline byte ActivePlayerCount() Darkvater@4824: { Darkvater@4824: const Player *p; Darkvater@4824: byte count = 0; Darkvater@4824: Darkvater@4824: FOR_ALL_PLAYERS(p) { Darkvater@4824: if (p->is_active) count++; Darkvater@4824: } Darkvater@4824: Darkvater@4824: return count; Darkvater@4824: } Darkvater@2944: Darkvater@2436: static inline Player* GetPlayer(PlayerID i) tron@1767: { KUDr@5980: assert(IS_INSIDE_1D(i, PLAYER_FIRST, lengthof(_players))); Darkvater@2425: return &_players[i]; Darkvater@2425: } Darkvater@2425: rubidium@6573: static inline bool IsLocalPlayer() Darkvater@2425: { Darkvater@2425: return _local_player == _current_player; tron@1767: } tron@1767: Darkvater@4850: static inline bool IsValidPlayer(PlayerID pi) Darkvater@4850: { KUDr@5980: return IS_INSIDE_1D(pi, PLAYER_FIRST, MAX_PLAYERS); Darkvater@4850: } Darkvater@4850: tron@2544: byte GetPlayerRailtypes(PlayerID p); rubidium@9625: byte GetPlayerRoadtypes(PlayerID p); celestar@2147: rubidium@4549: /** Finds out if a Player has a certain railtype available */ Darkvater@2436: static inline bool HasRailtypeAvail(const Player *p, RailType Railtype) celestar@2147: { celestar@2147: return HASBIT(p->avail_railtypes, Railtype); celestar@2147: } celestar@2147: Darkvater@4845: static inline bool IsHumanPlayer(PlayerID pi) Darkvater@4845: { Darkvater@4845: return !GetPlayer(pi)->is_ai; Darkvater@4845: } Darkvater@4845: Darkvater@4845: static inline bool IsInteractivePlayer(PlayerID pi) Darkvater@4845: { Darkvater@4845: return pi == _local_player; Darkvater@4845: } Darkvater@4845: maedhros@6001: void DrawPlayerIcon(PlayerID p, int x, int y); maedhros@6001: tron@2154: /* Validate functions for rail building */ tron@2154: static inline bool ValParamRailtype(uint32 rail) { return HASBIT(GetPlayer(_current_player)->avail_railtypes, rail);} tron@2154: celestar@2147: /** Returns the "best" railtype a player can build. tron@4077: * As the AI doesn't know what the BEST one is, we have our own priority list tron@4077: * here. When adding new railtypes, modify this function tron@4077: * @param p the player "in action" tron@4077: * @return The "best" railtype a player has available tron@4077: */ tron@2520: static inline RailType GetBestRailtype(const Player* p) celestar@2147: { celestar@2147: if (HasRailtypeAvail(p, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV; celestar@2147: if (HasRailtypeAvail(p, RAILTYPE_MONO)) return RAILTYPE_MONO; celestar@3355: if (HasRailtypeAvail(p, RAILTYPE_ELECTRIC)) return RAILTYPE_ELECTRIC; celestar@2147: return RAILTYPE_RAIL; celestar@2147: } celestar@2147: rubidium@6574: struct HighScore { darkvater@983: char company[100]; glx@9505: StringID title; ///< NO_SAVE, has troubles with changing string-numbers. glx@9505: uint16 score; ///< do NOT change type, will break hs.dat rubidium@6574: }; darkvater@983: darkvater@998: VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5 rubidium@6573: void SaveToHighScore(); rubidium@6573: void LoadFromHighScore(); darkvater@998: int8 SaveHighScoreValue(const Player *p); rubidium@6573: int8 SaveHighScoreValueNetwork(); darkvater@983: peter1138@2848: /* Engine Replacement Functions */ peter1138@2848: peter1138@2848: /** peter1138@2848: * Remove all engine replacement settings for the given player. peter1138@2848: * @param p Player. peter1138@2848: */ peter1138@2848: static inline void RemoveAllEngineReplacementForPlayer(Player *p) { RemoveAllEngineReplacement(&p->engine_renew_list); } peter1138@2848: peter1138@2848: /** peter1138@2848: * Retrieve the engine replacement for the given player and original engine type. peter1138@2848: * @param p Player. peter1138@2848: * @param engine Engine type. peter1138@2848: * @return The engine type to replace with, or INVALID_ENGINE if no peter1138@2848: * replacement is in the list. peter1138@2848: */ glx@9624: static inline EngineID EngineReplacementForPlayer(const Player *p, EngineID engine, GroupID group) { return EngineReplacement(p->engine_renew_list, engine, group); } peter1138@2848: peter1138@2848: /** peter1138@2848: * Check if a player has a replacement set up for the given engine. peter1138@2848: * @param p Player. peter1138@2848: * @param engine Engine type to be replaced. peter1138@2848: * @return true if a replacement was set up, false otherwise. peter1138@2848: */ glx@9624: static inline bool EngineHasReplacementForPlayer(const Player *p, EngineID engine, GroupID group) { return EngineReplacementForPlayer(p, engine, group) != INVALID_ENGINE; } peter1138@2848: peter1138@2848: /** peter1138@2848: * Add an engine replacement for the player. peter1138@2848: * @param p Player. peter1138@2848: * @param old_engine The original engine type. peter1138@2848: * @param new_engine The replacement engine type. peter1138@2848: * @param flags The calling command flags. peter1138@2848: * @return 0 on success, CMD_ERROR on failure. peter1138@2848: */ glx@9624: static inline int32 AddEngineReplacementForPlayer(Player *p, EngineID old_engine, EngineID new_engine, GroupID group, uint32 flags) { return AddEngineReplacement(&p->engine_renew_list, old_engine, new_engine, group, flags); } peter1138@2848: peter1138@2848: /** peter1138@2848: * Remove an engine replacement for the player. peter1138@2848: * @param p Player. peter1138@2848: * @param engine The original engine type. peter1138@2848: * @param flags The calling command flags. peter1138@2848: * @return 0 on success, CMD_ERROR on failure. peter1138@2848: */ glx@9624: static inline int32 RemoveEngineReplacementForPlayer(Player *p, EngineID engine, GroupID group, uint32 flags) {return RemoveEngineReplacement(&p->engine_renew_list, engine, group, flags); } peter1138@2697: peter1138@4603: /** peter1138@4603: * Reset the livery schemes to the player's primary colour. peter1138@4603: * This is used on loading games without livery information and on new player start up. peter1138@4603: * @param p Player to reset. peter1138@4603: */ peter1138@4603: void ResetPlayerLivery(Player *p); peter1138@4603: truelight@0: #endif /* PLAYER_H */