diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -130,10 +130,27 @@ void CheckTrainsLengths() } /** - * Update the cached visual effect. + * Update visual effect, power and acceleration caches. + * Called when a vehicle in the consist enters a different railtype. */ -void Train::UpdateVisualEffect() +void Train::RailtypeChanged() { + for (Train *u = this; u != NULL; u = u->Next()) { + /* The wagon-is-powered-state should not change, so the weight does not change. */ + u->UpdateVisualEffect(false); + } + this->PowerChanged(); + if (this->IsFrontEngine()) this->UpdateAcceleration(); +} + +/** + * Update the cached visual effect. + * @param allow_power_change true if the wagon-is-powered-state may change. + */ +void Train::UpdateVisualEffect(bool allow_power_change) +{ + byte powered_before = this->tcache.cached_vis_effect & 0x80; + const Engine *e = Engine::Get(this->engine_type); if (e->u.rail.visual_effect != 0) { this->tcache.cached_vis_effect = e->u.rail.visual_effect; @@ -156,6 +173,11 @@ void Train::UpdateVisualEffect() if (callback != CALLBACK_FAILED) this->tcache.cached_vis_effect = GB(callback, 0, 8); } + + if (!allow_power_change && powered_before != (this->tcache.cached_vis_effect & 0x80)) { + this->tcache.cached_vis_effect ^= 0x80; + ShowNewGrfVehicleError(this->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_POWERED_WAGON, GBUG_VEH_POWERED_WAGON, false); + } } /** @@ -215,7 +237,7 @@ void Train::ConsistChanged(bool same_len u->colourmap = PAL_NONE; /* Update powered-wagon-status and visual effect */ - u->UpdateVisualEffect(); + u->UpdateVisualEffect(true); if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON && UsesWagonOverride(u) && !HasBit(u->tcache.cached_vis_effect, 7)) { @@ -1566,7 +1588,7 @@ static void ReverseTrainSwapVeh(Train *v } /* Update power of the train in case tiles were different rail type. */ - v->PowerChanged(); + v->RailtypeChanged(); } @@ -3367,8 +3389,7 @@ static void TrainController(Train *v, Ve v->tile = gp.new_tile; if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) { - v->First()->PowerChanged(); - v->First()->UpdateAcceleration(); + v->First()->RailtypeChanged(); } v->track = chosen_track;