From e9c93f9c0ca76117ac1315b6aff03f1f138f62e4 Mon Sep 17 00:00:00 2001 From: truelight Date: Sun, 6 Feb 2005 10:18:47 +0000 Subject: [PATCH] (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) --- Makefile | 1 + ai.c | 1 + ai_new.c | 3 +- aircraft_gui.c | 1 + airport_gui.c | 1 + depot.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++ depot.h | 51 +++++++++++++++ misc.c | 2 + npf.c | 11 ++-- oldloader.c | 19 ++++-- order_gui.c | 11 ++-- rail_cmd.c | 11 ++-- road_cmd.c | 7 +- roadveh_cmd.c | 27 ++++---- roadveh_gui.c | 14 ++-- saveload.c | 2 + ship_cmd.c | 40 ++++++------ ship_gui.c | 14 ++-- station_cmd.c | 1 + train_cmd.c | 36 ++++------- train_gui.c | 15 ++--- ttd.c | 1 + ttd.dsp | 8 +++ ttd.vcproj | 6 ++ vehicle.c | 73 --------------------- vehicle.h | 27 +------- water_cmd.c | 27 +++----- 27 files changed, 355 insertions(+), 224 deletions(-) create mode 100644 depot.c create mode 100644 depot.h diff --git a/Makefile b/Makefile index d6b359bd63..2ae440659a 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/ai.c b/ai.c index b04c692d46..5e3d9e2bdd 100644 --- a/ai.c +++ b/ai.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; diff --git a/ai_new.c b/ai_new.c index cabd0ee9a7..c3de5fedb2 100644 --- a/ai_new.c +++ b/ai_new.c @@ -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); } diff --git a/aircraft_gui.c b/aircraft_gui.c index 1d3302f071..0a8191b017 100644 --- a/aircraft_gui.c +++ b/aircraft_gui.c @@ -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) diff --git a/airport_gui.c b/airport_gui.c index fec9af2996..7757b8ac9b 100644 --- a/airport_gui.c +++ b/airport_gui.c @@ -11,6 +11,7 @@ #include "vehicle.h" #include "station.h" #include "airport.h" +#include "depot.h" static byte _selected_airport_type; diff --git a/depot.c b/depot.c new file mode 100644 index 0000000000..0430162d26 --- /dev/null +++ b/depot.c @@ -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}, +}; diff --git a/depot.h b/depot.h new file mode 100644 index 0000000000..b2ae02068f --- /dev/null +++ b/depot.h @@ -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 */ diff --git a/misc.c b/misc.c index 546aeeaa87..c011228331 100644 --- a/misc.c +++ b/misc.c @@ -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(); diff --git a/npf.c b/npf.c index 9b81174f88..5a1696436f 100644 --- a/npf.c +++ b/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;ixy, tiletype)) + depots.push(&depots, depot, DistanceManhattan(tile, depot->xy)); } /* Now, let's initialise the aystar */ diff --git a/oldloader.c b/oldloader.c index 24db721cc1..08165476f0 100644 --- a/oldloader.c +++ b/oldloader.c @@ -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)); diff --git a/order_gui.c b/order_gui.c index df4db8f195..7cbd0089c8 100644 --- a/order_gui.c +++ b/order_gui.c @@ -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; diff --git a/rail_cmd.c b/rail_cmd.c index 20827b0fb2..7de16d0fb1 100644 --- a/rail_cmd.c +++ b/rail_cmd.c @@ -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); diff --git a/road_cmd.c b/road_cmd.c index 026b5487e8..a9b2ef350d 100644 --- a/road_cmd.c +++ b/road_cmd.c @@ -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); diff --git a/roadveh_cmd.c b/roadveh_cmd.c index 3a71c58b29..872d91a9ae 100644 --- a/roadveh_cmd.c +++ b/roadveh_cmd.c @@ -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); } diff --git a/roadveh_gui.c b/roadveh_gui.c index 2bbdceab45..4a8128d4e5 100644 --- a/roadveh_gui.c +++ b/roadveh_gui.c @@ -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; diff --git a/saveload.c b/saveload.c index 33e14e965e..d5fabd7cc1 100644 --- a/saveload.c +++ b/saveload.c @@ -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, diff --git a/ship_cmd.c b/ship_cmd.c index 4a6a19ffc0..684d304711 100644 --- a/ship_cmd.c +++ b/ship_cmd.c @@ -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); } } diff --git a/ship_gui.c b/ship_gui.c index 9c953e9f11..0e786aa931 100644 --- a/ship_gui.c +++ b/ship_gui.c @@ -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; diff --git a/station_cmd.c b/station_cmd.c index d592dc3eba..61c09e2c02 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -18,6 +18,7 @@ #include "airport.h" #include "sprite.h" #include "npf.h" +#include "depot.h" enum { /* Max stations: 64000 (64 * 1000) */ diff --git a/train_cmd.c b/train_cmd.c index 5af4f77ab2..a26d37786f 100644 --- a/train_cmd.c +++ b/train_cmd.c @@ -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); } diff --git a/train_gui.c b/train_gui.c index f6656cb425..85a5e8ee04 100644 --- a/train_gui.c +++ b/train_gui.c @@ -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); diff --git a/ttd.c b/ttd.c index 07544364b9..83c3e58cb0 100644 --- a/ttd.c +++ b/ttd.c @@ -30,6 +30,7 @@ #include "screenshot.h" #include "network.h" #include "signs.h" +#include "depot.h" #include diff --git a/ttd.dsp b/ttd.dsp index 37b629833e..b70af23c5a 100644 --- a/ttd.dsp +++ b/ttd.dsp @@ -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 diff --git a/ttd.vcproj b/ttd.vcproj index c5eb890792..648c7aab8b 100644 --- a/ttd.vcproj +++ b/ttd.vcproj @@ -314,6 +314,9 @@ + + @@ -1163,6 +1166,9 @@ + + diff --git a/vehicle.c b/vehicle.c index 9e56287b5f..991f6e6ddf 100644 --- a/vehicle.c +++ b/vehicle.c @@ -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}, }; diff --git a/vehicle.h b/vehicle.h index 9e056edf9b..689118bca9 100644 --- a/vehicle.h +++ b/vehicle.h @@ -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 diff --git a/water_cmd.c b/water_cmd.c index 5f5a4c59f8..c1533e04c6 100644 --- a/water_cmd.c +++ b/water_cmd.c @@ -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;