437 rfdd.owner = v->owner; |
437 rfdd.owner = v->owner; |
438 rfdd.best_length = (uint)-1; |
438 rfdd.best_length = (uint)-1; |
439 |
439 |
440 /* search in all directions */ |
440 /* search in all directions */ |
441 for (DiagDirection i = DIAGDIR_BEGIN; i != DIAGDIR_END; i++) { |
441 for (DiagDirection i = DIAGDIR_BEGIN; i != DIAGDIR_END; i++) { |
442 FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, v->u.road.compatible_roadtypes, i, EnumRoadSignalFindDepot, NULL, &rfdd); |
442 FollowTrack(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, i, EnumRoadSignalFindDepot, NULL, &rfdd); |
443 } |
443 } |
444 |
444 |
445 if (rfdd.best_length == (uint)-1) return NULL; |
445 if (rfdd.best_length == (uint)-1) return NULL; |
446 |
446 |
447 return GetDepotByTile(rfdd.tile); |
447 return GetDepotByTile(rfdd.tile); |
1278 uint i; |
1278 uint i; |
1279 FOR_EACH_SET_BIT(i, bitmask) { |
1279 FOR_EACH_SET_BIT(i, bitmask) { |
1280 if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track |
1280 if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track |
1281 frd.maxtracklen = (uint)-1; |
1281 frd.maxtracklen = (uint)-1; |
1282 frd.mindist = (uint)-1; |
1282 frd.mindist = (uint)-1; |
1283 FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); |
1283 FollowTrack(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); |
1284 |
1284 |
1285 if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) { |
1285 if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) { |
1286 best_dist = frd.mindist; |
1286 best_dist = frd.mindist; |
1287 best_maxlen = frd.maxtracklen; |
1287 best_maxlen = frd.maxtracklen; |
1288 best_track = (Trackdir)i; |
1288 best_track = (Trackdir)i; |
1518 v->cur_speed = u->First()->cur_speed; |
1518 v->cur_speed = u->First()->cur_speed; |
1519 return false; |
1519 return false; |
1520 } |
1520 } |
1521 } |
1521 } |
1522 |
1522 |
1523 if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) { |
1523 if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) { |
1524 /* Vehicle has just entered a bridge or tunnel */ |
1524 /* Vehicle has just entered a bridge or tunnel */ |
1525 v->cur_image = v->GetImage(v->direction); |
1525 v->cur_image = v->GetImage(v->direction); |
1526 v->UpdateDeltaXY(v->direction); |
1526 v->UpdateDeltaXY(v->direction); |
1527 SetRoadVehPosition(v,gp.x,gp.y); |
1527 SetRoadVehPosition(v,gp.x,gp.y); |
1528 return true; |
1528 return true; |
2002 v->current_order.dest = depot->index; |
2002 v->current_order.dest = depot->index; |
2003 v->dest_tile = depot->xy; |
2003 v->dest_tile = depot->xy; |
2004 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
2004 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
2005 } |
2005 } |
2006 |
2006 |
2007 void OnNewDay_RoadVeh(Vehicle *v) |
2007 void RoadVehicle::OnNewDay() |
2008 { |
2008 { |
2009 CommandCost cost(EXPENSES_ROADVEH_RUN); |
2009 CommandCost cost(EXPENSES_ROADVEH_RUN); |
2010 |
2010 |
2011 if (!IsRoadVehFront(v)) return; |
2011 if (!IsRoadVehFront(this)) return; |
2012 |
2012 |
2013 if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v); |
2013 if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this); |
2014 if (v->u.road.blocked_ctr == 0) CheckVehicleBreakdown(v); |
2014 if (this->u.road.blocked_ctr == 0) CheckVehicleBreakdown(this); |
2015 |
2015 |
2016 AgeVehicle(v); |
2016 AgeVehicle(this); |
2017 CheckIfRoadVehNeedsService(v); |
2017 CheckIfRoadVehNeedsService(this); |
2018 |
2018 |
2019 CheckOrders(v); |
2019 CheckOrders(this); |
2020 |
2020 |
2021 /* Current slot has expired */ |
2021 /* Current slot has expired */ |
2022 if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot != NULL && v->u.road.slot_age-- == 0) { |
2022 if (this->current_order.type == OT_GOTO_STATION && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) { |
2023 DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X", |
2023 DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X", |
2024 v->unitnumber, v->index, v->u.road.slot->xy); |
2024 this->unitnumber, this->index, this->u.road.slot->xy); |
2025 ClearSlot(v); |
2025 ClearSlot(this); |
2026 } |
2026 } |
2027 |
2027 |
2028 if (v->vehstatus & VS_STOPPED) return; |
2028 if (this->vehstatus & VS_STOPPED) return; |
2029 |
2029 |
2030 /* update destination */ |
2030 /* update destination */ |
2031 if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) { |
2031 if (this->current_order.type == OT_GOTO_STATION && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) { |
2032 Station *st = GetStation(v->current_order.dest); |
2032 Station *st = GetStation(this->current_order.dest); |
2033 RoadStop *rs = st->GetPrimaryRoadStop(v); |
2033 RoadStop *rs = st->GetPrimaryRoadStop(this); |
2034 RoadStop *best = NULL; |
2034 RoadStop *best = NULL; |
2035 |
2035 |
2036 if (rs != NULL) { |
2036 if (rs != NULL) { |
2037 /* We try to obtain a slot if: |
2037 /* We try to obtain a slot if: |
2038 * 1) we're reasonably close to the primary road stop |
2038 * 1) we're reasonably close to the primary road stop |
2039 * or |
2039 * or |
2040 * 2) we're somewhere close to the station rectangle (to make sure we do assign |
2040 * 2) we're somewhere close to the station rectangle (to make sure we do assign |
2041 * slots even if the station and its road stops are incredibly spread out) |
2041 * slots even if the station and its road stops are incredibly spread out) |
2042 */ |
2042 */ |
2043 if (DistanceManhattan(v->tile, rs->xy) < 16 || st->rect.PtInExtendedRect(TileX(v->tile), TileY(v->tile), 2)) { |
2043 if (DistanceManhattan(this->tile, rs->xy) < 16 || st->rect.PtInExtendedRect(TileX(this->tile), TileY(this->tile), 2)) { |
2044 uint dist, badness; |
2044 uint dist, badness; |
2045 uint minbadness = UINT_MAX; |
2045 uint minbadness = UINT_MAX; |
2046 |
2046 |
2047 DEBUG(ms, 2, "Attempting to obtain a slot for vehicle %d (index %d) at station %d (0x%X)", |
2047 DEBUG(ms, 2, "Attempting to obtain a slot for vehicle %d (index %d) at station %d (0x%X)", |
2048 v->unitnumber, v->index, st->index, st->xy |
2048 this->unitnumber, this->index, st->index, st->xy |
2049 ); |
2049 ); |
2050 /* Now we find the nearest road stop that has a free slot */ |
2050 /* Now we find the nearest road stop that has a free slot */ |
2051 for (; rs != NULL; rs = rs->GetNextRoadStop(v)) { |
2051 for (; rs != NULL; rs = rs->GetNextRoadStop(this)) { |
2052 dist = RoadFindPathToStop(v, rs->xy); |
2052 dist = RoadFindPathToStop(this, rs->xy); |
2053 if (dist == UINT_MAX) { |
2053 if (dist == UINT_MAX) { |
2054 DEBUG(ms, 4, " stop 0x%X is unreachable, not treating further", rs->xy); |
2054 DEBUG(ms, 4, " stop 0x%X is unreachable, not treating further", rs->xy); |
2055 continue; |
2055 continue; |
2056 } |
2056 } |
2057 badness = (rs->num_vehicles + 1) * (rs->num_vehicles + 1) + dist; |
2057 badness = (rs->num_vehicles + 1) * (rs->num_vehicles + 1) + dist; |
2068 |
2068 |
2069 if (best != NULL) { |
2069 if (best != NULL) { |
2070 best->num_vehicles++; |
2070 best->num_vehicles++; |
2071 DEBUG(ms, 3, "Assigned to stop 0x%X", best->xy); |
2071 DEBUG(ms, 3, "Assigned to stop 0x%X", best->xy); |
2072 |
2072 |
2073 v->u.road.slot = best; |
2073 this->u.road.slot = best; |
2074 v->dest_tile = best->xy; |
2074 this->dest_tile = best->xy; |
2075 v->u.road.slot_age = 14; |
2075 this->u.road.slot_age = 14; |
2076 } else { |
2076 } else { |
2077 DEBUG(ms, 3, "Could not find a suitable stop"); |
2077 DEBUG(ms, 3, "Could not find a suitable stop"); |
2078 } |
2078 } |
2079 } else { |
2079 } else { |
2080 DEBUG(ms, 5, "Distance from station too far. Postponing slotting for vehicle %d (index %d) at station %d, (0x%X)", |
2080 DEBUG(ms, 5, "Distance from station too far. Postponing slotting for vehicle %d (index %d) at station %d, (0x%X)", |
2081 v->unitnumber, v->index, st->index, st->xy); |
2081 this->unitnumber, this->index, st->index, st->xy); |
2082 } |
2082 } |
2083 } else { |
2083 } else { |
2084 DEBUG(ms, 4, "No road stop for vehicle %d (index %d) at station %d (0x%X)", |
2084 DEBUG(ms, 4, "No road stop for vehicle %d (index %d) at station %d (0x%X)", |
2085 v->unitnumber, v->index, st->index, st->xy); |
2085 this->unitnumber, this->index, st->index, st->xy); |
2086 } |
2086 } |
2087 } |
2087 } |
2088 |
2088 |
2089 cost = CommandCost(EXPENSES_ROADVEH_RUN, RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364); |
2089 cost = CommandCost(EXPENSES_ROADVEH_RUN, RoadVehInfo(this->engine_type)->running_cost * _price.roadveh_running / 364); |
2090 |
2090 |
2091 v->profit_this_year -= cost.GetCost() >> 8; |
2091 this->profit_this_year -= cost.GetCost() >> 8; |
2092 |
2092 |
2093 SubtractMoneyFromPlayerFract(v->owner, cost); |
2093 SubtractMoneyFromPlayerFract(this->owner, cost); |
2094 |
2094 |
2095 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
2095 InvalidateWindow(WC_VEHICLE_DETAILS, this->index); |
2096 InvalidateWindowClasses(WC_ROADVEH_LIST); |
2096 InvalidateWindowClasses(WC_ROADVEH_LIST); |
2097 } |
2097 } |
2098 |
2098 |
2099 |
2099 |
2100 void RoadVehiclesYearlyLoop() |
2100 void RoadVehiclesYearlyLoop() |