mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-09 07:29:44 +00:00
(svn r11792) -Codechange: move some (virtually) globally included AI related structs to a place where they are only included a few times.
This commit is contained in:
parent
a27a240b87
commit
b4337eba83
@ -2,6 +2,7 @@
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../openttd.h"
|
||||
#include "../player.h"
|
||||
#include "../variables.h"
|
||||
#include "../command_func.h"
|
||||
#include "../network/network.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,5 +4,61 @@
|
||||
#define DEFAULT_H
|
||||
|
||||
void AiDoGameLoop(Player*);
|
||||
void SaveLoad_AI(PlayerID id);
|
||||
|
||||
struct AiBuildRec {
|
||||
TileIndex spec_tile;
|
||||
TileIndex use_tile;
|
||||
byte rand_rng;
|
||||
byte cur_building_rule;
|
||||
byte unk6;
|
||||
byte unk7;
|
||||
byte buildcmd_a;
|
||||
byte buildcmd_b;
|
||||
byte direction;
|
||||
CargoID cargo;
|
||||
};
|
||||
|
||||
struct PlayerAI {
|
||||
byte state;
|
||||
byte tick; ///< Used to determine how often to move
|
||||
uint32 state_counter; ///< Can hold tile index!
|
||||
uint16 timeout_counter;
|
||||
|
||||
byte state_mode;
|
||||
byte banned_tile_count;
|
||||
RailTypeByte railtype_to_use;
|
||||
|
||||
CargoID cargo_type;
|
||||
byte num_wagons;
|
||||
byte build_kind;
|
||||
byte num_build_rec;
|
||||
byte num_loco_to_build;
|
||||
byte num_want_fullload;
|
||||
|
||||
byte route_type_mask;
|
||||
|
||||
TileIndex start_tile_a;
|
||||
TileIndex cur_tile_a;
|
||||
DiagDirectionByte cur_dir_a;
|
||||
DiagDirectionByte start_dir_a;
|
||||
|
||||
TileIndex start_tile_b;
|
||||
TileIndex cur_tile_b;
|
||||
DiagDirectionByte cur_dir_b;
|
||||
DiagDirectionByte start_dir_b;
|
||||
|
||||
Vehicle *cur_veh; ///< only used by some states
|
||||
|
||||
AiBuildRec src, dst, mid1, mid2;
|
||||
|
||||
VehicleID wagon_list[9];
|
||||
byte order_list_blocks[20];
|
||||
|
||||
TileIndex banned_tiles[16];
|
||||
byte banned_val[16];
|
||||
};
|
||||
|
||||
extern PlayerAI _players_ai[MAX_PLAYERS];
|
||||
|
||||
#endif
|
||||
|
@ -70,7 +70,7 @@ CommandCost AiNew_Build_Bridge(Player *p, TileIndex tile_a, TileIndex tile_b, by
|
||||
if (type2 == 0 && type != 0) type2 = type;
|
||||
|
||||
// Now, simply, build the bridge!
|
||||
if (p->ainew.tbt == AI_TRAIN) {
|
||||
if (_players_ainew[p->index].tbt == AI_TRAIN) {
|
||||
return AI_DoCommand(tile_a, tile_b, (0x00 << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
|
||||
} else {
|
||||
return AI_DoCommand(tile_a, tile_b, ((0x80 | ROADTYPES_ROAD) << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
|
||||
@ -144,7 +144,7 @@ CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo,
|
||||
res = AI_DoCommand(route[part], 0, dir, flag, CMD_BUILD_SINGLE_RAIL);
|
||||
if (CmdFailed(res)) {
|
||||
// Problem.. let's just abort it all!
|
||||
p->ainew.state = AI_STATE_NOTHING;
|
||||
_players_ainew[p->index].state = AI_STATE_NOTHING;
|
||||
return CommandCost();
|
||||
}
|
||||
cost.AddCost(res);
|
||||
@ -200,7 +200,7 @@ CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo,
|
||||
if (CmdFailed(res) && flag == DC_EXEC && !IsTileType(route[part], MP_ROAD) && !EnsureNoVehicleOnGround(route[part])) {
|
||||
// Problem.. let's just abort it all!
|
||||
DEBUG(ai, 0, "[BuidPath] route building failed at tile 0x%X, aborting", route[part]);
|
||||
p->ainew.state = AI_STATE_NOTHING;
|
||||
_players_ainew[p->index].state = AI_STATE_NOTHING;
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo,
|
||||
// It returns INVALID_ENGINE if not suitable engine is found
|
||||
EngineID AiNew_PickVehicle(Player *p)
|
||||
{
|
||||
if (p->ainew.tbt == AI_TRAIN) {
|
||||
if (_players_ainew[p->index].tbt == AI_TRAIN) {
|
||||
// Not supported yet
|
||||
return INVALID_ENGINE;
|
||||
} else {
|
||||
@ -244,7 +244,7 @@ EngineID AiNew_PickVehicle(Player *p)
|
||||
CommandCost ret;
|
||||
|
||||
/* Skip vehicles which can't take our cargo type */
|
||||
if (rvi->cargo_type != p->ainew.cargo && !CanRefitTo(i, p->ainew.cargo)) continue;
|
||||
if (rvi->cargo_type != _players_ainew[p->index].cargo && !CanRefitTo(i, _players_ainew[p->index].cargo)) continue;
|
||||
|
||||
// Is it availiable?
|
||||
// Also, check if the reliability of the vehicle is above the AI_VEHICLE_MIN_RELIABILTY
|
||||
@ -272,20 +272,20 @@ void CcAI(bool success, TileIndex tile, uint32 p1, uint32 p2)
|
||||
Player* p = GetPlayer(_current_player);
|
||||
|
||||
if (success) {
|
||||
p->ainew.state = AI_STATE_GIVE_ORDERS;
|
||||
p->ainew.veh_id = _new_vehicle_id;
|
||||
_players_ainew[p->index].state = AI_STATE_GIVE_ORDERS;
|
||||
_players_ainew[p->index].veh_id = _new_vehicle_id;
|
||||
|
||||
if (GetVehicle(p->ainew.veh_id)->cargo_type != p->ainew.cargo) {
|
||||
if (GetVehicle(_players_ainew[p->index].veh_id)->cargo_type != _players_ainew[p->index].cargo) {
|
||||
/* Cargo type doesn't match, so refit it */
|
||||
if (CmdFailed(DoCommand(tile, p->ainew.veh_id, p->ainew.cargo, DC_EXEC, CMD_REFIT_ROAD_VEH))) {
|
||||
if (CmdFailed(DoCommand(tile, _players_ainew[p->index].veh_id, _players_ainew[p->index].cargo, DC_EXEC, CMD_REFIT_ROAD_VEH))) {
|
||||
/* Refit failed, so sell the vehicle */
|
||||
DoCommand(tile, p->ainew.veh_id, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
|
||||
p->ainew.state = AI_STATE_NOTHING;
|
||||
DoCommand(tile, _players_ainew[p->index].veh_id, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
|
||||
_players_ainew[p->index].state = AI_STATE_NOTHING;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* XXX this should be handled more gracefully */
|
||||
p->ainew.state = AI_STATE_NOTHING;
|
||||
_players_ainew[p->index].state = AI_STATE_NOTHING;
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,7 +296,7 @@ CommandCost AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
|
||||
EngineID i = AiNew_PickVehicle(p);
|
||||
|
||||
if (i == INVALID_ENGINE) return CMD_ERROR;
|
||||
if (p->ainew.tbt == AI_TRAIN) return CMD_ERROR;
|
||||
if (_players_ainew[p->index].tbt == AI_TRAIN) return CMD_ERROR;
|
||||
|
||||
if (flag & DC_EXEC) {
|
||||
return AI_DoCommandCc(tile, i, 0, flag, CMD_BUILD_ROAD_VEH, CcAI);
|
||||
@ -308,7 +308,7 @@ CommandCost AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
|
||||
CommandCost AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction, byte flag)
|
||||
{
|
||||
CommandCost ret, ret2;
|
||||
if (p->ainew.tbt == AI_TRAIN) {
|
||||
if (_players_ainew[p->index].tbt == AI_TRAIN) {
|
||||
return AI_DoCommand(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
|
||||
} else {
|
||||
ret = AI_DoCommand(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
|
||||
|
@ -27,14 +27,14 @@ static bool TestCanBuildStationHere(TileIndex tile, byte dir)
|
||||
// TODO: currently we only allow spots that can be access from al 4 directions...
|
||||
// should be fixed!!!
|
||||
for (dir = 0; dir < 4; dir++) {
|
||||
ret = AiNew_Build_Station(p, p->ainew.tbt, tile, 1, 1, dir, DC_QUERY_COST);
|
||||
ret = AiNew_Build_Station(p, _players_ainew[p->index].tbt, tile, 1, 1, dir, DC_QUERY_COST);
|
||||
if (CmdSucceeded(ret)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// return true if command succeeded, so the inverse of CmdFailed()
|
||||
return CmdSucceeded(AiNew_Build_Station(p, p->ainew.tbt, tile, 1, 1, dir, DC_QUERY_COST));
|
||||
return CmdSucceeded(AiNew_Build_Station(p, _players_ainew[p->index].tbt, tile, 1, 1, dir, DC_QUERY_COST));
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,8 +80,8 @@ uint AiNew_GetSpecialVehicleFlag(Player* p, Vehicle* v)
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < AI_MAX_SPECIAL_VEHICLES; i++) {
|
||||
if (p->ainew.special_vehicles[i].veh_id == v->index) {
|
||||
return p->ainew.special_vehicles[i].flag;
|
||||
if (_players_ainew[p->index].special_vehicles[i].veh_id == v->index) {
|
||||
return _players_ainew[p->index].special_vehicles[i].flag;
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,13 +96,13 @@ bool AiNew_SetSpecialVehicleFlag(Player* p, Vehicle* v, uint flag)
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < AI_MAX_SPECIAL_VEHICLES; i++) {
|
||||
if (p->ainew.special_vehicles[i].veh_id == v->index) {
|
||||
p->ainew.special_vehicles[i].flag |= flag;
|
||||
if (_players_ainew[p->index].special_vehicles[i].veh_id == v->index) {
|
||||
_players_ainew[p->index].special_vehicles[i].flag |= flag;
|
||||
return true;
|
||||
}
|
||||
if (new_id == -1 &&
|
||||
p->ainew.special_vehicles[i].veh_id == 0 &&
|
||||
p->ainew.special_vehicles[i].flag == 0) {
|
||||
_players_ainew[p->index].special_vehicles[i].veh_id == 0 &&
|
||||
_players_ainew[p->index].special_vehicles[i].flag == 0) {
|
||||
new_id = i;
|
||||
}
|
||||
}
|
||||
@ -112,7 +112,7 @@ bool AiNew_SetSpecialVehicleFlag(Player* p, Vehicle* v, uint flag)
|
||||
DEBUG(ai, 1, "special_vehicles list is too small");
|
||||
return false;
|
||||
}
|
||||
p->ainew.special_vehicles[new_id].veh_id = v->index;
|
||||
p->ainew.special_vehicles[new_id].flag = flag;
|
||||
_players_ainew[p->index].special_vehicles[new_id].veh_id = v->index;
|
||||
_players_ainew[p->index].special_vehicles[new_id].flag = flag;
|
||||
return true;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -239,6 +239,22 @@ typedef void AiNew_StateFunction(Player *p);
|
||||
// ai_new.c
|
||||
void AiNewDoGameLoop(Player *p);
|
||||
|
||||
struct Ai_PathFinderInfo {
|
||||
TileIndex start_tile_tl; ///< tl = top-left
|
||||
TileIndex start_tile_br; ///< br = bottom-right
|
||||
TileIndex end_tile_tl; ///< tl = top-left
|
||||
TileIndex end_tile_br; ///< br = bottom-right
|
||||
DiagDirection start_direction; ///< 0 to 3 or AI_PATHFINDER_NO_DIRECTION
|
||||
DiagDirection end_direction; ///< 0 to 3 or AI_PATHFINDER_NO_DIRECTION
|
||||
|
||||
TileIndex route[500];
|
||||
byte route_extra[500]; ///< Some extra information about the route like bridge/tunnel
|
||||
int route_length;
|
||||
int position; ///< Current position in the build-path, needed to build the path
|
||||
|
||||
bool rail_or_road; ///< true = rail, false = road
|
||||
};
|
||||
|
||||
// ai_pathfinder.c
|
||||
AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo);
|
||||
void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo);
|
||||
@ -259,4 +275,64 @@ EngineID AiNew_PickVehicle(Player *p);
|
||||
CommandCost AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag);
|
||||
CommandCost AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction, byte flag);
|
||||
|
||||
/* The amount of memory reserved for the AI-special-vehicles */
|
||||
#define AI_MAX_SPECIAL_VEHICLES 100
|
||||
|
||||
struct Ai_SpecialVehicle {
|
||||
VehicleID veh_id;
|
||||
uint32 flag;
|
||||
};
|
||||
|
||||
struct PlayerAiNew {
|
||||
uint8 state;
|
||||
uint tick;
|
||||
uint idle;
|
||||
|
||||
int temp; ///< A value used in more than one function, but it just temporary
|
||||
///< The use is pretty simple: with this we can 'think' about stuff
|
||||
///< in more than one tick, and more than one AI. A static will not
|
||||
///< do, because they are not saved. This way, the AI is almost human ;)
|
||||
int counter; ///< For the same reason as temp, we have counter. It can count how
|
||||
///< long we are trying something, and just abort if it takes too long
|
||||
|
||||
/* Pathfinder stuff */
|
||||
Ai_PathFinderInfo path_info;
|
||||
AyStar *pathfinder;
|
||||
|
||||
/* Route stuff */
|
||||
|
||||
CargoID cargo;
|
||||
byte tbt; ///< train/bus/truck 0/1/2 AI_TRAIN/AI_BUS/AI_TRUCK
|
||||
Money new_cost;
|
||||
|
||||
byte action;
|
||||
|
||||
int last_id; ///< here is stored the last id of the searched city/industry
|
||||
Date last_vehiclecheck_date; // Used in CheckVehicle
|
||||
Ai_SpecialVehicle special_vehicles[AI_MAX_SPECIAL_VEHICLES]; ///< Some vehicles have some special flags
|
||||
|
||||
TileIndex from_tile;
|
||||
TileIndex to_tile;
|
||||
|
||||
DiagDirectionByte from_direction;
|
||||
DiagDirectionByte to_direction;
|
||||
|
||||
bool from_deliver; ///< True if this is the station that GIVES cargo
|
||||
bool to_deliver;
|
||||
|
||||
TileIndex depot_tile;
|
||||
DiagDirectionByte depot_direction;
|
||||
|
||||
byte amount_veh; ///< How many vehicles we are going to build in this route
|
||||
byte cur_veh; ///< How many vehicles did we bought?
|
||||
VehicleID veh_id; ///< Used when bought a vehicle
|
||||
VehicleID veh_main_id; ///< The ID of the first vehicle, for shared copy
|
||||
|
||||
int from_ic; ///< ic = industry/city. This is the ID of them
|
||||
byte from_type; ///< AI_NO_TYPE/AI_CITY/AI_INDUSTRY
|
||||
int to_ic;
|
||||
byte to_type;
|
||||
};
|
||||
extern PlayerAiNew _players_ainew[MAX_PLAYERS];
|
||||
|
||||
#endif /* AI_TROLLY_H */
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "depot.h"
|
||||
#include "newgrf_config.h"
|
||||
#include "ai/ai.h"
|
||||
#include "ai/default/default.h"
|
||||
#include "zoom_func.h"
|
||||
#include "functions.h"
|
||||
#include "date_func.h"
|
||||
@ -811,10 +812,10 @@ static bool OldLoadAIBuildRec(LoadgameState *ls, int num)
|
||||
Player *p = GetPlayer(_current_player_id);
|
||||
|
||||
switch (num) {
|
||||
case 0: return LoadChunk(ls, &p->ai.src, player_ai_build_rec_chunk);
|
||||
case 1: return LoadChunk(ls, &p->ai.dst, player_ai_build_rec_chunk);
|
||||
case 2: return LoadChunk(ls, &p->ai.mid1, player_ai_build_rec_chunk);
|
||||
case 3: return LoadChunk(ls, &p->ai.mid2, player_ai_build_rec_chunk);
|
||||
case 0: return LoadChunk(ls, &_players_ai[p->index].src, player_ai_build_rec_chunk);
|
||||
case 1: return LoadChunk(ls, &_players_ai[p->index].dst, player_ai_build_rec_chunk);
|
||||
case 2: return LoadChunk(ls, &_players_ai[p->index].mid1, player_ai_build_rec_chunk);
|
||||
case 3: return LoadChunk(ls, &_players_ai[p->index].mid2, player_ai_build_rec_chunk);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -924,11 +925,10 @@ static const OldChunks player_ai_chunk[] = {
|
||||
|
||||
static bool OldPlayerAI(LoadgameState *ls, int num)
|
||||
{
|
||||
Player *p = GetPlayer(_current_player_id);
|
||||
|
||||
return LoadChunk(ls, &p->ai, player_ai_chunk);
|
||||
return LoadChunk(ls, &_players_ai[_current_player_id], player_ai_chunk);
|
||||
}
|
||||
|
||||
uint8 ai_tick;
|
||||
static const OldChunks player_chunk[] = {
|
||||
OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
|
||||
OCL_SVAR( OC_UINT32, Player, name_2 ),
|
||||
@ -958,7 +958,7 @@ static const OldChunks player_chunk[] = {
|
||||
OCL_CHUNK( 1, OldPlayerAI ),
|
||||
|
||||
OCL_SVAR( OC_UINT8, Player, block_preview ),
|
||||
OCL_SVAR( OC_UINT8, Player, ai.tick ),
|
||||
OCL_VAR( OC_UINT8, 1, &ai_tick ),
|
||||
OCL_SVAR( OC_UINT8, Player, avail_railtypes ),
|
||||
OCL_SVAR( OC_TILE, Player, location_of_house ),
|
||||
OCL_SVAR( OC_UINT8, Player, share_owners[0] ),
|
||||
@ -982,6 +982,7 @@ static bool LoadOldPlayer(LoadgameState *ls, int num)
|
||||
p->name_1 = RemapOldStringID(_old_string_id);
|
||||
p->president_name_1 = RemapOldStringID(_old_string_id_2);
|
||||
p->player_money = p->player_money;
|
||||
_players_ai[_current_player_id].tick = ai_tick;
|
||||
|
||||
if (num == 0) {
|
||||
/* If the first player has no name, make sure we call it UNNAMED */
|
||||
@ -1007,10 +1008,10 @@ static bool LoadOldPlayer(LoadgameState *ls, int num)
|
||||
p->location_of_house = 0;
|
||||
|
||||
/* State 20 for AI players is sell vehicle. Since the AI struct is not
|
||||
* really figured out as of now, p->ai.cur_veh; needed for 'sell vehicle'
|
||||
* really figured out as of now, _players_ai[p->index].cur_veh; needed for 'sell vehicle'
|
||||
* is NULL and the function will crash. To fix this, just change the state
|
||||
* to some harmless state, like 'loop vehicle'; 1 */
|
||||
if (!IsHumanPlayer((PlayerID)num) && p->ai.state == 20) p->ai.state = 1;
|
||||
if (!IsHumanPlayer((PlayerID)num) && _players_ai[p->index].state == 20) _players_ai[p->index].state = 1;
|
||||
|
||||
if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
|
||||
AI_StartNewAI(p->index);
|
||||
|
137
src/player.h
137
src/player.h
@ -5,12 +5,7 @@
|
||||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
|
||||
#include "oldpool.h"
|
||||
#include "aystar.h"
|
||||
#include "rail_type.h"
|
||||
#include "road_func.h"
|
||||
#include "cargo_type.h"
|
||||
#include "command_type.h"
|
||||
#include "date_type.h"
|
||||
#include "engine.h"
|
||||
#include "livery.h"
|
||||
@ -25,136 +20,6 @@ struct PlayerEconomyEntry {
|
||||
Money company_value;
|
||||
};
|
||||
|
||||
struct AiBuildRec {
|
||||
TileIndex spec_tile;
|
||||
TileIndex use_tile;
|
||||
byte rand_rng;
|
||||
byte cur_building_rule;
|
||||
byte unk6;
|
||||
byte unk7;
|
||||
byte buildcmd_a;
|
||||
byte buildcmd_b;
|
||||
byte direction;
|
||||
CargoID cargo;
|
||||
};
|
||||
|
||||
struct PlayerAI {
|
||||
byte state;
|
||||
byte tick; ///< Used to determine how often to move
|
||||
uint32 state_counter; ///< Can hold tile index!
|
||||
uint16 timeout_counter;
|
||||
|
||||
byte state_mode;
|
||||
byte banned_tile_count;
|
||||
RailTypeByte railtype_to_use;
|
||||
|
||||
CargoID cargo_type;
|
||||
byte num_wagons;
|
||||
byte build_kind;
|
||||
byte num_build_rec;
|
||||
byte num_loco_to_build;
|
||||
byte num_want_fullload;
|
||||
|
||||
byte route_type_mask;
|
||||
|
||||
TileIndex start_tile_a;
|
||||
TileIndex cur_tile_a;
|
||||
DiagDirectionByte cur_dir_a;
|
||||
DiagDirectionByte start_dir_a;
|
||||
|
||||
TileIndex start_tile_b;
|
||||
TileIndex cur_tile_b;
|
||||
DiagDirectionByte cur_dir_b;
|
||||
DiagDirectionByte start_dir_b;
|
||||
|
||||
Vehicle *cur_veh; ///< only used by some states
|
||||
|
||||
AiBuildRec src, dst, mid1, mid2;
|
||||
|
||||
VehicleID wagon_list[9];
|
||||
byte order_list_blocks[20];
|
||||
|
||||
TileIndex banned_tiles[16];
|
||||
byte banned_val[16];
|
||||
};
|
||||
|
||||
struct Ai_PathFinderInfo {
|
||||
TileIndex start_tile_tl; ///< tl = top-left
|
||||
TileIndex start_tile_br; ///< br = bottom-right
|
||||
TileIndex end_tile_tl; ///< tl = top-left
|
||||
TileIndex end_tile_br; ///< br = bottom-right
|
||||
DiagDirection start_direction; ///< 0 to 3 or AI_PATHFINDER_NO_DIRECTION
|
||||
DiagDirection end_direction; ///< 0 to 3 or AI_PATHFINDER_NO_DIRECTION
|
||||
|
||||
TileIndex route[500];
|
||||
byte route_extra[500]; ///< Some extra information about the route like bridge/tunnel
|
||||
int route_length;
|
||||
int position; ///< Current position in the build-path, needed to build the path
|
||||
|
||||
bool rail_or_road; ///< true = rail, false = road
|
||||
};
|
||||
|
||||
/* The amount of memory reserved for the AI-special-vehicles */
|
||||
#define AI_MAX_SPECIAL_VEHICLES 100
|
||||
|
||||
struct Ai_SpecialVehicle {
|
||||
VehicleID veh_id;
|
||||
uint32 flag;
|
||||
};
|
||||
|
||||
struct PlayerAiNew {
|
||||
uint8 state;
|
||||
uint tick;
|
||||
uint idle;
|
||||
|
||||
int temp; ///< A value used in more than one function, but it just temporary
|
||||
///< The use is pretty simple: with this we can 'think' about stuff
|
||||
///< in more than one tick, and more than one AI. A static will not
|
||||
///< do, because they are not saved. This way, the AI is almost human ;)
|
||||
int counter; ///< For the same reason as temp, we have counter. It can count how
|
||||
///< long we are trying something, and just abort if it takes too long
|
||||
|
||||
/* Pathfinder stuff */
|
||||
Ai_PathFinderInfo path_info;
|
||||
AyStar *pathfinder;
|
||||
|
||||
/* Route stuff */
|
||||
|
||||
CargoID cargo;
|
||||
byte tbt; ///< train/bus/truck 0/1/2 AI_TRAIN/AI_BUS/AI_TRUCK
|
||||
Money new_cost;
|
||||
|
||||
byte action;
|
||||
|
||||
int last_id; ///< here is stored the last id of the searched city/industry
|
||||
Date last_vehiclecheck_date; // Used in CheckVehicle
|
||||
Ai_SpecialVehicle special_vehicles[AI_MAX_SPECIAL_VEHICLES]; ///< Some vehicles have some special flags
|
||||
|
||||
TileIndex from_tile;
|
||||
TileIndex to_tile;
|
||||
|
||||
DiagDirectionByte from_direction;
|
||||
DiagDirectionByte to_direction;
|
||||
|
||||
bool from_deliver; ///< True if this is the station that GIVES cargo
|
||||
bool to_deliver;
|
||||
|
||||
TileIndex depot_tile;
|
||||
DiagDirectionByte depot_direction;
|
||||
|
||||
byte amount_veh; ///< How many vehicles we are going to build in this route
|
||||
byte cur_veh; ///< How many vehicles did we bought?
|
||||
VehicleID veh_id; ///< Used when bought a vehicle
|
||||
VehicleID veh_main_id; ///< The ID of the first vehicle, for shared copy
|
||||
|
||||
int from_ic; ///< ic = industry/city. This is the ID of them
|
||||
byte from_type; ///< AI_NO_TYPE/AI_CITY/AI_INDUSTRY
|
||||
int to_ic;
|
||||
byte to_type;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* The "steps" in loan size, in British Pounds! */
|
||||
enum {
|
||||
LOAN_INTERVAL = 10000,
|
||||
@ -198,8 +63,6 @@ struct Player {
|
||||
|
||||
bool is_active;
|
||||
bool is_ai;
|
||||
PlayerAI ai;
|
||||
PlayerAiNew ainew;
|
||||
|
||||
Money yearly_expenses[3][13];
|
||||
PlayerEconomyEntry cur_economy;
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "autoreplace_func.h"
|
||||
#include "autoreplace_gui.h"
|
||||
#include "string_func.h"
|
||||
#include "ai/default/default.h"
|
||||
#include "ai/trolly/trolly.h"
|
||||
|
||||
/**
|
||||
* Sets the local player and updates the patch settings that are set on a
|
||||
@ -441,6 +443,8 @@ static Player *AllocatePlayer()
|
||||
if (!p->is_active) {
|
||||
PlayerID i = p->index;
|
||||
memset(p, 0, sizeof(Player));
|
||||
memset(&_players_ai[i], 0, sizeof(PlayerAI));
|
||||
memset(&_players_ainew[i], 0, sizeof(PlayerAiNew));
|
||||
p->index = i;
|
||||
return p;
|
||||
}
|
||||
@ -480,7 +484,7 @@ Player *DoStartupNewPlayer(bool is_ai)
|
||||
p->player_money = p->current_loan = 100000;
|
||||
|
||||
p->is_ai = is_ai;
|
||||
p->ai.state = 5; // AIS_WANT_NEW_ROUTE
|
||||
_players_ai[p->index].state = 5; // AIS_WANT_NEW_ROUTE
|
||||
p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR;
|
||||
|
||||
p->avail_railtypes = GetPlayerRailtypes(p->index);
|
||||
@ -1193,66 +1197,6 @@ static const SaveLoad _player_economy_desc[] = {
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _player_ai_desc[] = {
|
||||
SLE_VAR(PlayerAI, state, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, tick, SLE_UINT8),
|
||||
SLE_CONDVAR(PlayerAI, state_counter, SLE_FILE_U16 | SLE_VAR_U32, 0, 12),
|
||||
SLE_CONDVAR(PlayerAI, state_counter, SLE_UINT32, 13, SL_MAX_VERSION),
|
||||
SLE_VAR(PlayerAI, timeout_counter, SLE_UINT16),
|
||||
|
||||
SLE_VAR(PlayerAI, state_mode, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, banned_tile_count, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, railtype_to_use, SLE_UINT8),
|
||||
|
||||
SLE_VAR(PlayerAI, cargo_type, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, num_wagons, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, build_kind, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, num_build_rec, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, num_loco_to_build, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, num_want_fullload, SLE_UINT8),
|
||||
|
||||
SLE_VAR(PlayerAI, route_type_mask, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(PlayerAI, start_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(PlayerAI, start_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(PlayerAI, cur_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(PlayerAI, cur_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(PlayerAI, start_dir_a, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, cur_dir_a, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(PlayerAI, start_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(PlayerAI, start_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(PlayerAI, cur_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(PlayerAI, cur_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(PlayerAI, start_dir_b, SLE_UINT8),
|
||||
SLE_VAR(PlayerAI, cur_dir_b, SLE_UINT8),
|
||||
|
||||
SLE_REF(PlayerAI, cur_veh, REF_VEHICLE),
|
||||
|
||||
SLE_ARR(PlayerAI, wagon_list, SLE_UINT16, 9),
|
||||
SLE_ARR(PlayerAI, order_list_blocks, SLE_UINT8, 20),
|
||||
SLE_ARR(PlayerAI, banned_tiles, SLE_UINT16, 16),
|
||||
|
||||
SLE_CONDNULL(64, 2, SL_MAX_VERSION),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _player_ai_build_rec_desc[] = {
|
||||
SLE_CONDVAR(AiBuildRec, spec_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(AiBuildRec, spec_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(AiBuildRec, use_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(AiBuildRec, use_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(AiBuildRec, rand_rng, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, unk6, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, unk7, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, buildcmd_a, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, buildcmd_b, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, direction, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, cargo, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _player_livery_desc[] = {
|
||||
SLE_CONDVAR(Livery, in_use, SLE_BOOL, 34, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
|
||||
@ -1268,10 +1212,7 @@ static void SaveLoad_PLYR(Player* p)
|
||||
|
||||
/* Write AI? */
|
||||
if (!IsHumanPlayer(p->index)) {
|
||||
SlObject(&p->ai, _player_ai_desc);
|
||||
for (i = 0; i != p->ai.num_build_rec; i++) {
|
||||
SlObject(&p->ai.src + i, _player_ai_build_rec_desc);
|
||||
}
|
||||
SaveLoad_AI(p->index);
|
||||
}
|
||||
|
||||
/* Write economy */
|
||||
|
Loading…
Reference in New Issue
Block a user