mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-09 15:41:15 +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 "../stdafx.h"
|
||||||
#include "../openttd.h"
|
#include "../openttd.h"
|
||||||
|
#include "../player.h"
|
||||||
#include "../variables.h"
|
#include "../variables.h"
|
||||||
#include "../command_func.h"
|
#include "../command_func.h"
|
||||||
#include "../network/network.h"
|
#include "../network/network.h"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,5 +4,61 @@
|
|||||||
#define DEFAULT_H
|
#define DEFAULT_H
|
||||||
|
|
||||||
void AiDoGameLoop(Player*);
|
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
|
#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;
|
if (type2 == 0 && type != 0) type2 = type;
|
||||||
|
|
||||||
// Now, simply, build the bridge!
|
// 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);
|
return AI_DoCommand(tile_a, tile_b, (0x00 << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
|
||||||
} else {
|
} else {
|
||||||
return AI_DoCommand(tile_a, tile_b, ((0x80 | ROADTYPES_ROAD) << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
|
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);
|
res = AI_DoCommand(route[part], 0, dir, flag, CMD_BUILD_SINGLE_RAIL);
|
||||||
if (CmdFailed(res)) {
|
if (CmdFailed(res)) {
|
||||||
// Problem.. let's just abort it all!
|
// Problem.. let's just abort it all!
|
||||||
p->ainew.state = AI_STATE_NOTHING;
|
_players_ainew[p->index].state = AI_STATE_NOTHING;
|
||||||
return CommandCost();
|
return CommandCost();
|
||||||
}
|
}
|
||||||
cost.AddCost(res);
|
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])) {
|
if (CmdFailed(res) && flag == DC_EXEC && !IsTileType(route[part], MP_ROAD) && !EnsureNoVehicleOnGround(route[part])) {
|
||||||
// Problem.. let's just abort it all!
|
// Problem.. let's just abort it all!
|
||||||
DEBUG(ai, 0, "[BuidPath] route building failed at tile 0x%X, aborting", route[part]);
|
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();
|
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
|
// It returns INVALID_ENGINE if not suitable engine is found
|
||||||
EngineID AiNew_PickVehicle(Player *p)
|
EngineID AiNew_PickVehicle(Player *p)
|
||||||
{
|
{
|
||||||
if (p->ainew.tbt == AI_TRAIN) {
|
if (_players_ainew[p->index].tbt == AI_TRAIN) {
|
||||||
// Not supported yet
|
// Not supported yet
|
||||||
return INVALID_ENGINE;
|
return INVALID_ENGINE;
|
||||||
} else {
|
} else {
|
||||||
@ -244,7 +244,7 @@ EngineID AiNew_PickVehicle(Player *p)
|
|||||||
CommandCost ret;
|
CommandCost ret;
|
||||||
|
|
||||||
/* Skip vehicles which can't take our cargo type */
|
/* 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?
|
// Is it availiable?
|
||||||
// Also, check if the reliability of the vehicle is above the AI_VEHICLE_MIN_RELIABILTY
|
// 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);
|
Player* p = GetPlayer(_current_player);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
p->ainew.state = AI_STATE_GIVE_ORDERS;
|
_players_ainew[p->index].state = AI_STATE_GIVE_ORDERS;
|
||||||
p->ainew.veh_id = _new_vehicle_id;
|
_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 */
|
/* 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 */
|
/* Refit failed, so sell the vehicle */
|
||||||
DoCommand(tile, p->ainew.veh_id, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
|
DoCommand(tile, _players_ainew[p->index].veh_id, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
|
||||||
p->ainew.state = AI_STATE_NOTHING;
|
_players_ainew[p->index].state = AI_STATE_NOTHING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* XXX this should be handled more gracefully */
|
/* 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);
|
EngineID i = AiNew_PickVehicle(p);
|
||||||
|
|
||||||
if (i == INVALID_ENGINE) return CMD_ERROR;
|
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) {
|
if (flag & DC_EXEC) {
|
||||||
return AI_DoCommandCc(tile, i, 0, flag, CMD_BUILD_ROAD_VEH, CcAI);
|
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 AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction, byte flag)
|
||||||
{
|
{
|
||||||
CommandCost ret, ret2;
|
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);
|
return AI_DoCommand(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
|
||||||
} else {
|
} else {
|
||||||
ret = AI_DoCommand(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
|
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...
|
// TODO: currently we only allow spots that can be access from al 4 directions...
|
||||||
// should be fixed!!!
|
// should be fixed!!!
|
||||||
for (dir = 0; dir < 4; dir++) {
|
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;
|
if (CmdSucceeded(ret)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if command succeeded, so the inverse of CmdFailed()
|
// 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;
|
uint i;
|
||||||
|
|
||||||
for (i = 0; i < AI_MAX_SPECIAL_VEHICLES; i++) {
|
for (i = 0; i < AI_MAX_SPECIAL_VEHICLES; i++) {
|
||||||
if (p->ainew.special_vehicles[i].veh_id == v->index) {
|
if (_players_ainew[p->index].special_vehicles[i].veh_id == v->index) {
|
||||||
return p->ainew.special_vehicles[i].flag;
|
return _players_ainew[p->index].special_vehicles[i].flag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,13 +96,13 @@ bool AiNew_SetSpecialVehicleFlag(Player* p, Vehicle* v, uint flag)
|
|||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
for (i = 0; i < AI_MAX_SPECIAL_VEHICLES; i++) {
|
for (i = 0; i < AI_MAX_SPECIAL_VEHICLES; i++) {
|
||||||
if (p->ainew.special_vehicles[i].veh_id == v->index) {
|
if (_players_ainew[p->index].special_vehicles[i].veh_id == v->index) {
|
||||||
p->ainew.special_vehicles[i].flag |= flag;
|
_players_ainew[p->index].special_vehicles[i].flag |= flag;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (new_id == -1 &&
|
if (new_id == -1 &&
|
||||||
p->ainew.special_vehicles[i].veh_id == 0 &&
|
_players_ainew[p->index].special_vehicles[i].veh_id == 0 &&
|
||||||
p->ainew.special_vehicles[i].flag == 0) {
|
_players_ainew[p->index].special_vehicles[i].flag == 0) {
|
||||||
new_id = i;
|
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");
|
DEBUG(ai, 1, "special_vehicles list is too small");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
p->ainew.special_vehicles[new_id].veh_id = v->index;
|
_players_ainew[p->index].special_vehicles[new_id].veh_id = v->index;
|
||||||
p->ainew.special_vehicles[new_id].flag = flag;
|
_players_ainew[p->index].special_vehicles[new_id].flag = flag;
|
||||||
return true;
|
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
|
// ai_new.c
|
||||||
void AiNewDoGameLoop(Player *p);
|
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
|
// ai_pathfinder.c
|
||||||
AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo);
|
AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo);
|
||||||
void clean_AyStar_AiPathFinder(AyStar *aystar, 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_Vehicle(Player *p, TileIndex tile, byte flag);
|
||||||
CommandCost AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction, 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 */
|
#endif /* AI_TROLLY_H */
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "depot.h"
|
#include "depot.h"
|
||||||
#include "newgrf_config.h"
|
#include "newgrf_config.h"
|
||||||
#include "ai/ai.h"
|
#include "ai/ai.h"
|
||||||
|
#include "ai/default/default.h"
|
||||||
#include "zoom_func.h"
|
#include "zoom_func.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "date_func.h"
|
#include "date_func.h"
|
||||||
@ -811,10 +812,10 @@ static bool OldLoadAIBuildRec(LoadgameState *ls, int num)
|
|||||||
Player *p = GetPlayer(_current_player_id);
|
Player *p = GetPlayer(_current_player_id);
|
||||||
|
|
||||||
switch (num) {
|
switch (num) {
|
||||||
case 0: return LoadChunk(ls, &p->ai.src, 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, &p->ai.dst, 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, &p->ai.mid1, 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, &p->ai.mid2, player_ai_build_rec_chunk);
|
case 3: return LoadChunk(ls, &_players_ai[p->index].mid2, player_ai_build_rec_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -924,11 +925,10 @@ static const OldChunks player_ai_chunk[] = {
|
|||||||
|
|
||||||
static bool OldPlayerAI(LoadgameState *ls, int num)
|
static bool OldPlayerAI(LoadgameState *ls, int num)
|
||||||
{
|
{
|
||||||
Player *p = GetPlayer(_current_player_id);
|
return LoadChunk(ls, &_players_ai[_current_player_id], player_ai_chunk);
|
||||||
|
|
||||||
return LoadChunk(ls, &p->ai, player_ai_chunk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 ai_tick;
|
||||||
static const OldChunks player_chunk[] = {
|
static const OldChunks player_chunk[] = {
|
||||||
OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
|
OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
|
||||||
OCL_SVAR( OC_UINT32, Player, name_2 ),
|
OCL_SVAR( OC_UINT32, Player, name_2 ),
|
||||||
@ -958,7 +958,7 @@ static const OldChunks player_chunk[] = {
|
|||||||
OCL_CHUNK( 1, OldPlayerAI ),
|
OCL_CHUNK( 1, OldPlayerAI ),
|
||||||
|
|
||||||
OCL_SVAR( OC_UINT8, Player, block_preview ),
|
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_UINT8, Player, avail_railtypes ),
|
||||||
OCL_SVAR( OC_TILE, Player, location_of_house ),
|
OCL_SVAR( OC_TILE, Player, location_of_house ),
|
||||||
OCL_SVAR( OC_UINT8, Player, share_owners[0] ),
|
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->name_1 = RemapOldStringID(_old_string_id);
|
||||||
p->president_name_1 = RemapOldStringID(_old_string_id_2);
|
p->president_name_1 = RemapOldStringID(_old_string_id_2);
|
||||||
p->player_money = p->player_money;
|
p->player_money = p->player_money;
|
||||||
|
_players_ai[_current_player_id].tick = ai_tick;
|
||||||
|
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
/* If the first player has no name, make sure we call it UNNAMED */
|
/* 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;
|
p->location_of_house = 0;
|
||||||
|
|
||||||
/* State 20 for AI players is sell vehicle. Since the AI struct is not
|
/* 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
|
* is NULL and the function will crash. To fix this, just change the state
|
||||||
* to some harmless state, like 'loop vehicle'; 1 */
|
* 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)
|
if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
|
||||||
AI_StartNewAI(p->index);
|
AI_StartNewAI(p->index);
|
||||||
|
137
src/player.h
137
src/player.h
@ -5,12 +5,7 @@
|
|||||||
#ifndef PLAYER_H
|
#ifndef PLAYER_H
|
||||||
#define PLAYER_H
|
#define PLAYER_H
|
||||||
|
|
||||||
#include "oldpool.h"
|
|
||||||
#include "aystar.h"
|
|
||||||
#include "rail_type.h"
|
|
||||||
#include "road_func.h"
|
#include "road_func.h"
|
||||||
#include "cargo_type.h"
|
|
||||||
#include "command_type.h"
|
|
||||||
#include "date_type.h"
|
#include "date_type.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "livery.h"
|
#include "livery.h"
|
||||||
@ -25,136 +20,6 @@ struct PlayerEconomyEntry {
|
|||||||
Money company_value;
|
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! */
|
/* The "steps" in loan size, in British Pounds! */
|
||||||
enum {
|
enum {
|
||||||
LOAN_INTERVAL = 10000,
|
LOAN_INTERVAL = 10000,
|
||||||
@ -198,8 +63,6 @@ struct Player {
|
|||||||
|
|
||||||
bool is_active;
|
bool is_active;
|
||||||
bool is_ai;
|
bool is_ai;
|
||||||
PlayerAI ai;
|
|
||||||
PlayerAiNew ainew;
|
|
||||||
|
|
||||||
Money yearly_expenses[3][13];
|
Money yearly_expenses[3][13];
|
||||||
PlayerEconomyEntry cur_economy;
|
PlayerEconomyEntry cur_economy;
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "autoreplace_func.h"
|
#include "autoreplace_func.h"
|
||||||
#include "autoreplace_gui.h"
|
#include "autoreplace_gui.h"
|
||||||
#include "string_func.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
|
* 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) {
|
if (!p->is_active) {
|
||||||
PlayerID i = p->index;
|
PlayerID i = p->index;
|
||||||
memset(p, 0, sizeof(Player));
|
memset(p, 0, sizeof(Player));
|
||||||
|
memset(&_players_ai[i], 0, sizeof(PlayerAI));
|
||||||
|
memset(&_players_ainew[i], 0, sizeof(PlayerAiNew));
|
||||||
p->index = i;
|
p->index = i;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -480,7 +484,7 @@ Player *DoStartupNewPlayer(bool is_ai)
|
|||||||
p->player_money = p->current_loan = 100000;
|
p->player_money = p->current_loan = 100000;
|
||||||
|
|
||||||
p->is_ai = is_ai;
|
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->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR;
|
||||||
|
|
||||||
p->avail_railtypes = GetPlayerRailtypes(p->index);
|
p->avail_railtypes = GetPlayerRailtypes(p->index);
|
||||||
@ -1193,66 +1197,6 @@ static const SaveLoad _player_economy_desc[] = {
|
|||||||
SLE_END()
|
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[] = {
|
static const SaveLoad _player_livery_desc[] = {
|
||||||
SLE_CONDVAR(Livery, in_use, SLE_BOOL, 34, SL_MAX_VERSION),
|
SLE_CONDVAR(Livery, in_use, SLE_BOOL, 34, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR(Livery, colour1, SLE_UINT8, 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? */
|
/* Write AI? */
|
||||||
if (!IsHumanPlayer(p->index)) {
|
if (!IsHumanPlayer(p->index)) {
|
||||||
SlObject(&p->ai, _player_ai_desc);
|
SaveLoad_AI(p->index);
|
||||||
for (i = 0; i != p->ai.num_build_rec; i++) {
|
|
||||||
SlObject(&p->ai.src + i, _player_ai_build_rec_desc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write economy */
|
/* Write economy */
|
||||||
|
Loading…
Reference in New Issue
Block a user