42 #include "window_func.h" |
41 #include "window_func.h" |
43 #include "date_func.h" |
42 #include "date_func.h" |
44 #include "vehicle_func.h" |
43 #include "vehicle_func.h" |
45 #include "string_func.h" |
44 #include "string_func.h" |
46 #include "signal_func.h" |
45 #include "signal_func.h" |
|
46 #include "oldpool_func.h" |
47 |
47 |
48 #include "table/sprites.h" |
48 #include "table/sprites.h" |
49 #include "table/strings.h" |
49 #include "table/strings.h" |
50 |
50 |
51 DEFINE_OLD_POOL_GENERIC(Station, Station) |
51 DEFINE_OLD_POOL_GENERIC(Station, Station) |
131 st->fsmportsspeclist[1].spec->size_y[st->FSMport_layout_set], |
131 st->fsmportsspeclist[1].spec->size_y[st->FSMport_layout_set], |
132 st->FSMport_orientation); |
132 st->FSMport_orientation); |
133 return st->airport_tile + ToTileIndexDiff(keydepot); |
133 return st->airport_tile + ToTileIndexDiff(keydepot); |
134 } |
134 } |
135 |
135 |
136 RoadStop* GetRoadStopByTile(TileIndex tile, RoadStop::Type type) |
136 RoadStop* GetRoadStopByTile(TileIndex tile, RoadStopType type) |
137 { |
137 { |
138 const Station* st = GetStationByTile(tile); |
138 const Station* st = GetStationByTile(tile); |
139 |
139 |
140 for (RoadStop *rs = st->GetPrimaryRoadStop(type);; rs = rs->next) { |
140 for (RoadStop *rs = st->GetPrimaryRoadStop(type);; rs = rs->next) { |
141 if (rs->xy == tile) return rs; |
141 if (rs->xy == tile) return rs; |
142 assert(rs->next != NULL); |
142 assert(rs->next != NULL); |
143 } |
143 } |
144 } |
144 } |
145 |
145 |
146 |
146 |
147 static uint GetNumRoadStopsInStation(const Station* st, RoadStop::Type type) |
147 static uint GetNumRoadStopsInStation(const Station* st, RoadStopType type) |
148 { |
148 { |
149 uint num = 0; |
149 uint num = 0; |
150 |
150 |
151 assert(st != NULL); |
151 assert(st != NULL); |
152 for (const RoadStop *rs = st->GetPrimaryRoadStop(type); rs != NULL; rs = rs->next) { |
152 for (const RoadStop *rs = st->GetPrimaryRoadStop(type); rs != NULL; rs = rs->next) { |
492 for (uint i = 0; i < num_items; i++) { |
492 for (uint i = 0; i < num_items; i++) { |
493 SetDParam(i + 1, GetCargo(cargo[i])->name); |
493 SetDParam(i + 1, GetCargo(cargo[i])->name); |
494 } |
494 } |
495 |
495 |
496 SetDParam(0, st->index); |
496 SetDParam(0, st->index); |
497 AddNewsItem(msg, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT | NF_TILE, NT_ACCEPTANCE, 0), st->xy, 0); |
497 AddNewsItem(msg, NM_SMALL, NF_VIEWPORT | NF_TILE, NT_ACCEPTANCE, DNC_NONE, st->xy, 0); |
498 } |
498 } |
499 |
499 |
500 /** |
500 /** |
501 * Get a list of the cargo types being produced around the tile (in a rectangle). |
501 * Get a list of the cargo types being produced around the tile (in a rectangle). |
502 * @param produced: Destination array of produced cargo |
502 * @param produced: Destination array of produced cargo |
526 assert(w > 0); |
526 assert(w > 0); |
527 assert(h > 0); |
527 assert(h > 0); |
528 |
528 |
529 for (int yc = y1; yc != y2; yc++) { |
529 for (int yc = y1; yc != y2; yc++) { |
530 for (int xc = x1; xc != x2; xc++) { |
530 for (int xc = x1; xc != x2; xc++) { |
531 if (!(IsInsideBS(xc, x, w) && IsInsideBS(yc, y, h))) { |
531 TileIndex tile = TileXY(xc, yc); |
532 TileIndex tile = TileXY(xc, yc); |
532 |
533 |
533 if (!IsTileType(tile, MP_STATION)) { |
534 GetProducedCargoProc *gpc = _tile_type_procs[GetTileType(tile)]->get_produced_cargo_proc; |
534 GetProducedCargoProc *gpc = _tile_type_procs[GetTileType(tile)]->get_produced_cargo_proc; |
535 if (gpc != NULL) { |
535 if (gpc != NULL) { |
536 CargoID cargos[2] = { CT_INVALID, CT_INVALID }; |
536 CargoID cargos[256]; // Required for CBID_HOUSE_PRODUCE_CARGO. |
|
537 memset(cargos, CT_INVALID, 256); |
537 |
538 |
538 gpc(tile, cargos); |
539 gpc(tile, cargos); |
539 for (uint i = 0; i < lengthof(cargos); ++i) { |
540 for (uint i = 0; i < lengthof(cargos); ++i) { |
540 if (cargos[i] != CT_INVALID) produced[cargos[i]]++; |
541 if (cargos[i] != CT_INVALID) produced[cargos[i]]++; |
541 } |
542 } |
1484 |
1485 |
1485 /* ensure that in case of error (or no DC_EXEC) the new road stop gets deleted upon return */ |
1486 /* ensure that in case of error (or no DC_EXEC) the new road stop gets deleted upon return */ |
1486 AutoPtrT<RoadStop> rs_auto_delete(road_stop); |
1487 AutoPtrT<RoadStop> rs_auto_delete(road_stop); |
1487 |
1488 |
1488 if (st != NULL && |
1489 if (st != NULL && |
1489 GetNumRoadStopsInStation(st, RoadStop::BUS) + GetNumRoadStopsInStation(st, RoadStop::TRUCK) >= RoadStop::LIMIT) { |
1490 GetNumRoadStopsInStation(st, ROADSTOP_BUS) + GetNumRoadStopsInStation(st, ROADSTOP_TRUCK) >= RoadStop::LIMIT) { |
1490 return_cmd_error(type ? STR_TOO_MANY_TRUCK_STOPS : STR_TOO_MANY_BUS_STOPS); |
1491 return_cmd_error(type ? STR_TOO_MANY_TRUCK_STOPS : STR_TOO_MANY_BUS_STOPS); |
1491 } |
1492 } |
1492 |
1493 |
1493 /* In case of new station if DC_EXEC is NOT set we still need to create the station |
1494 /* In case of new station if DC_EXEC is NOT set we still need to create the station |
1494 * to test if everything is OK. In this case we need to delete it before return. */ |
1495 * to test if everything is OK. In this case we need to delete it before return. */ |
1529 /*initialize an empty station */ |
1530 /*initialize an empty station */ |
1530 st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile); |
1531 st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile); |
1531 |
1532 |
1532 st->rect.BeforeAddTile(tile, StationRect::ADD_TRY); |
1533 st->rect.BeforeAddTile(tile, StationRect::ADD_TRY); |
1533 |
1534 |
1534 RoadStop::Type rs_type = type ? RoadStop::TRUCK : RoadStop::BUS; |
1535 RoadStopType rs_type = type ? ROADSTOP_TRUCK : ROADSTOP_BUS; |
1535 if (is_drive_through) { |
1536 if (is_drive_through) { |
1536 MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, rts, (Axis)p1, town_owned_road); |
1537 MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, rts, (Axis)p1, town_owned_road); |
1537 } else { |
1538 } else { |
1538 MakeRoadStop(tile, st->owner, st->index, rs_type, rts, (DiagDirection)p1); |
1539 MakeRoadStop(tile, st->owner, st->index, rs_type, rts, (DiagDirection)p1); |
1539 } |
1540 } |
1575 |
1576 |
1576 RoadStop **primary_stop; |
1577 RoadStop **primary_stop; |
1577 RoadStop *cur_stop; |
1578 RoadStop *cur_stop; |
1578 if (is_truck) { // truck stop |
1579 if (is_truck) { // truck stop |
1579 primary_stop = &st->truck_stops; |
1580 primary_stop = &st->truck_stops; |
1580 cur_stop = GetRoadStopByTile(tile, RoadStop::TRUCK); |
1581 cur_stop = GetRoadStopByTile(tile, ROADSTOP_TRUCK); |
1581 } else { |
1582 } else { |
1582 primary_stop = &st->bus_stops; |
1583 primary_stop = &st->bus_stops; |
1583 cur_stop = GetRoadStopByTile(tile, RoadStop::BUS); |
1584 cur_stop = GetRoadStopByTile(tile, ROADSTOP_BUS); |
1584 } |
1585 } |
1585 |
1586 |
1586 assert(cur_stop != NULL); |
1587 assert(cur_stop != NULL); |
1587 |
1588 |
1588 /* don't do the check for drive-through road stops when company bankrupts */ |
1589 /* don't do the check for drive-through road stops when company bankrupts */ |
2288 |
2289 |
2289 /* station_land array has been increased from 82 elements to 114 |
2290 /* station_land array has been increased from 82 elements to 114 |
2290 * but this is something else. If AI builds station with 114 it looks all weird */ |
2291 * but this is something else. If AI builds station with 114 it looks all weird */ |
2291 DrawGroundSprite(image, HasBit(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE); |
2292 DrawGroundSprite(image, HasBit(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE); |
2292 |
2293 |
2293 if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti); |
2294 if (HasCatenary(GetRailType(ti->tile)) && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti); |
2294 |
2295 |
2295 if (HasBit(roadtypes, ROADTYPE_TRAM)) { |
2296 if (HasBit(roadtypes, ROADTYPE_TRAM)) { |
2296 Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y; |
2297 Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y; |
2297 DrawGroundSprite((HasBit(roadtypes, ROADTYPE_ROAD) ? SPR_TRAMWAY_OVERLAY : SPR_TRAMWAY_TRAM) + (axis ^ 1), PAL_NONE); |
2298 DrawGroundSprite((HasBit(roadtypes, ROADTYPE_ROAD) ? SPR_TRAMWAY_OVERLAY : SPR_TRAMWAY_TRAM) + (axis ^ 1), PAL_NONE); |
2298 DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y); |
2299 DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y); |
2299 } |
2300 } |
|
2301 |
|
2302 /* End now if buildings are invisible */ |
|
2303 if (IsInvisibilitySet(TO_BUILDINGS)) return; |
2300 |
2304 |
2301 const DrawTileSeqStruct *dtss; |
2305 const DrawTileSeqStruct *dtss; |
2302 foreach_draw_tile_seq(dtss, t->seq) { |
2306 foreach_draw_tile_seq(dtss, t->seq) { |
2303 SpriteID image = dtss->image.sprite; |
2307 SpriteID image = dtss->image.sprite; |
2304 if (relocation == 0 || HasBit(image, SPRITE_MODIFIER_USE_OFFSET)) { |
2308 if (relocation == 0 || HasBit(image, SPRITE_MODIFIER_USE_OFFSET)) { |
2510 215, 195, 175, 155, 135, 115, 95, 75, 55, 35, 15, 0 |
2514 215, 195, 175, 155, 135, 115, 95, 75, 55, 35, 15, 0 |
2511 }; |
2515 }; |
2512 |
2516 |
2513 static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y) |
2517 static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, int x, int y) |
2514 { |
2518 { |
|
2519 StationID station_id = GetStationIndex(tile); |
|
2520 if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE; |
|
2521 |
2515 if (v->type == VEH_TRAIN) { |
2522 if (v->type == VEH_TRAIN) { |
2516 if (IsRailwayStation(tile) && IsFrontEngine(v) && |
2523 if (IsRailwayStation(tile) && IsFrontEngine(v) && |
2517 !IsCompatibleTrainStationTile(tile + TileOffsByDiagDir(DirToDiagDir(v->direction)), tile)) { |
2524 !IsCompatibleTrainStationTile(tile + TileOffsByDiagDir(DirToDiagDir(v->direction)), tile)) { |
2518 StationID station_id = GetStationIndex(tile); |
2525 DiagDirection dir = DirToDiagDir(v->direction); |
2519 |
2526 |
2520 if ((!(v->current_order.flags & OFB_NON_STOP) && !_patches.new_nonstop) || |
2527 x &= 0xF; |
2521 (v->current_order.type == OT_GOTO_STATION && v->current_order.dest == station_id)) { |
2528 y &= 0xF; |
2522 if (!(_patches.new_nonstop && v->current_order.flags & OFB_NON_STOP) && |
2529 |
2523 v->current_order.type != OT_LEAVESTATION && |
2530 if (DiagDirToAxis(dir) != AXIS_X) Swap(x, y); |
2524 v->last_station_visited != station_id) { |
2531 if (y == TILE_SIZE / 2) { |
2525 DiagDirection dir = DirToDiagDir(v->direction); |
2532 if (dir != DIAGDIR_SE && dir != DIAGDIR_SW) x = TILE_SIZE - 1 - x; |
2526 |
2533 if (x == 12) return VETSB_ENTERED_STATION | (VehicleEnterTileStatus)(station_id << VETS_STATION_ID_OFFSET); /* enter station */ |
2527 x &= 0xF; |
2534 if (x < 12) { |
2528 y &= 0xF; |
2535 uint16 spd; |
2529 |
2536 |
2530 if (DiagDirToAxis(dir) != AXIS_X) Swap(x, y); |
2537 v->vehstatus |= VS_TRAIN_SLOWING; |
2531 if (y == TILE_SIZE / 2) { |
2538 spd = _enter_station_speedtable[x]; |
2532 if (dir != DIAGDIR_SE && dir != DIAGDIR_SW) x = TILE_SIZE - 1 - x; |
2539 if (spd < v->cur_speed) v->cur_speed = spd; |
2533 if (x == 12) return VETSB_ENTERED_STATION | (VehicleEnterTileStatus)(station_id << VETS_STATION_ID_OFFSET); /* enter station */ |
|
2534 if (x < 12) { |
|
2535 uint16 spd; |
|
2536 |
|
2537 v->vehstatus |= VS_TRAIN_SLOWING; |
|
2538 spd = _enter_station_speedtable[x]; |
|
2539 if (spd < v->cur_speed) v->cur_speed = spd; |
|
2540 } |
|
2541 } |
|
2542 } |
2540 } |
2543 } |
2541 } |
2544 } |
2542 } |
2545 } else if (v->type == VEH_ROAD) { |
2543 } else if (v->type == VEH_ROAD) { |
2546 if (v->u.road.state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)v->u.road.state) && v->u.road.frame == 0) { |
2544 if (v->u.road.state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)v->u.road.state) && v->u.road.frame == 0) { |
2553 byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1; |
2551 byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1; |
2554 |
2552 |
2555 if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER; |
2553 if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER; |
2556 |
2554 |
2557 /* Check if the vehicle is stopping at this road stop */ |
2555 /* Check if the vehicle is stopping at this road stop */ |
2558 if (GetRoadStopType(tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) && |
2556 if (GetRoadStopType(tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && |
2559 v->current_order.dest == GetStationIndex(tile)) { |
2557 v->current_order.GetDestination() == GetStationIndex(tile)) { |
2560 SetBit(v->u.road.state, RVS_IS_STOPPING); |
2558 SetBit(v->u.road.state, RVS_IS_STOPPING); |
2561 rs->AllocateDriveThroughBay(side); |
2559 rs->AllocateDriveThroughBay(side); |
2562 } |
2560 } |
2563 |
2561 |
2564 /* Indicate if vehicle is using second bay. */ |
2562 /* Indicate if vehicle is using second bay. */ |
3030 RebuildStationLists(); |
3028 RebuildStationLists(); |
3031 InvalidateWindowClasses(WC_STATION_LIST); |
3029 InvalidateWindowClasses(WC_STATION_LIST); |
3032 } else { |
3030 } else { |
3033 if (IsDriveThroughStopTile(tile)) { |
3031 if (IsDriveThroughStopTile(tile)) { |
3034 /* Remove the drive-through road stop */ |
3032 /* Remove the drive-through road stop */ |
3035 DoCommand(tile, 0, (GetStationType(tile) == STATION_TRUCK) ? RoadStop::TRUCK : RoadStop::BUS, DC_EXEC | DC_BANKRUPT, CMD_REMOVE_ROAD_STOP); |
3033 DoCommand(tile, 0, (GetStationType(tile) == STATION_TRUCK) ? ROADSTOP_TRUCK : ROADSTOP_BUS, DC_EXEC | DC_BANKRUPT, CMD_REMOVE_ROAD_STOP); |
3036 assert(IsTileType(tile, MP_ROAD)); |
3034 assert(IsTileType(tile, MP_ROAD)); |
3037 /* Change owner of tile and all roadtypes */ |
3035 /* Change owner of tile and all roadtypes */ |
3038 ChangeTileOwner(tile, old_player, new_player); |
3036 ChangeTileOwner(tile, old_player, new_player); |
3039 } else { |
3037 } else { |
3040 DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); |
3038 DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); |