diff options
-rw-r--r-- | src/lang/english.txt | 1 | ||||
-rw-r--r-- | src/newgrf_config.h | 5 | ||||
-rw-r--r-- | src/rail_cmd.cpp | 4 | ||||
-rw-r--r-- | src/train.h | 4 | ||||
-rw-r--r-- | src/train_cmd.cpp | 31 |
5 files changed, 34 insertions, 11 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt index 8be19adcc..76397e6f5 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2466,6 +2466,7 @@ STR_NEWGRF_LIST_MISSING :{RED}Missing fi # NewGRF 'it's broken' warnings STR_NEWGRF_BROKEN :{WHITE}Behaviour of NewGRF '{0:RAW_STRING}' is likely to cause desyncs and/or crashes. +STR_NEWGRF_BROKEN_POWERED_WAGON :{WHITE}Wagon '{1:ENGINE}' changed powered-wagon state when not inside a depot. STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}It changes vehicle length for '{1:ENGINE}' when not inside a depot. STR_BROKEN_VEHICLE_LENGTH :{WHITE}Train '{VEHICLE}' belonging to '{COMPANY}' has invalid length. It is probably caused by problems with NewGRFs. Game may desync or crash. diff --git a/src/newgrf_config.h b/src/newgrf_config.h index c4f268e02..e553a01d0 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -39,8 +39,9 @@ enum GRFStatus { /** Encountered GRF bugs */ enum GRFBugs { - GBUG_VEH_LENGTH, ///< Length of rail vehicle changes when not inside a depot - GBUG_VEH_REFIT, ///< Articulated vehicles carry different cargos resp. are differently refittable than specified in purchase list + GBUG_VEH_LENGTH, ///< Length of rail vehicle changes when not inside a depot + GBUG_VEH_REFIT, ///< Articulated vehicles carry different cargos resp. are differently refittable than specified in purchase list + GBUG_VEH_POWERED_WAGON, ///< Powered wagon changed poweredness state when not inside a depot }; /** Status of post-gameload GRF compatibility check */ diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index cab0a304c..a2dcf650d 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1380,7 +1380,6 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data) { if (v->type != VEH_TRAIN) return NULL; - /* Similar checks as in Train::PowerChanged() */ TrainList *affected_trains = static_cast<TrainList*>(data); affected_trains->Include(Train::From(v)->First()); @@ -1583,8 +1582,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (flags & DC_EXEC) { /* Railtype changed, update trains as when entering different track */ for (Train **v = affected_trains.Begin(); v != affected_trains.End(); v++) { - (*v)->PowerChanged(); - (*v)->UpdateAcceleration(); + (*v)->RailtypeChanged(); } } diff --git a/src/train.h b/src/train.h index 885130ba7..2f51871c9 100644 --- a/src/train.h +++ b/src/train.h @@ -145,6 +145,8 @@ struct Train : public GroundVehicle<Train, VEH_TRAIN> { void ConsistChanged(bool same_length); + void RailtypeChanged(); + int UpdateSpeed(); void UpdateAcceleration(); @@ -372,7 +374,7 @@ struct Train : public GroundVehicle<Train, VEH_TRAIN> { protected: // These functions should not be called outside acceleration code. - void UpdateVisualEffect(); + void UpdateVisualEffect(bool allow_power_change); /** * Allows to know the power value that this vehicle will use. diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 442c7d680..70c275925 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -130,10 +130,27 @@ void CheckTrainsLengths() } /** + * Update visual effect, power and acceleration caches. + * Called when a vehicle in the consist enters a different railtype. + */ +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() +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_length) 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, int l, int r) } /* 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, Vehicle *nomove) 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; |