|
@@ -286,25 +286,25 @@ CommandCost CmdBuildRoadVeh(TileIndex ti
|
|
|
for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
|
|
|
u->rcache.cached_veh_length = GetRoadVehLength(u);
|
|
|
/* Cargo capacity is zero if and only if the vehicle cannot carry anything */
|
|
|
if (u->cargo_cap != 0) u->cargo_cap = GetVehicleProperty(u, 0x0F, u->cargo_cap);
|
|
|
v->InvalidateNewGRFCache();
|
|
|
u->InvalidateNewGRFCache();
|
|
|
}
|
|
|
|
|
|
VehicleMove(v, false);
|
|
|
|
|
|
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
|
|
InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
|
|
|
InvalidateWindow(WC_COMPANY, v->owner);
|
|
|
SetWindowDirty(WC_COMPANY, v->owner);
|
|
|
if (IsLocalCompany()) {
|
|
|
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window
|
|
|
}
|
|
|
|
|
|
Company::Get(_current_company)->num_engines[p1]++;
|
|
|
|
|
|
CheckConsistencyOfArticulatedVehicle(v);
|
|
|
}
|
|
|
|
|
|
return cost;
|
|
|
}
|
|
|
|
|
@@ -611,25 +611,25 @@ static void RoadVehCrash(RoadVehicle *v)
|
|
|
v->crashed_ctr++;
|
|
|
|
|
|
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
|
|
if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo.Count();
|
|
|
|
|
|
u->vehstatus |= VS_CRASHED;
|
|
|
|
|
|
MarkSingleVehicleDirty(u);
|
|
|
}
|
|
|
|
|
|
ClearSlot(v);
|
|
|
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
|
|
|
AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING));
|
|
|
|
|
|
SetDParam(0, pass);
|
|
|
AddVehicleNewsItem(
|
|
|
(pass == 1) ?
|
|
|
STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER : STR_NEWS_ROAD_VEHICLE_CRASH,
|
|
|
NS_ACCIDENT,
|
|
|
v->index
|
|
|
);
|
|
|
|
|
|
ModifyStationRatingAround(v->tile, v->owner, -160, 22);
|
|
@@ -654,42 +654,42 @@ static bool RoadVehCheckTrainCrash(RoadV
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
static void HandleBrokenRoadVeh(RoadVehicle *v)
|
|
|
{
|
|
|
if (v->breakdown_ctr != 1) {
|
|
|
v->breakdown_ctr = 1;
|
|
|
v->cur_speed = 0;
|
|
|
|
|
|
if (v->breakdowns_since_last_service != 255)
|
|
|
v->breakdowns_since_last_service++;
|
|
|
|
|
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_VIEW, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
|
|
|
|
|
if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
|
|
|
SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
|
|
|
SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v);
|
|
|
}
|
|
|
|
|
|
if (!(v->vehstatus & VS_HIDDEN)) {
|
|
|
EffectVehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
|
|
|
if (u != NULL) u->animation_state = v->breakdown_delay * 2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ((v->tick_counter & 1) == 0) {
|
|
|
if (--v->breakdown_delay == 0) {
|
|
|
v->breakdown_ctr = 0;
|
|
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_VIEW, v->index);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
TileIndex RoadVehicle::GetOrderStationLocation(StationID station)
|
|
|
{
|
|
|
if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
|
|
|
|
|
|
TileIndex dest;
|
|
|
if (YapfFindNearestRoadVehicleCompatibleStop(this, station, &dest)) {
|
|
|
return dest;
|
|
|
} else {
|
|
@@ -827,25 +827,25 @@ static int RoadVehAccelerate(RoadVehicle
|
|
|
}
|
|
|
|
|
|
v->cur_speed = spd = Clamp(v->cur_speed + ((int)spd >> 8), 0, tempmax);
|
|
|
|
|
|
/* Apply bridge speed limit */
|
|
|
if (v->state == RVSB_WORMHOLE && !(v->vehstatus & VS_HIDDEN)) {
|
|
|
v->cur_speed = min(v->cur_speed, GetBridgeSpec(GetBridgeType(v->tile))->speed * 2);
|
|
|
}
|
|
|
|
|
|
/* Update statusbar only if speed has changed to save CPU time */
|
|
|
if (oldspeed != v->cur_speed) {
|
|
|
if (_settings_client.gui.vehicle_speed) {
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Speed is scaled in the same manner as for trains. @see train_cmd.cpp */
|
|
|
int scaled_spd = spd * 3 >> 2;
|
|
|
|
|
|
scaled_spd += v->progress;
|
|
|
v->progress = 0;
|
|
|
return scaled_spd;
|
|
|
}
|
|
|
|
|
|
static Direction RoadVehGetNewDirection(const RoadVehicle *v, int x, int y)
|
|
@@ -1721,25 +1721,25 @@ again:
|
|
|
DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.GetType());
|
|
|
} else {
|
|
|
if (v->current_order.GetDestination() != st->index)
|
|
|
DEBUG(ms, 2, " current station %d is not target station in current_order.station (%d)",
|
|
|
st->index, v->current_order.GetDestination());
|
|
|
}
|
|
|
|
|
|
DEBUG(ms, 2, " force a slot clearing");
|
|
|
ClearSlot(v);
|
|
|
}
|
|
|
|
|
|
StartRoadVehSound(v);
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
|
|
|
/* Check tile position conditions - i.e. stop position in depot,
|
|
|
* entry onto bridge or into tunnel */
|
|
|
uint32 r = VehicleEnterTile(v, v->tile, x, y);
|
|
|
if (HasBit(r, VETS_CANNOT_ENTER)) {
|
|
|
v->cur_speed = 0;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (v->current_order.IsType(OT_LEAVESTATION) && IsDriveThroughStopTile(v->tile)) {
|
|
|
v->current_order.Free();
|
|
@@ -1836,43 +1836,43 @@ static void CheckIfRoadVehNeedsService(R
|
|
|
VehicleServiceInDepot(v);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
RoadFindDepotData rfdd = FindClosestRoadDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
|
|
|
/* Only go to the depot if it is not too far out of our way. */
|
|
|
if (rfdd.best_length == UINT_MAX || rfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
|
|
|
if (v->current_order.IsType(OT_GOTO_DEPOT)) {
|
|
|
/* If we were already heading for a depot but it has
|
|
|
* suddenly moved farther away, we continue our normal
|
|
|
* schedule? */
|
|
|
v->current_order.MakeDummy();
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
DepotID depot = GetDepotIndex(rfdd.tile);
|
|
|
|
|
|
if (v->current_order.IsType(OT_GOTO_DEPOT) &&
|
|
|
v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS &&
|
|
|
!Chance16(1, 20)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (v->current_order.IsType(OT_LOADING)) v->LeaveStation();
|
|
|
ClearSlot(v);
|
|
|
|
|
|
v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE);
|
|
|
v->dest_tile = rfdd.tile;
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
|
|
|
void RoadVehicle::OnNewDay()
|
|
|
{
|
|
|
if (!this->IsRoadVehFront()) return;
|
|
|
|
|
|
if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
|
|
|
if (this->blocked_ctr == 0) CheckVehicleBreakdown(this);
|
|
|
|
|
|
AgeVehicle(this);
|
|
|
CheckIfRoadVehNeedsService(this);
|
|
|
|
|
@@ -1948,26 +1948,26 @@ void RoadVehicle::OnNewDay()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (this->running_ticks == 0) return;
|
|
|
|
|
|
CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS));
|
|
|
|
|
|
this->profit_this_year -= cost.GetCost();
|
|
|
this->running_ticks = 0;
|
|
|
|
|
|
SubtractMoneyFromCompanyFract(this->owner, cost);
|
|
|
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
|
|
|
InvalidateWindowClasses(WC_ROADVEH_LIST);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
|
|
|
SetWindowClassesDirty(WC_ROADVEH_LIST);
|
|
|
}
|
|
|
|
|
|
Trackdir RoadVehicle::GetVehicleTrackdir() const
|
|
|
{
|
|
|
if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
|
|
|
|
|
|
if (this->IsInDepot()) {
|
|
|
/* We'll assume the road vehicle is facing outwards */
|
|
|
return DiagDirToDiagTrackdir(GetRoadDepotDirection(this->tile));
|
|
|
}
|
|
|
|
|
|
if (IsStandardRoadStopTile(this->tile)) {
|
|
@@ -2060,24 +2060,24 @@ CommandCost CmdRefitRoadVeh(TileIndex ti
|
|
|
|
|
|
total_capacity += capacity;
|
|
|
|
|
|
if (new_cid != v->cargo_type) {
|
|
|
cost.AddCost(GetRefitCost(v->engine_type));
|
|
|
}
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
v->cargo_cap = capacity;
|
|
|
v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
|
|
|
v->cargo_type = new_cid;
|
|
|
v->cargo_subtype = new_subtype;
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
|
|
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
|
|
|
InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (flags & DC_EXEC) RoadVehUpdateCache(RoadVehicle::Get(p1)->First());
|
|
|
|
|
|
_returned_refit_capacity = total_capacity;
|
|
|
|
|
|
return cost;
|
|
|
}
|