(svn r1817) -Codechange: Moved depot-functions to depot.c

-Codechange: Added wrappers around depot-access (GetDepot no exists)
-Codechange: Made depot-functions a bit more logic (no longer 
GetDepotByTile crashes your game when you request it on a non-depot tile)
-Add: made depots dynamic (yes, 64k depots are possible now)
pull/155/head
truelight 20 years ago
parent e4913f1de8
commit bd7f37d592

@ -563,6 +563,7 @@ C_SOURCES += console.c
C_SOURCES += console_cmds.c
C_SOURCES += debug.c
C_SOURCES += dedicated.c
C_SOURCES += depot.c
C_SOURCES += disaster_cmd.c
C_SOURCES += dock_gui.c
C_SOURCES += dummy_land.c

@ -12,6 +12,7 @@
#include "pathfind.h"
#include "economy.h"
#include "airport.h"
#include "depot.h"
// remove some day perhaps?
static Player *_cur_ai_player;

@ -26,6 +26,7 @@
#include "station.h"
#include "engine.h"
#include "gui.h"
#include "depot.h"
// This function is called after StartUp. It is the init of an AI
static void AiNew_State_FirstTime(Player *p) {
@ -1166,7 +1167,7 @@ static void AiNew_State_GiveOrders(Player *p) {
idx = 2;
order.type = OT_GOTO_DEPOT;
order.flags = OF_UNLOAD;
order.station = GetDepotByTile(p->ainew.depot_tile);
order.station = GetDepotByTile(p->ainew.depot_tile)->index;
DoCommandByTile(0, p->ainew.veh_id + (idx << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER);
}

@ -13,6 +13,7 @@
#include "engine.h"
#include "viewport.h"
#include "player.h"
#include "depot.h"
void Set_DPARAM_Aircraft_Build_Window(uint16 engine_number)

@ -11,6 +11,7 @@
#include "vehicle.h"
#include "station.h"
#include "airport.h"
#include "depot.h"
static byte _selected_airport_type;

@ -0,0 +1,169 @@
#include "stdafx.h"
#include "ttd.h"
#include "depot.h"
#include "tile.h"
#include "map.h"
#include "table/strings.h"
#include "saveload.h"
#include "order.h"
enum {
/* Max depots: 64000 (8 * 8000) */
DEPOT_POOL_BLOCK_SIZE_BITS = 3, /* In bits, so (1 << 3) == 8 */
DEPOT_POOL_MAX_BLOCKS = 8000,
};
/**
* Called if a new block is added to the depot-pool
*/
static void DepotPoolNewBlock(uint start_item)
{
Depot *depot;
FOR_ALL_DEPOTS_FROM(depot, start_item)
depot->index = start_item++;
}
/* Initialize the town-pool */
MemoryPool _depot_pool = { "Depots", DEPOT_POOL_MAX_BLOCKS, DEPOT_POOL_BLOCK_SIZE_BITS, sizeof(Depot), &DepotPoolNewBlock, 0, 0, NULL };
/**
* Gets a depot from a tile
*
* @return Returns the depot if the tile had a depot, else it returns NULL
*/
Depot *GetDepotByTile(uint tile)
{
Depot *depot;
FOR_ALL_DEPOTS(depot) {
if (depot->xy == tile)
return depot;
}
return NULL;
}
/**
* Check if a tile is a road-depot
*/
bool IsRoadDepotTile(TileIndex tile)
{
return IsTileType(tile, MP_STREET) &&
(_map5[tile] & 0xF0) == 0x20;
}
/**
* Check if a tile is a train-depot
*/
bool IsTrainDepotTile(TileIndex tile)
{
return IsTileType(tile, MP_RAILWAY) &&
(_map5[tile] & 0xFC) == 0xC0;
}
/**
* Check if a tile is a ship-depot
*/
bool IsShipDepotTile(TileIndex tile)
{
return IsTileType(tile, MP_WATER) &&
(_map5[tile] & ~3) == 0x80;
}
/**
* Allocate a new depot
*/
Depot *AllocateDepot(void)
{
Depot *depot;
FOR_ALL_DEPOTS(depot) {
if (depot->xy == 0) {
uint index = depot->index;
memset(depot, 0, sizeof(Depot));
depot->index = index;
return depot;
}
}
/* Check if we can add a block to the pool */
if (AddBlockToPool(&_depot_pool))
return AllocateDepot();
return NULL;
}
/**
* Delete a depot
*/
void DoDeleteDepot(uint tile)
{
Order order;
Depot *depot;
/* Get the depot */
depot = GetDepotByTile(tile);
/* Clear the tile */
DoClearSquare(tile);
/* Clear the depot */
depot->xy = 0;
/* Clear the depot from all order-lists */
order.type = OT_GOTO_DEPOT;
order.station = depot->index;
DeleteDestinationFromVehicleOrder(order);
/* Delete the depot-window */
DeleteWindowById(WC_VEHICLE_DEPOT, tile);
}
void InitializeDepot(void)
{
CleanPool(&_depot_pool);
AddBlockToPool(&_depot_pool);
}
static const byte _depot_desc[] = {
SLE_CONDVAR(Depot, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Depot, xy, SLE_UINT32, 6, 255),
SLE_VAR(Depot,town_index, SLE_UINT16),
SLE_END()
};
static void Save_DEPT(void)
{
Depot *depot;
FOR_ALL_DEPOTS(depot) {
if (depot->xy != 0) {
SlSetArrayIndex(depot->index);
SlObject(depot, _depot_desc);
}
}
}
static void Load_DEPT(void)
{
int index;
while ((index = SlIterateArray()) != -1) {
Depot *depot;
if (!AddBlockIfNeeded(&_depot_pool, index))
error("Depots: failed loading savegame: too many depots");
depot = GetDepot(index);
SlObject(depot, _depot_desc);
}
}
const ChunkHandler _depot_chunk_handlers[] = {
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,51 @@
#ifndef DEPOT_H
#define DEPOT_H
#include "pool.h"
struct Depot {
TileIndex xy;
uint16 town_index;
uint16 index;
};
extern MemoryPool _depot_pool;
/**
* Get the pointer to the depot with index 'index'
*/
static inline Depot *GetDepot(uint index)
{
return (Depot*)GetItemFromPool(&_depot_pool, index);
}
/**
* Get the current size of the DepotPool
*/
static inline uint16 GetDepotPoolSize(void)
{
return _depot_pool.total_items;
}
#define FOR_ALL_DEPOTS_FROM(d, start) for (d = GetDepot(start); d != NULL; d = (d->index + 1 < GetDepotPoolSize()) ? GetDepot(d->index + 1) : NULL)
#define FOR_ALL_DEPOTS(d) FOR_ALL_DEPOTS_FROM(d, 0)
#define MIN_SERVINT_PERCENT 5
#define MAX_SERVINT_PERCENT 90
#define MIN_SERVINT_DAYS 30
#define MAX_SERVINT_DAYS 800
VARDEF TileIndex _last_built_train_depot_tile;
VARDEF TileIndex _last_built_road_depot_tile;
VARDEF TileIndex _last_built_aircraft_depot_tile;
VARDEF TileIndex _last_built_ship_depot_tile;
bool IsTrainDepotTile(TileIndex tile);
bool IsRoadDepotTile(TileIndex tile);
Depot *GetDepotByTile(uint tile);
void InitializeDepot(void);
Depot *AllocateDepot(void);
bool IsShipDepotTile(TileIndex tile);
void DoDeleteDepot(uint tile);
#endif /* DEPOT_H */

@ -156,6 +156,7 @@ void CSleep(int milliseconds)
}
void InitializeVehicles(void);
void InitializeDepot(void);
void InitializeOrders(void);
void InitializeClearLand(void);
void InitializeRail(void);
@ -216,6 +217,7 @@ void InitializeGame(uint log_x, uint log_y)
}
InitializeVehicles();
InitializeDepot();
InitializeOrders();
InitNewsItemStructs();

11
npf.c

@ -7,6 +7,7 @@
#include "pathfind.h"
#include "station.h"
#include "tile.h"
#include "depot.h"
AyStar _train_find_station;
AyStar _train_find_depot;
@ -605,7 +606,6 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, Tran
* for ships, since the heuristic will not be to far off then. I hope.
*/
Queue depots;
uint i;
TileType tiletype = 0;
int r;
NPFFoundTargetData best_result;
@ -613,6 +613,7 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, Tran
NPFFindStationOrTileData target;
AyStarNode start;
Depot* current;
Depot *depot;
/* This is a little ugly, but it works :-S */
@ -627,11 +628,9 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, Tran
init_InsSort(&depots);
/* Okay, let's find all depots that we can use first */
for (i=0;i<lengthof(_depots);i++) {
int depot_tile = _depots[i].xy;
if (IsTileType(depot_tile, tiletype))
depots.push(&depots, &_depots[i], DistanceManhattan(tile, depot_tile));
FOR_ALL_DEPOTS(depot) {
if (IsTileType(depot->xy, tiletype))
depots.push(&depots, depot, DistanceManhattan(tile, depot->xy));
}
/* Now, let's initialise the aystar */

@ -11,6 +11,7 @@
#include "engine.h"
#include "vehicle.h"
#include "signs.h"
#include "depot.h"
extern byte _name_array[512][32];
extern TileIndex _animated_tile_list[256];
@ -777,15 +778,23 @@ static void FixStation(OldStation *o, int num)
} while (i++,o++,--num);
}
static void FixDepot(Depot *n, OldDepot *o, int num)
static void FixDepot(OldDepot *o, int num)
{
Depot *depot;
uint i = 0;
do {
if (o->xy == 0)
continue;
n->town_index = REMAP_TOWN_IDX(o->town);
n->xy = o->xy;
} while (n++,o++,--num);
if (!AddBlockIfNeeded(&_depot_pool, i))
error("Depots: failed loading savegame: too many depots");
depot = GetDepot(i);
depot->town_index = REMAP_TOWN_IDX(o->town);
depot->xy = o->xy;
} while (i++,o++,--num);
}
static void FixOrder(uint16 *o, int num)
@ -1533,7 +1542,7 @@ bool LoadOldSaveGame(const char *file)
FixIndustry(m->industries, lengthof(m->industries));
FixStation(m->stations, lengthof(m->stations));
FixDepot(_depots, m->depots, lengthof(m->depots));
FixDepot(m->depots, lengthof(m->depots));
FixOrder(m->order_list, lengthof(m->order_list));
FixVehicle(m->vehicles, lengthof(m->vehicles));
FixSubsidy(_subsidies, m->subsidies, lengthof(m->subsidies));

@ -11,6 +11,7 @@
#include "town.h"
#include "command.h"
#include "viewport.h"
#include "depot.h"
static int OrderGetSel(Window *w)
{
@ -110,7 +111,7 @@ static void DrawOrdersWindow(Window *w)
s = STR_GO_TO_AIRPORT_HANGAR;
SetDParam(2, order->station);
} else {
SetDParam(2, _depots[order->station].town_index);
SetDParam(2, GetDepot(order->station)->town_index);
switch (v->type) {
case VEH_Train: s = STR_880E_GO_TO_TRAIN_DEPOT; break;
case VEH_Road: s = STR_9038_GO_TO_ROADVEH_DEPOT; break;
@ -189,7 +190,7 @@ static Order GetOrderCmdFromTile(Vehicle *v, uint tile)
if ((_map5[tile]&0xFC)==0xC0) {
order.type = OT_GOTO_DEPOT;
order.flags = OF_UNLOAD;
order.station = GetDepotByTile(tile);
order.station = GetDepotByTile(tile)->index;
return order;
}
}
@ -199,7 +200,7 @@ static Order GetOrderCmdFromTile(Vehicle *v, uint tile)
if ((_map5[tile] & 0xF0) == 0x20 && v->type == VEH_Road && _map_owner[tile] == _local_player) {
order.type = OT_GOTO_DEPOT;
order.flags = OF_UNLOAD;
order.station = GetDepotByTile(tile);
order.station = GetDepotByTile(tile)->index;
return order;
}
break;
@ -223,7 +224,7 @@ static Order GetOrderCmdFromTile(Vehicle *v, uint tile)
}
order.type = OT_GOTO_DEPOT;
order.flags = OF_UNLOAD;
order.station = GetDepotByTile(tile);
order.station = GetDepotByTile(tile)->index;
return order;
}
@ -396,7 +397,7 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
xy = GetStation(ord->station)->xy ;
break;
case OT_GOTO_DEPOT: /* goto depot order */
xy = _depots[ord->station].xy;
xy = GetDepot(ord->station)->xy;
break;
case OT_GOTO_WAYPOINT: /* goto waypoint order */
xy = _waypoints[ord->station].xy;

@ -12,6 +12,7 @@
#include "sound.h"
#include "station.h"
#include "sprite.h"
#include "depot.h"
extern uint16 _custom_sprites_base;
@ -632,7 +633,7 @@ int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
uint tile = TILE_FROM_XY(x,y);
int32 cost, ret;
Depot *dep;
Depot *depot;
uint tileh;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@ -649,8 +650,8 @@ int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if (ret == CMD_ERROR) return CMD_ERROR;
cost = ret;
dep = AllocateDepot();
if (dep == NULL)
depot = AllocateDepot();
if (depot == NULL)
return CMD_ERROR;
if (flags & DC_EXEC) {
@ -664,8 +665,8 @@ int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
p2 | RAIL_TYPE_DEPOT /* map5 */
);
dep->xy = tile;
dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
depot->xy = tile;
depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
SetSignalsOnBothDir(tile, (p2&1) ? 2 : 1);

@ -11,6 +11,7 @@
#include "gfx.h"
#include "npf.h"
#include "sound.h"
#include "depot.h"
/* When true, GetTrackStatus for roads will treat roads under reconstruction
* as normal roads instead of impassable. This is used when detecting whether
@ -116,12 +117,6 @@ static bool CheckAllowRemoveRoad(uint tile, uint br, bool *edge_road)
return true;
}
bool IsRoadDepotTile(TileIndex tile)
{
return IsTileType(tile, MP_STREET) &&
(_map5[tile] & 0xF0) == 0x20;
}
uint GetRoadBitsByTile(TileIndex tile)
{
uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD);

@ -14,6 +14,7 @@
#include "npf.h"
#include "player.h"
#include "sound.h"
#include "depot.h"
void ShowRoadVehViewWindow(Vehicle *v);
@ -285,7 +286,7 @@ static bool EnumRoadSignalFindDepot(uint tile, RoadFindDepotData *rfdd, int trac
return false;
}
static int FindClosestRoadDepot(Vehicle *v)
static Depot *FindClosestRoadDepot(Vehicle *v)
{
uint tile = v->tile;
int i;
@ -300,7 +301,7 @@ static int FindClosestRoadDepot(Vehicle *v)
if (ftd.best_bird_dist == 0)
return GetDepotByTile(ftd.node.tile); /* Target found */
else
return -1; /* Target not found */
return NULL; /* Target not found */
/* We do not search in two directions here, why should we? We can't reverse right now can we? */
} else {
RoadFindDepotData rfdd;
@ -312,7 +313,7 @@ static int FindClosestRoadDepot(Vehicle *v)
FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, i, (TPFEnumProc*)EnumRoadSignalFindDepot, NULL, &rfdd);
if (rfdd.best_length == (uint)-1)
return -1;
return NULL;
return GetDepotByTile(rfdd.tile);
}
@ -326,7 +327,7 @@ static int FindClosestRoadDepot(Vehicle *v)
int32 CmdSendRoadVehToDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
int depot;
Depot *depot;
if (!IsVehicleIndex(p1)) return CMD_ERROR;
@ -352,14 +353,14 @@ int32 CmdSendRoadVehToDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
}
depot = FindClosestRoadDepot(v);
if (depot < 0)
if (depot == NULL)
return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
if (flags & DC_EXEC) {
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = p2 == 0 ? OF_NON_STOP | OF_FULL_LOAD : 0;
v->current_order.station = (byte)depot;
v->dest_tile = _depots[depot].xy;
v->current_order.station = depot->index;
v->dest_tile = depot->xy;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
}
@ -676,7 +677,7 @@ static void ProcessRoadVehOrder(Vehicle *v)
dist = NULL;
}
} else if (order->type == OT_GOTO_DEPOT) {
v->dest_tile = _depots[order->station].xy;
v->dest_tile = GetDepot(order->station)->xy;
}
InvalidateVehicleOrder(v);
@ -1596,7 +1597,7 @@ void RoadVeh_Tick(Vehicle *v)
static void CheckIfRoadVehNeedsService(Vehicle *v)
{
int i;
Depot *depot;
if (_patches.servint_roadveh == 0 && !v->set_for_replacement)
return;
@ -1620,9 +1621,9 @@ static void CheckIfRoadVehNeedsService(Vehicle *v)
if (v->u.road.slot != NULL)
return;
i = FindClosestRoadDepot(v);
depot = FindClosestRoadDepot(v);
if (i < 0 || DistanceManhattan(v->tile, (&_depots[i])->xy) > 12) {
if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) {
if (v->current_order.type == OT_GOTO_DEPOT && !(
DistanceManhattan(v->tile, v->dest_tile) > 25 && v->set_for_replacement)) {
/* a vehicle needs a greater distance to a depot to loose it than to find it since
@ -1641,8 +1642,8 @@ static void CheckIfRoadVehNeedsService(Vehicle *v)
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = OF_NON_STOP;
v->current_order.station = (byte)i;
v->dest_tile = (&_depots[i])->xy;
v->current_order.station = depot->index;
v->dest_tile = depot->xy;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
}

@ -12,6 +12,7 @@
#include "command.h"
#include "player.h"
#include "engine.h"
#include "depot.h"
void Set_DPARAM_Road_Veh_Build_Window(uint16 engine_number)
{
@ -233,8 +234,8 @@ static void RoadVehViewWndProc(Window *w, WindowEvent *e)
} break;
case OT_GOTO_DEPOT: {
Depot *dep = &_depots[v->current_order.station];
SetDParam(0, dep->town_index);
Depot *depot = GetDepot(v->current_order.station);
SetDParam(0, depot->town_index);
SetDParam(1, v->cur_speed * 10 >> 5);
str = STR_HEADING_FOR_ROAD_DEPOT + _patches.vehicle_speed;
} break;
@ -494,7 +495,7 @@ static void DrawRoadDepotWindow(Window *w)
uint tile;
Vehicle *v;
int num,x,y;
Depot *d;
Depot *depot;
tile = w->window_number;
@ -511,11 +512,10 @@ static void DrawRoadDepotWindow(Window *w)
SetVScrollCount(w, (num + w->hscroll.cap - 1) / w->hscroll.cap);
/* locate the depot struct */
for (d = _depots; d->xy != (TileIndex)tile; d++) {
assert(d < endof(_depots));
}
depot = GetDepotByTile(tile);
assert(depot != NULL);
SetDParam(0, d->town_index);
SetDParam(0, depot->town_index);
DrawWindowWidgets(w);
x = 2;

@ -872,6 +872,7 @@ static void UninitWriteZlib(void)
extern const ChunkHandler _misc_chunk_handlers[];
extern const ChunkHandler _player_chunk_handlers[];
extern const ChunkHandler _veh_chunk_handlers[];
extern const ChunkHandler _depot_chunk_handlers[];
extern const ChunkHandler _order_chunk_handlers[];
extern const ChunkHandler _town_chunk_handlers[];
extern const ChunkHandler _sign_chunk_handlers[];
@ -884,6 +885,7 @@ extern const ChunkHandler _animated_tile_chunk_handlers[];
static const ChunkHandler * const _chunk_handlers[] = {
_misc_chunk_handlers,
_veh_chunk_handlers,
_depot_chunk_handlers,
_order_chunk_handlers,
_industry_chunk_handlers,
_economy_chunk_handlers,

@ -14,6 +14,7 @@
#include "player.h"
#include "sound.h"
#include "npf.h"
#include "depot.h"
static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
static const byte _ship_sometracks[4] = {0x19, 0x16, 0x25, 0x2A};
@ -63,30 +64,31 @@ int GetShipImage(Vehicle *v, byte direction)
return _ship_sprites[spritenum] + direction;
}
static int FindClosestShipDepot(Vehicle *v)
static Depot *FindClosestShipDepot(Vehicle *v)
{
Depot *depot;
Depot *best_depot = NULL;
uint tile, dist, best_dist = (uint)-1;
int best_depot = -1;
int i;
byte owner = v->owner;
uint tile2 = v->tile;
if (_patches.new_pathfinding_all) {
NPFFoundTargetData ftd;
byte trackdir = _track_direction_to_trackdir[FIND_FIRST_BIT(v->u.ship.state)][v->direction];
ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_ROAD);
/* XXX --- SLOW!!!! */
ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER);
if (ftd.best_bird_dist == 0)
best_depot = ftd.node.tile; /* Found target */
best_depot = GetDepotByTile(ftd.node.tile); /* Found target */
else
best_depot = -1; /* Did not find target */
best_depot = NULL; /* Did not find target */
} else {
for(i=0; i!=lengthof(_depots); i++) {
tile = _depots[i].xy;
FOR_ALL_DEPOTS(depot) {
tile = depot->xy;
if (IsTileType(tile, MP_WATER) && _map_owner[tile] == owner) {
dist = DistanceManhattan(tile, tile2);
if (dist < best_dist) {
best_dist = dist;
best_depot = i;
best_depot = depot;
}
}
}
@ -96,7 +98,7 @@ static int FindClosestShipDepot(Vehicle *v)
static void CheckIfShipNeedsService(Vehicle *v)
{
int i;
Depot *depot;
if (_patches.servint_ships == 0 && !v->set_for_replacement)
return;
@ -114,9 +116,9 @@ static void CheckIfShipNeedsService(Vehicle *v)
if (_patches.gotodepot && VehicleHasDepotOrders(v))
return;
i = FindClosestShipDepot(v);
depot = FindClosestShipDepot(v);
if (i < 0 || DistanceManhattan(v->tile, (&_depots[i])->xy) > 12) {
if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) {
if (v->current_order.type == OT_GOTO_DEPOT) {
v->current_order.type = OT_DUMMY;
v->current_order.flags = 0;
@ -127,8 +129,8 @@ static void CheckIfShipNeedsService(Vehicle *v)
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = OF_NON_STOP;
v->current_order.station = (byte)i;
v->dest_tile = (&_depots[i])->xy;
v->current_order.station = depot->index;
v->dest_tile = depot->xy;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
}
@ -261,7 +263,7 @@ static void ProcessShipOrder(Vehicle *v)
v->dest_tile = TILE_ADD(st->dock_tile, ToTileIndexDiff(_dock_offs[_map5[st->dock_tile]-0x4B]));
}
} else if (order->type == OT_GOTO_DEPOT) {
v->dest_tile = _depots[order->station].xy;
v->dest_tile = GetDepot(order->station)->xy;
} else {
v->dest_tile = 0;
}
@ -1009,7 +1011,7 @@ int32 CmdStartStopShip(int x, int y, uint32 flags, uint32 p1, uint32 p2)
int32 CmdSendShipToDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
int depot;
Depot *depot;
if (!IsVehicleIndex(p1)) return CMD_ERROR;
@ -1032,14 +1034,14 @@ int32 CmdSendShipToDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
}
} else {
depot = FindClosestShipDepot(v);
if (depot < 0)
if (depot == NULL)
return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
if (flags & DC_EXEC) {
v->dest_tile = _depots[depot].xy;
v->dest_tile = depot->xy;
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = HASBIT(p2, 0) ? 0 : OF_NON_STOP | OF_FULL_LOAD;
v->current_order.station = depot;
v->current_order.station = depot->index;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
}
}

@ -12,6 +12,7 @@
#include "command.h"
#include "player.h"
#include "engine.h"
#include "depot.h"
void Set_DPARAM_Ship_Build_Window(uint16 engine_number)
{
@ -518,8 +519,8 @@ static void ShipViewWndProc(Window *w, WindowEvent *e) {
} break;
case OT_GOTO_DEPOT: {
Depot *dep = &_depots[v->current_order.station];
SetDParam(0, dep->town_index);
Depot *depot = GetDepot(v->current_order.station);
SetDParam(0, depot->town_index);
SetDParam(1, v->cur_speed * 10 >> 5);
str = STR_HEADING_FOR_SHIP_DEPOT + _patches.vehicle_speed;
} break;
@ -627,7 +628,7 @@ static void DrawShipDepotWindow(Window *w)
uint tile;
Vehicle *v;
int num,x,y;
Depot *d;
Depot *depot;
tile = w->window_number;
@ -644,11 +645,10 @@ static void DrawShipDepotWindow(Window *w)
SetVScrollCount(w, (num + w->hscroll.cap - 1) / w->hscroll.cap);
/* locate the depot struct */
for (d = _depots; d->xy != (TileIndex)tile; d++) {
assert(d < endof(_depots));
}
depot = GetDepotByTile(tile);
assert(depot != NULL);
SetDParam(0, d->town_index);
SetDParam(0, depot->town_index);
DrawWindowWidgets(w);
x = 2;

@ -18,6 +18,7 @@
#include "airport.h"
#include "sprite.h"
#include "npf.h"
#include "depot.h"
enum {
/* Max stations: 64000 (64 * 1000) */

@ -14,6 +14,7 @@
#include "engine.h"
#include "player.h"
#include "sound.h"
#include "depot.h"
#define is_firsthead_sprite(spritenum) \
(is_custom_sprite(spritenum) \
@ -627,13 +628,6 @@ int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return value;
}
bool IsTrainDepotTile(TileIndex tile)
{
return IsTileType(tile, MP_RAILWAY) &&
(_map5[tile] & 0xFC) == 0xC0;
}
static bool IsTunnelTile(TileIndex tile)
{
return IsTileType(tile, MP_TUNNELBRIDGE) &&
@ -641,7 +635,7 @@ static bool IsTunnelTile(TileIndex tile)
}
int CheckStoppedInDepot(Vehicle *v)
int CheckTrainStoppedInDepot(Vehicle *v)
{
int count;
TileIndex tile = v->tile;
@ -744,13 +738,13 @@ int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if (dst != NULL) dst_head = GetFirstVehicleInChain(dst);
/* check if all vehicles in the source train are stopped */
if (CheckStoppedInDepot(src_head) < 0)
if (CheckTrainStoppedInDepot(src_head) < 0)
return CMD_ERROR;
/* check if all the vehicles in the dest train are stopped,
* and that the length of the dest train is no longer than XXX vehicles */
if (dst_head != NULL) {
int num = CheckStoppedInDepot(dst_head);
int num = CheckTrainStoppedInDepot(dst_head);
if (num < 0)
return CMD_ERROR;
@ -925,7 +919,7 @@ int32 CmdSellRailWagon(int x, int y, uint32 flags, uint32 p1, uint32 p2)
}
// make sure the vehicle is stopped in the depot
if (CheckStoppedInDepot(first) < 0)
if (CheckTrainStoppedInDepot(first) < 0)
return CMD_ERROR;
@ -1234,7 +1228,7 @@ int32 CmdRefitRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
v = GetVehicle(p1);
if (v->type != VEH_Train || !CheckOwnership(v->owner) || ((CheckStoppedInDepot(v) < 0) && !(SkipStoppedInDepotCheck)))
if (v->type != VEH_Train || !CheckOwnership(v->owner) || ((CheckTrainStoppedInDepot(v) < 0) && !(SkipStoppedInDepotCheck)))
return CMD_ERROR;
SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
@ -1268,14 +1262,6 @@ int32 CmdRefitRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return cost;
}
int GetDepotByTile(uint tile)
{
Depot *d;
int i=0;
for(d=_depots; d->xy != (TileIndex)tile; d++) { i++; }
return i;
}
typedef struct TrainFindDepotData {
uint best_length;
uint tile;
@ -1396,7 +1382,7 @@ int32 CmdTrainGotoDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
v->dest_tile = tfdd.tile;
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = HASBIT(p2, 0) ? 0 : OF_NON_STOP | OF_FULL_LOAD;
v->current_order.station = GetDepotByTile(tfdd.tile);
v->current_order.station = GetDepotByTile(tfdd.tile)->index;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
}
@ -1944,7 +1930,7 @@ static bool ProcessTrainOrder(Vehicle *v)
break;
case OT_GOTO_DEPOT:
v->dest_tile = _depots[order->station].xy;
v->dest_tile = GetDepot(order->station)->xy;
result = CheckReverseTrain(v);
break;
@ -2988,7 +2974,7 @@ void TrainEnterDepot(Vehicle *v, uint tile)
static void CheckIfTrainNeedsService(Vehicle *v)
{
byte depot;
Depot *depot;
TrainFindDepotData tfdd;
if (_patches.servint_trains == 0 && !v->set_for_replacement)
@ -3026,13 +3012,13 @@ static void CheckIfTrainNeedsService(Vehicle *v)
depot = GetDepotByTile(tfdd.tile);
if (v->current_order.type == OT_GOTO_DEPOT &&
v->current_order.station != depot &&
v->current_order.station != depot->index &&
!CHANCE16(3,16))
return;
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = OF_NON_STOP;
v->current_order.station = depot;
v->current_order.station = depot->index;
v->dest_tile = tfdd.tile;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
}

@ -13,7 +13,7 @@
#include "player.h"
#include "engine.h"
#include "vehicle_gui.h"
#include "depot.h"
int _traininfo_vehicle_pitch = 0;
@ -303,7 +303,7 @@ static void DrawTrainDepotWindow(Window *w)
uint tile;
Vehicle *v, *u;
int num,x,y,i, hnum;
Depot *d;
Depot *depot;
tile = w->window_number;
@ -336,11 +336,10 @@ static void DrawTrainDepotWindow(Window *w)
SetHScrollCount(w, hnum);
/* locate the depot struct */
for (d = _depots; d->xy != (TileIndex)tile; d++) {
assert(d < endof(_depots));
}
depot = GetDepotByTile(tile);
assert(depot != NULL);
SetDParam(0, d->town_index);
SetDParam(0, depot->town_index);
DrawWindowWidgets(w);
x = 2;
@ -850,7 +849,7 @@ static void TrainViewWndProc(Window *w, WindowEvent *e)
} break;
case OT_GOTO_DEPOT: {
Depot *dep = &_depots[v->current_order.station];
Depot *dep = GetDepot(v->current_order.station);
SetDParam(0, dep->town_index);
str = STR_HEADING_FOR_TRAIN_DEPOT + _patches.vehicle_speed;
SetDParam(1, v->u.rail.last_speed * 10 >> 4);
@ -927,7 +926,7 @@ static void TrainViewWndProc(Window *w, WindowEvent *e)
v = GetVehicle(w->window_number);
assert(v->type == VEH_Train);
h = CheckStoppedInDepot(v) >= 0 ? (1 << 9) : (1 << 12);
h = CheckTrainStoppedInDepot(v) >= 0 ? (1 << 9) : (1 << 12);
if (h != w->hidden_state) {
w->hidden_state = h;
SetWindowDirty(w);

@ -30,6 +30,7 @@
#include "screenshot.h"
#include "network.h"
#include "signs.h"
#include "depot.h"
#include <stdarg.h>

@ -465,6 +465,10 @@ SOURCE=.\console.h
SOURCE=.\debug.h
# End Source File
# Begin Source File
SOURCE=.\depot.h
# End Source File
# Begin Source File
SOURCE=.\economy.h
# End Source File
@ -711,6 +715,10 @@ SOURCE=.\aircraft_cmd.c
SOURCE=.\clear_cmd.c
# End Source File
# Begin Source File
SOURCE=.\debug.c
# End Source File
# Begin Source File
SOURCE=.\disaster_cmd.c
# End Source File

@ -314,6 +314,9 @@
</File>
<File
RelativePath=".\dedicated.c">
</File>
<File
RelativePath=".\depot.c">
</File>
<File
RelativePath="economy.c">
@ -1163,6 +1166,9 @@
<File
RelativePath="debug.h">
</File>
<File
RelativePath="depot.h">
</File>
<File
RelativePath="economy.h">
</File>

@ -353,7 +353,6 @@ void InitializeVehicles(void)
// clear it...
memset(&_waypoints, 0, sizeof(_waypoints));
memset(&_depots, 0, sizeof(_depots));
memset(_vehicle_position_hash, -1, sizeof(_vehicle_position_hash));
}
@ -397,29 +396,6 @@ int CountVehiclesInChain(Vehicle *v)
return count;
}
Depot *AllocateDepot(void)
{
Depot *dep, *free_dep = NULL;
int num_free = 0;
for(dep = _depots; dep != endof(_depots); dep++) {
if (dep->xy == 0) {
num_free++;
if (free_dep==NULL)
free_dep = dep;
}
}
if (free_dep == NULL ||
(num_free < 30 && IS_HUMAN_PLAYER(_current_player))) {
_error_message = STR_1009_TOO_MANY_DEPOTS;
return NULL;
}
return free_dep;
}
Waypoint *AllocateWaypoint(void)
{
Waypoint *cp;
@ -440,27 +416,6 @@ uint GetWaypointByTile(uint tile)
return i;
}
void DoDeleteDepot(uint tile)
{
Order order;
byte dep_index;
Depot *d;
// Clear it
DoClearSquare(tile);
// Nullify the depot struct
for(d=_depots,dep_index=0; d->xy != (TileIndex)tile; d++) {dep_index++;}
d->xy = 0;
order.type = OT_GOTO_DEPOT;
order.station = dep_index;
DeleteDestinationFromVehicleOrder(order);
// Delete the depot
DeleteWindowById(WC_VEHICLE_DEPOT, tile);
}
void DeleteVehicle(Vehicle *v)
{
DeleteName(v->string_id);
@ -2110,33 +2065,6 @@ static void Load_VEHS(void)
_vehicle_id_ctr_day = 0;
}
static const byte _depot_desc[] = {
SLE_CONDVAR(Depot, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Depot, xy, SLE_UINT32, 6, 255),
SLE_VAR(Depot,town_index, SLE_UINT16),
SLE_END()
};
static void Save_DEPT(void)
{
Depot *d;
int i;
for(i=0,d=_depots; i!=lengthof(_depots); i++,d++) {
if (d->xy != 0) {
SlSetArrayIndex(i);
SlObject(d, _depot_desc);
}
}
}
static void Load_DEPT(void)
{
int index;
while ((index = SlIterateArray()) != -1) {
SlObject(&_depots[index], _depot_desc);
}
}
static const byte _waypoint_desc[] = {
SLE_CONDVAR(Waypoint, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Waypoint, xy, SLE_UINT32, 6, 255),
@ -2171,7 +2099,6 @@ static void Load_CHKP(void)
const ChunkHandler _veh_chunk_handlers[] = {
{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY},
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY},
{ 'CHKP', Save_CHKP, Load_CHKP, CH_ARRAY | CH_LAST},
};

@ -200,11 +200,6 @@ struct Vehicle {
#define is_custom_firsthead_sprite(x) (x == 0xfd)
#define is_custom_secondhead_sprite(x) (x == 0xfe)
struct Depot {
TileIndex xy;
uint16 town_index;
};
// train waypoint
struct Waypoint {
TileIndex xy;
@ -280,14 +275,11 @@ void DeleteVehicleChain(Vehicle *v);
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc);
void CallVehicleTicks(void);
Depot *AllocateDepot(void);
Waypoint *AllocateWaypoint(void);
void UpdateWaypointSign(Waypoint *cp);
void RedrawWaypointSign(Waypoint *cp);
void InitializeTrains(void);
bool IsTrainDepotTile(TileIndex tile);
bool IsRoadDepotTile(TileIndex tile);
bool CanFillVehicle(Vehicle *v);
@ -330,19 +322,15 @@ void EndVehicleMove(Vehicle *v);
bool IsAircraftHangarTile(TileIndex tile);
void ShowAircraftViewWindow(Vehicle *v);
bool IsShipDepotTile(TileIndex tile);
UnitID GetFreeUnitNumber(byte type);
int LoadUnloadVehicle(Vehicle *v);
int GetDepotByTile(uint tile);
uint GetWaypointByTile(uint tile);
void DoDeleteDepot(uint tile);
void UpdateTrainAcceleration(Vehicle *v);
int32 GetTrainRunningCost(Vehicle *v);
int CheckStoppedInDepot(Vehicle *v);
int CheckTrainStoppedInDepot(Vehicle *v);
bool VehicleNeedsService(const Vehicle *v);
@ -434,8 +422,6 @@ static inline Vehicle *GetFirstVehicleFromSharedList(Vehicle *v)
return u;
}
VARDEF Depot _depots[255];
// 128 waypoints
VARDEF Waypoint _waypoints[128];
@ -452,22 +438,11 @@ VARDEF uint16 _aircraft_refit_capacity;
VARDEF byte _cmd_build_rail_veh_score;
VARDEF byte _cmd_build_rail_veh_var1;
// NOSAVE: Player specific info
VARDEF TileIndex _last_built_train_depot_tile;
VARDEF TileIndex _last_built_road_depot_tile;
VARDEF TileIndex _last_built_aircraft_depot_tile;
VARDEF TileIndex _last_built_ship_depot_tile;
// for each player, for each vehicle type, keep a list of the vehicles.
//VARDEF Vehicle *_vehicle_arr[8][4];
#define INVALID_VEHICLE 0xffff
#define MIN_SERVINT_PERCENT 5
#define MAX_SERVINT_PERCENT 90
#define MIN_SERVINT_DAYS 30
#define MAX_SERVINT_DAYS 800
/* A lot of code calls for the invalidation of the status bar, which is widget 5.
* Best is to have a virtual value for it when it needs to change again */
#define STATUS_BAR 5

@ -9,14 +9,10 @@
#include "town.h"
#include "news.h"
#include "sound.h"
#include "depot.h"
static void FloodVehicle(Vehicle *v);
bool IsShipDepotTile(TileIndex tile)
{
return IsTileType(tile, MP_WATER) && (_map5[tile] & ~3) == 0x80;
}
static bool IsClearWaterTile(uint tile)
{
TileInfo ti;
@ -33,7 +29,7 @@ int32 CmdBuildShipDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
uint tile, tile2;
int32 cost, ret;
Depot *dep;
Depot *depot;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@ -57,14 +53,14 @@ int32 CmdBuildShipDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
// pretend that we're not making land from the water even though we actually are.
cost = 0;
dep = AllocateDepot();
if (dep == NULL)
depot = AllocateDepot();
if (depot == NULL)
return CMD_ERROR;
if (flags & DC_EXEC) {
dep->xy = tile;
depot->xy = tile;
_last_built_ship_depot_tile = tile;
dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
ModifyTile(tile,
MP_SETTYPE(MP_WATER) | MP_MAPOWNER_CURRENT | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR,
@ -96,17 +92,12 @@ static int32 RemoveShipDepot(uint tile, uint32 flags)
return CMD_ERROR;
if (flags & DC_EXEC) {
Depot *d;
/* Kill the depot */
DoDeleteDepot(tile);
// convert the cleared tiles to water
/* Make the tiles water */
ModifyTile(tile, MP_SETTYPE(MP_WATER) | MP_MAPOWNER | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR, OWNER_WATER, 0);
ModifyTile(tile2, MP_SETTYPE(MP_WATER) | MP_MAPOWNER | MP_MAP5 | MP_MAP2_CLEAR | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR, OWNER_WATER, 0);
// Kill the entry from the depot table
for(d=_depots; d->xy != tile; d++) {}
d->xy = 0;
DeleteWindowById(WC_VEHICLE_DEPOT, tile);
}
return _price.remove_ship_depot;

Loading…
Cancel
Save