tron@2186: /* $Id$ */ tron@2186: truelight@0: #ifndef PLAYER_H truelight@0: #define PLAYER_H truelight@0: truelight@84: #include "aystar.h" celestar@2147: #include "rail.h" peter1138@2573: #include "engine.h" truelight@84: truelight@0: typedef struct PlayerEconomyEntry { truelight@0: int32 income; truelight@0: int32 expenses; truelight@0: int32 delivered_cargo; darkvater@147: int32 performance_history; // player score (scale 0-1000) truelight@200: int64 company_value; truelight@0: } PlayerEconomyEntry; truelight@0: truelight@0: typedef struct AiBuildRec { truelight@0: TileIndex spec_tile; truelight@0: TileIndex use_tile; truelight@0: byte rand_rng; truelight@0: byte cur_building_rule; truelight@0: byte unk6; truelight@0: byte unk7; truelight@0: byte buildcmd_a; truelight@0: byte buildcmd_b; truelight@0: byte direction; truelight@0: byte cargo; truelight@0: } AiBuildRec; truelight@0: truelight@0: typedef struct PlayerAI { truelight@0: byte state; truelight@0: byte tick; // Used to determine how often to move pasky@1576: uint32 state_counter; // Can hold tile index! truelight@0: uint16 timeout_counter; truelight@0: truelight@0: byte state_mode; truelight@0: byte banned_tile_count; truelight@0: byte railtype_to_use; truelight@0: truelight@0: byte cargo_type; truelight@0: byte num_wagons; truelight@0: byte build_kind; truelight@0: byte num_build_rec; truelight@0: byte num_loco_to_build; truelight@0: byte num_want_fullload; truelight@0: truelight@0: byte route_type_mask; truelight@0: truelight@0: TileIndex start_tile_a; truelight@0: TileIndex cur_tile_a; truelight@0: byte cur_dir_a; truelight@0: byte start_dir_a; truelight@145: truelight@0: TileIndex start_tile_b; truelight@0: TileIndex cur_tile_b; truelight@0: byte cur_dir_b; truelight@0: byte start_dir_b; truelight@0: truelight@0: Vehicle *cur_veh; /* only used by some states */ truelight@145: truelight@0: AiBuildRec src, dst, mid1, mid2; truelight@145: truelight@0: VehicleID wagon_list[9]; truelight@0: byte order_list_blocks[20]; truelight@145: truelight@0: TileIndex banned_tiles[16]; truelight@0: byte banned_val[16]; truelight@0: } PlayerAI; truelight@0: truelight@84: typedef struct Ai_PathFinderInfo { truelight@84: TileIndex start_tile_tl; // tl = top-left truelight@84: TileIndex start_tile_br; // br = bottom-right truelight@84: TileIndex end_tile_tl; // tl = top-left truelight@84: TileIndex end_tile_br; // br = bottom-right truelight@84: byte start_direction; // 0 to 3 or AI_PATHFINDER_NO_DIRECTION truelight@84: byte end_direction; // 0 to 3 or AI_PATHFINDER_NO_DIRECTION truelight@84: truelight@84: TileIndex route[500]; truelight@84: byte route_extra[500]; // Some extra information about the route like bridge/tunnel truelight@84: int route_length; truelight@84: int position; // Current position in the build-path, needed to build the path truelight@145: truelight@84: bool rail_or_road; // true = rail, false = road truelight@84: } Ai_PathFinderInfo; truelight@84: truelight@145: // The amount of memory reserved for the AI-special-vehicles truelight@145: #define AI_MAX_SPECIAL_VEHICLES 100 truelight@145: truelight@145: typedef struct Ai_SpecialVehicle { truelight@145: VehicleID veh_id; truelight@145: uint32 flag; truelight@145: } Ai_SpecialVehicle; truelight@145: truelight@84: typedef struct PlayerAiNew { truelight@84: uint8 state; truelight@84: uint tick; truelight@84: uint idle; truelight@145: miham@826: int temp; // A value used in more than one function, but it just temporary truelight@84: // The use is pretty simple: with this we can 'think' about stuff miham@826: // in more than one tick, and more than one AI. A static will not truelight@84: // do, because they are not saved. This way, the AI is almost human ;) truelight@84: int counter; // For the same reason as temp, we have counter. It can count how truelight@84: // long we are trying something, and just abort if it takes too long truelight@145: truelight@84: // Pathfinder stuff truelight@84: Ai_PathFinderInfo path_info; truelight@84: AyStar *pathfinder; truelight@145: truelight@84: // Route stuff truelight@145: truelight@84: byte cargo; truelight@84: byte tbt; // train/bus/truck 0/1/2 AI_TRAIN/AI_BUS/AI_TRUCK truelight@84: int new_cost; truelight@145: truelight@84: byte action; truelight@145: truelight@990: int last_id; // here is stored the last id of the searched city/industry truelight@145: uint last_vehiclecheck_date; // Used in CheckVehicle truelight@145: Ai_SpecialVehicle special_vehicles[AI_MAX_SPECIAL_VEHICLES]; // Some vehicles have some special flags truelight@145: truelight@84: TileIndex from_tile; truelight@84: TileIndex to_tile; truelight@145: truelight@84: byte from_direction; truelight@84: byte to_direction; truelight@145: truelight@84: bool from_deliver; // True if this is the station that GIVES cargo truelight@84: bool to_deliver; truelight@145: truelight@84: TileIndex depot_tile; truelight@84: byte depot_direction; truelight@145: truelight@84: byte amount_veh; // How many vehicles we are going to build in this route truelight@84: byte cur_veh; // How many vehicles did we bought? truelight@84: VehicleID veh_id; // Used when bought a vehicle truelight@84: VehicleID veh_main_id; // The ID of the first vehicle, for shared copy truelight@145: truelight@84: int from_ic; // ic = industry/city. This is the ID of them truelight@84: byte from_type; // AI_NO_TYPE/AI_CITY/AI_INDUSTRY truelight@84: int to_ic; truelight@84: byte to_type; truelight@145: truelight@84: } PlayerAiNew; truelight@84: truelight@84: truelight@84: truelight@0: typedef 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: truelight@0: uint32 face; truelight@0: truelight@0: int32 player_money; truelight@0: int32 current_loan; truelight@0: 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; truelight@0: byte player_money_fraction; celestar@2147: byte avail_railtypes; truelight@0: byte block_preview; Darkvater@1786: PlayerID index; truelight@0: truelight@0: 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: Darkvater@2436: PlayerID share_owners[4]; truelight@145: truelight@0: byte inaugurated_year; truelight@0: byte num_valid_stat_ent; truelight@145: truelight@0: byte quarters_of_bankrupcy; truelight@0: 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; truelight@0: byte is_ai; truelight@0: PlayerAI ai; truelight@84: PlayerAiNew ainew; truelight@145: truelight@0: int64 yearly_expenses[3][13]; truelight@0: PlayerEconomyEntry cur_economy; truelight@0: PlayerEconomyEntry old_economy[24]; peter1138@2573: EngineID engine_replacement[TOTAL_NUM_ENGINES]; bjarni@2293: bool engine_renew; bjarni@2617: bool renew_keep_length; bjarni@2293: int16 engine_renew_months; bjarni@2293: uint32 engine_renew_money; truelight@0: } Player; truelight@0: Darkvater@2436: void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player); Darkvater@2436: void GetNameOfOwner(PlayerID owner, TileIndex tile); tron@2475: int64 CalculateCompanyValue(const Player* p); tron@2475: void InvalidatePlayerWindows(const Player* p); truelight@0: void UpdatePlayerMoney32(Player *p); truelight@0: #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: #define MAX_PLAYERS 8 truelight@0: VARDEF Player _players[MAX_PLAYERS]; tron@2154: // NOSAVE: can be determined from player structs tron@2154: VARDEF byte _player_colors[MAX_PLAYERS]; truelight@0: Darkvater@2436: static inline Player* GetPlayer(PlayerID i) tron@1767: { Darkvater@2425: assert(i < lengthof(_players)); Darkvater@2425: return &_players[i]; Darkvater@2425: } Darkvater@2425: Darkvater@2425: static inline bool IsLocalPlayer(void) Darkvater@2425: { Darkvater@2425: return _local_player == _current_player; tron@1767: } tron@1767: tron@2544: void DeletePlayerWindows(PlayerID pi); tron@2544: byte GetPlayerRailtypes(PlayerID p); celestar@2147: celestar@2147: /** Finds out if a Player has a certain railtype available celestar@2147: */ 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: 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. celestar@2147: * As the AI doesn't know what the BEST one is, we celestar@2147: * have our own priority list here. When adding celestar@2147: * new railtypes, modify this function celestar@2147: * @param p the player "in action" celestar@2147: * @return The "best" railtype a player has available celestar@2147: */ 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@2147: return RAILTYPE_RAIL; celestar@2147: } celestar@2147: tron@2475: #define IS_HUMAN_PLAYER(p) (!GetPlayer(p)->is_ai) tron@2475: #define IS_INTERACTIVE_PLAYER(p) ((p) == _local_player) truelight@0: darkvater@983: typedef struct HighScore { darkvater@983: char company[100]; Darkvater@2613: StringID title; // NO_SAVE, has troubles with changing string-numbers. Darkvater@2613: uint16 score; // do NOT change type, will break hs.dat darkvater@983: } HighScore; darkvater@983: darkvater@998: VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5 darkvater@983: void SaveToHighScore(void); darkvater@983: void LoadFromHighScore(void); darkvater@998: int8 SaveHighScoreValue(const Player *p); darkvater@998: int8 SaveHighScoreValueNetwork(void); darkvater@983: peter1138@2697: void InitialiseEngineReplacement(Player *p); peter1138@2697: EngineID EngineReplacement(const Player *p, EngineID engine); peter1138@2697: bool EngineHasReplacement(const Player *p, EngineID engine); peter1138@2697: truelight@0: #endif /* PLAYER_H */