mirror of https://github.com/OpenTTD/OpenTTD
(svn r146) -Fix [AI]: Tunnel/bridge bug
-Fix [AI]: Minor problems -Add [AI]: Profit check (if not making enough money, vehicles are sold)release/0.4.5
parent
a7dd461672
commit
5eba928cb8
30
ai.h
30
ai.h
|
@ -136,11 +136,29 @@
|
||||||
// How many thick between building 2 vehicles
|
// How many thick between building 2 vehicles
|
||||||
#define AI_BUILD_VEHICLE_TIME_BETWEEN 74
|
#define AI_BUILD_VEHICLE_TIME_BETWEEN 74
|
||||||
|
|
||||||
|
// How many days must there between vehicle checks
|
||||||
|
// The more often, the less non-money-making lines there will be
|
||||||
|
// but the unfair it may seem to a human player
|
||||||
|
#define AI_DAYS_BETWEEN_VEHICLE_CHECKS 30
|
||||||
|
|
||||||
|
// How money profit does a vehicle needs to make to stay in order
|
||||||
|
// This is the profit of this year + profit of last year
|
||||||
|
// But also for vehicles that are just one year old. In other words:
|
||||||
|
// Vehicles of 2 years do easier meet this setting then vehicles
|
||||||
|
// of one year. This is a very good thing. New vehicles are filtered,
|
||||||
|
// while old vehicles stay longer, because we do get less in return.
|
||||||
|
#define AI_MINIMUM_ROUTE_PROFIT 1000
|
||||||
|
|
||||||
|
// A vehicle is considered lost when he his cargo is more then 180 days old
|
||||||
|
#define AI_VEHICLE_LOST_DAYS 180
|
||||||
|
|
||||||
|
// How many times may the AI try to find a route before it gives up
|
||||||
|
#define AI_MAX_TRIES_FOR_SAME_ROUTE 8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of defines
|
* End of defines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// This stops 90degrees curves
|
// This stops 90degrees curves
|
||||||
static const byte _illegal_curves[6] = {
|
static const byte _illegal_curves[6] = {
|
||||||
255, 255, // Horz and vert, don't have the effect
|
255, 255, // Horz and vert, don't have the effect
|
||||||
|
@ -174,6 +192,7 @@ enum {
|
||||||
AI_STATE_GIVE_ORDERS,
|
AI_STATE_GIVE_ORDERS,
|
||||||
AI_STATE_START_VEHICLE,
|
AI_STATE_START_VEHICLE,
|
||||||
AI_STATE_REPAY_MONEY,
|
AI_STATE_REPAY_MONEY,
|
||||||
|
AI_STATE_CHECK_ALL_VEHICLES,
|
||||||
AI_STATE_ACTION_DONE,
|
AI_STATE_ACTION_DONE,
|
||||||
AI_STATE_STOP, // Temporary function to stop the AI
|
AI_STATE_STOP, // Temporary function to stop the AI
|
||||||
};
|
};
|
||||||
|
@ -190,6 +209,7 @@ enum {
|
||||||
AI_ACTION_BUS_ROUTE,
|
AI_ACTION_BUS_ROUTE,
|
||||||
AI_ACTION_TRUCK_ROUTE,
|
AI_ACTION_TRUCK_ROUTE,
|
||||||
AI_ACTION_REPAY_LOAN,
|
AI_ACTION_REPAY_LOAN,
|
||||||
|
AI_ACTION_CHECK_ALL_VEHICLES,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used for from_type/to_type
|
// Used for from_type/to_type
|
||||||
|
@ -199,6 +219,12 @@ enum {
|
||||||
AI_INDUSTRY,
|
AI_INDUSTRY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Flags for in the vehicle
|
||||||
|
enum {
|
||||||
|
AI_VEHICLEFLAG_SELL = 1,
|
||||||
|
// Remember, flags must be in power of 2
|
||||||
|
};
|
||||||
|
|
||||||
#define AI_NO_CARGO 0xFF // Means that there is no cargo defined yet (used for industry)
|
#define AI_NO_CARGO 0xFF // Means that there is no cargo defined yet (used for industry)
|
||||||
#define AI_NEED_CARGO 0xFE // Used when the AI needs to find out a cargo for the route
|
#define AI_NEED_CARGO 0xFE // Used when the AI needs to find out a cargo for the route
|
||||||
#define AI_STATION_RANGE TILE_XY(TILE_X_MAX, TILE_Y_MAX)
|
#define AI_STATION_RANGE TILE_XY(TILE_X_MAX, TILE_Y_MAX)
|
||||||
|
@ -229,6 +255,8 @@ void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo
|
||||||
int AiNew_GetRailDirection(uint tile_a, uint tile_b, uint tile_c);
|
int AiNew_GetRailDirection(uint tile_a, uint tile_b, uint tile_c);
|
||||||
int AiNew_GetRoadDirection(uint tile_a, uint tile_b, uint tile_c);
|
int AiNew_GetRoadDirection(uint tile_a, uint tile_b, uint tile_c);
|
||||||
int AiNew_GetDirection(uint tile_a, uint tile_b);
|
int AiNew_GetDirection(uint tile_a, uint tile_b);
|
||||||
|
bool AiNew_SetSpecialVehicleFlag(Player *p, Vehicle *v, uint flag);
|
||||||
|
uint AiNew_GetSpecialVehicleFlag(Player *p, Vehicle *v);
|
||||||
|
|
||||||
// ai_build.c
|
// ai_build.c
|
||||||
bool AiNew_Build_CompanyHQ(Player *p, uint tile);
|
bool AiNew_Build_CompanyHQ(Player *p, uint tile);
|
||||||
|
|
|
@ -177,7 +177,7 @@ int AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte fla
|
||||||
// Build the tile
|
// Build the tile
|
||||||
res = DoCommandByTile(route[part], dir, 0, flag | DC_NO_WATER, CMD_BUILD_ROAD);
|
res = DoCommandByTile(route[part], dir, 0, flag | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||||
// Currently, we ignore CMD_ERRORs!
|
// Currently, we ignore CMD_ERRORs!
|
||||||
if (res == CMD_ERROR && !IS_TILETYPE(route[part], MP_STREET) && (flag == DC_EXEC && !EnsureNoVehicle(route[part]))) {
|
if (res == CMD_ERROR && flag == DC_EXEC && !IS_TILETYPE(route[part], MP_STREET) && !EnsureNoVehicle(route[part])) {
|
||||||
// Problem.. let's just abort it all!
|
// Problem.. let's just abort it all!
|
||||||
DEBUG(ai,0)("Darn, the route could not be builded.. aborting!");
|
DEBUG(ai,0)("Darn, the route could not be builded.. aborting!");
|
||||||
p->ainew.state = AI_STATE_NOTHING;
|
p->ainew.state = AI_STATE_NOTHING;
|
||||||
|
|
82
ai_new.c
82
ai_new.c
|
@ -46,6 +46,7 @@ static void AiNew_State_FirstTime(Player *p) {
|
||||||
p->ainew.pathfinder = new_AyStar_AiPathFinder(12, &p->ainew.path_info);
|
p->ainew.pathfinder = new_AyStar_AiPathFinder(12, &p->ainew.path_info);
|
||||||
|
|
||||||
p->ainew.idle = 0;
|
p->ainew.idle = 0;
|
||||||
|
p->ainew.last_vehiclecheck_date = _date;
|
||||||
|
|
||||||
// We ALWAYS start with a bus route.. just some basic money ;)
|
// We ALWAYS start with a bus route.. just some basic money ;)
|
||||||
p->ainew.action = AI_ACTION_BUS_ROUTE;
|
p->ainew.action = AI_ACTION_BUS_ROUTE;
|
||||||
|
@ -101,10 +102,14 @@ static void AiNew_State_WakeUp(Player *p) {
|
||||||
if (p->current_loan > 0 && p->old_economy[1].income > AI_MINIMUM_INCOME_FOR_LOAN &&
|
if (p->current_loan > 0 && p->old_economy[1].income > AI_MINIMUM_INCOME_FOR_LOAN &&
|
||||||
c < 10) {
|
c < 10) {
|
||||||
p->ainew.action = AI_ACTION_REPAY_LOAN;
|
p->ainew.action = AI_ACTION_REPAY_LOAN;
|
||||||
|
} else if (p->ainew.last_vehiclecheck_date + AI_DAYS_BETWEEN_VEHICLE_CHECKS < _date) {
|
||||||
|
// Check all vehicles once in a while
|
||||||
|
p->ainew.action = AI_ACTION_CHECK_ALL_VEHICLES;
|
||||||
|
p->ainew.last_vehiclecheck_date = _date;
|
||||||
} else if (c < 100 && !_patches.ai_disable_veh_roadveh) {
|
} else if (c < 100 && !_patches.ai_disable_veh_roadveh) {
|
||||||
// Do we have any spots for road-vehicles left open?
|
// Do we have any spots for road-vehicles left open?
|
||||||
if (GetFreeUnitNumber(VEH_Road) <= _patches.max_roadveh) {
|
if (GetFreeUnitNumber(VEH_Road) <= _patches.max_roadveh) {
|
||||||
if (c < 65) p->ainew.action = AI_ACTION_TRUCK_ROUTE;
|
if (c < 85) p->ainew.action = AI_ACTION_TRUCK_ROUTE;
|
||||||
else p->ainew.action = AI_ACTION_BUS_ROUTE;
|
else p->ainew.action = AI_ACTION_BUS_ROUTE;
|
||||||
}
|
}
|
||||||
}/* else if (c < 200 && !_patches.ai_disable_veh_train) {
|
}/* else if (c < 200 && !_patches.ai_disable_veh_train) {
|
||||||
|
@ -112,6 +117,13 @@ static void AiNew_State_WakeUp(Player *p) {
|
||||||
p->ainew.action = AI_ACTION_TRAIN_ROUTE;
|
p->ainew.action = AI_ACTION_TRAIN_ROUTE;
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
p->ainew.counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->ainew.counter++ > AI_MAX_TRIES_FOR_SAME_ROUTE) {
|
||||||
|
p->ainew.action = AI_ACTION_NONE;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_patches.ai_disable_veh_roadveh && (
|
if (_patches.ai_disable_veh_roadveh && (
|
||||||
|
@ -132,6 +144,11 @@ static void AiNew_State_WakeUp(Player *p) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->ainew.action == AI_ACTION_CHECK_ALL_VEHICLES) {
|
||||||
|
p->ainew.state = AI_STATE_CHECK_ALL_VEHICLES;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// It is useless to start finding a route if we don't have enough money
|
// It is useless to start finding a route if we don't have enough money
|
||||||
// to build the route anyway..
|
// to build the route anyway..
|
||||||
if (p->ainew.action == AI_ACTION_BUS_ROUTE && money > AI_MINIMUM_BUS_ROUTE_MONEY) {
|
if (p->ainew.action == AI_ACTION_BUS_ROUTE && money > AI_MINIMUM_BUS_ROUTE_MONEY) {
|
||||||
|
@ -964,7 +981,7 @@ static void AiNew_State_BuildPath(Player *p) {
|
||||||
static const byte _roadbits_by_dir[4] = {2,1,8,4};
|
static const byte _roadbits_by_dir[4] = {2,1,8,4};
|
||||||
// If they not queue, they have to go up and down to try again at a station...
|
// If they not queue, they have to go up and down to try again at a station...
|
||||||
// We don't want that, so try building some road left or right of the station
|
// We don't want that, so try building some road left or right of the station
|
||||||
short dir1, dir2, dir3;
|
int dir1, dir2, dir3;
|
||||||
TileIndex tile;
|
TileIndex tile;
|
||||||
int i, r;
|
int i, r;
|
||||||
for (i=0;i<2;i++) {
|
for (i=0;i<2;i++) {
|
||||||
|
@ -1000,14 +1017,14 @@ static void AiNew_State_BuildPath(Player *p) {
|
||||||
|
|
||||||
r = CMD_ERROR;
|
r = CMD_ERROR;
|
||||||
if (IS_TILETYPE(tile+dir2, MP_CLEAR) || IS_TILETYPE(tile+dir2, MP_TREES))
|
if (IS_TILETYPE(tile+dir2, MP_CLEAR) || IS_TILETYPE(tile+dir2, MP_TREES))
|
||||||
DoCommandByTile(tile+dir2, AiNew_GetRoadDirection(tile, tile+dir2, tile+dir2+dir2), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
|
r = DoCommandByTile(tile+dir2, AiNew_GetRoadDirection(tile, tile+dir2, tile+dir2+dir2), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||||
if (r != CMD_ERROR)
|
if (r != CMD_ERROR)
|
||||||
if (IS_TILETYPE(tile+dir2+dir2, MP_CLEAR) || IS_TILETYPE(tile+dir2+dir2, MP_TREES))
|
if (IS_TILETYPE(tile+dir2+dir2, MP_CLEAR) || IS_TILETYPE(tile+dir2+dir2, MP_TREES))
|
||||||
DoCommandByTile(tile+dir2+dir2, AiNew_GetRoadDirection(tile+dir2, tile+dir2+dir2, tile+dir2+dir2+dir2), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
|
DoCommandByTile(tile+dir2+dir2, AiNew_GetRoadDirection(tile+dir2, tile+dir2+dir2, tile+dir2+dir2+dir2), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||||
|
|
||||||
r = CMD_ERROR;
|
r = CMD_ERROR;
|
||||||
if (IS_TILETYPE(tile+dir3, MP_CLEAR) || IS_TILETYPE(tile+dir3, MP_TREES))
|
if (IS_TILETYPE(tile+dir3, MP_CLEAR) || IS_TILETYPE(tile+dir3, MP_TREES))
|
||||||
DoCommandByTile(tile+dir3, AiNew_GetRoadDirection(tile, tile+dir3, tile+dir3+dir3), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
|
r = DoCommandByTile(tile+dir3, AiNew_GetRoadDirection(tile, tile+dir3, tile+dir3+dir3), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||||
if (r != CMD_ERROR)
|
if (r != CMD_ERROR)
|
||||||
if (IS_TILETYPE(tile+dir3+dir3, MP_CLEAR) || IS_TILETYPE(tile+dir3+dir3, MP_TREES))
|
if (IS_TILETYPE(tile+dir3+dir3, MP_CLEAR) || IS_TILETYPE(tile+dir3+dir3, MP_TREES))
|
||||||
DoCommandByTile(tile+dir3+dir3, AiNew_GetRoadDirection(tile+dir3, tile+dir3+dir3, tile+dir3+dir3+dir3), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
|
DoCommandByTile(tile+dir3+dir3, AiNew_GetRoadDirection(tile+dir3, tile+dir3+dir3, tile+dir3+dir3+dir3), 0, DC_EXEC | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||||
|
@ -1151,6 +1168,62 @@ static void AiNew_State_RepayMoney(Player *p) {
|
||||||
p->ainew.state = AI_STATE_ACTION_DONE;
|
p->ainew.state = AI_STATE_ACTION_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AiNew_CheckVehicle(Player *p, Vehicle *v) {
|
||||||
|
// When a vehicle is under the 6 months, we don't check for anything
|
||||||
|
if (v->age < 180) return;
|
||||||
|
|
||||||
|
// When a vehicle is older then 1 year, it should make money...
|
||||||
|
if (v->age > 360) {
|
||||||
|
// If both years together are not more then AI_MINIMUM_ROUTE_PROFIT,
|
||||||
|
// it is not worth the line I guess...
|
||||||
|
if (v->profit_last_year + v->profit_this_year < AI_MINIMUM_ROUTE_PROFIT ||
|
||||||
|
(v->reliability * 100 >> 16) < 40) {
|
||||||
|
// There is a possibility that the route is fucked up...
|
||||||
|
if (v->cargo_days > AI_VEHICLE_LOST_DAYS) {
|
||||||
|
// The vehicle is lost.. check the route, or else, get the vehicle
|
||||||
|
// back to a depot
|
||||||
|
// TODO: make this piece of code
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We are already sending him back
|
||||||
|
if (AiNew_GetSpecialVehicleFlag(p, v) & AI_VEHICLEFLAG_SELL) {
|
||||||
|
if (v->type == VEH_Road && IsRoadDepotTile(v->tile) &&
|
||||||
|
(v->vehstatus&VS_STOPPED)) {
|
||||||
|
// We are at the depot, sell the vehicle
|
||||||
|
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AiNew_SetSpecialVehicleFlag(p, v, AI_VEHICLEFLAG_SELL)) return;
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
if (v->type == VEH_Road)
|
||||||
|
res = DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
|
||||||
|
// This means we can not find a depot :s
|
||||||
|
// if (res == CMD_ERROR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks all vehicles if they are still valid and make money and stuff
|
||||||
|
static void AiNew_State_CheckAllVehicles(Player *p) {
|
||||||
|
Vehicle *v;
|
||||||
|
|
||||||
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
if (v->type == 0) continue;
|
||||||
|
if (v->owner != p->index) continue;
|
||||||
|
// Currently, we only know how to handle road-vehicles
|
||||||
|
if (v->type != VEH_Road) continue;
|
||||||
|
|
||||||
|
AiNew_CheckVehicle(p, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
p->ainew.state = AI_STATE_ACTION_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
// Using the technique simular to the original AI
|
// Using the technique simular to the original AI
|
||||||
// Keeps things logical
|
// Keeps things logical
|
||||||
// It really should be in the same order as the AI_STATE's are!
|
// It really should be in the same order as the AI_STATE's are!
|
||||||
|
@ -1171,6 +1244,7 @@ static AiNew_StateFunction* const _ainew_state[] = {
|
||||||
AiNew_State_GiveOrders,
|
AiNew_State_GiveOrders,
|
||||||
AiNew_State_StartVehicle,
|
AiNew_State_StartVehicle,
|
||||||
AiNew_State_RepayMoney,
|
AiNew_State_RepayMoney,
|
||||||
|
AiNew_State_CheckAllVehicles,
|
||||||
AiNew_State_ActionDone,
|
AiNew_State_ActionDone,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
|
@ -187,7 +187,7 @@ static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *curr
|
||||||
// This problem only is valid for tunnels:
|
// This problem only is valid for tunnels:
|
||||||
// When the last tile was not yet a tunnel, check if we enter from the right side..
|
// When the last tile was not yet a tunnel, check if we enter from the right side..
|
||||||
if (!IS_TILETYPE(current->path.node.tile, MP_TUNNELBRIDGE) && (_map5[current->path.node.tile + _tiles_around[i]] & 0x80) == 0) {
|
if (!IS_TILETYPE(current->path.node.tile, MP_TUNNELBRIDGE) && (_map5[current->path.node.tile + _tiles_around[i]] & 0x80) == 0) {
|
||||||
if ((i^2) != (_map5[current->path.node.tile + _tiles_around[i]] & 3)) continue;
|
if (i != (_map5[current->path.node.tile + _tiles_around[i]] & 3)) continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
ai_shared.c
37
ai_shared.c
|
@ -1,7 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "ttd.h"
|
#include "ttd.h"
|
||||||
#include "player.h"
|
|
||||||
#include "ai.h"
|
#include "ai.h"
|
||||||
|
#include "vehicle.h"
|
||||||
|
|
||||||
int AiNew_GetRailDirection(uint tile_a, uint tile_b, uint tile_c) {
|
int AiNew_GetRailDirection(uint tile_a, uint tile_b, uint tile_c) {
|
||||||
// 0 = vert
|
// 0 = vert
|
||||||
|
@ -80,3 +80,38 @@ int AiNew_GetDirection(uint tile_a, uint tile_b) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This functions looks up if this vehicle is special for this AI
|
||||||
|
// and returns his flag
|
||||||
|
uint AiNew_GetSpecialVehicleFlag(Player *p, Vehicle *v) {
|
||||||
|
int 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found :(
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AiNew_SetSpecialVehicleFlag(Player *p, Vehicle *v, uint flag) {
|
||||||
|
int i, new_id = -1;
|
||||||
|
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;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (new_id == -1 && p->ainew.special_vehicles[i].veh_id == 0 &&
|
||||||
|
p->ainew.special_vehicles[i].flag == 0)
|
||||||
|
new_id = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Out of special_vehicle spots :s
|
||||||
|
if (new_id == -1) {
|
||||||
|
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;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
10
player.h
10
player.h
|
@ -80,6 +80,14 @@ typedef struct Ai_PathFinderInfo {
|
||||||
bool rail_or_road; // true = rail, false = road
|
bool rail_or_road; // true = rail, false = road
|
||||||
} Ai_PathFinderInfo;
|
} Ai_PathFinderInfo;
|
||||||
|
|
||||||
|
// The amount of memory reserved for the AI-special-vehicles
|
||||||
|
#define AI_MAX_SPECIAL_VEHICLES 100
|
||||||
|
|
||||||
|
typedef struct Ai_SpecialVehicle {
|
||||||
|
VehicleID veh_id;
|
||||||
|
uint32 flag;
|
||||||
|
} Ai_SpecialVehicle;
|
||||||
|
|
||||||
typedef struct PlayerAiNew {
|
typedef struct PlayerAiNew {
|
||||||
uint8 state;
|
uint8 state;
|
||||||
uint tick;
|
uint tick;
|
||||||
|
@ -105,6 +113,8 @@ typedef struct PlayerAiNew {
|
||||||
byte action;
|
byte action;
|
||||||
|
|
||||||
uint last_id; // here is stored the last id of the searched city/industry
|
uint last_id; // here is stored the last id of the searched city/industry
|
||||||
|
uint last_vehiclecheck_date; // Used in CheckVehicle
|
||||||
|
Ai_SpecialVehicle special_vehicles[AI_MAX_SPECIAL_VEHICLES]; // Some vehicles have some special flags
|
||||||
|
|
||||||
TileIndex from_tile;
|
TileIndex from_tile;
|
||||||
TileIndex to_tile;
|
TileIndex to_tile;
|
||||||
|
|
Loading…
Reference in New Issue