diff --git a/src/tbtr_template_gui_create.cpp b/src/tbtr_template_gui_create.cpp index a21c168636..42dd41c647 100644 --- a/src/tbtr_template_gui_create.cpp +++ b/src/tbtr_template_gui_create.cpp @@ -188,6 +188,9 @@ public: } virtual_train = train; + if (virtual_train != NULL) { + assert(HasBit(virtual_train->subtype, GVSF_VIRTUAL)); + } UpdateButtonState(); } @@ -542,6 +545,7 @@ public: void RearrangeVirtualTrain() { virtual_train = virtual_train->First(); + assert(HasBit(virtual_train->subtype, GVSF_VIRTUAL)); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index a88210baf3..64c086b80b 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1287,6 +1287,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u src = src->GetFirstEnginePart(); if (dst != NULL) { dst = dst->GetFirstEnginePart(); + assert(HasBit(dst->subtype, GVSF_VIRTUAL) == HasBit(src->subtype, GVSF_VIRTUAL)); } /* don't move the same vehicle.. */ @@ -1294,9 +1295,11 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u /* locate the head of the two chains */ Train *src_head = src->First(); + assert(HasBit(src_head->subtype, GVSF_VIRTUAL) == HasBit(src->subtype, GVSF_VIRTUAL)); Train *dst_head; if (dst != NULL) { dst_head = dst->First(); + assert(HasBit(dst_head->subtype, GVSF_VIRTUAL) == HasBit(dst->subtype, GVSF_VIRTUAL)); if (dst_head->tile != src_head->tile) return CMD_ERROR; /* Now deal with articulated part of destination wagon */ dst = dst->GetLastEnginePart(); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 99fce03adb..30bf7c3054 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1154,6 +1154,40 @@ void CallVehicleTicks() } v = NULL; + /* do Template Replacement */ + Backup tmpl_cur_company(_current_company, FILE_LINE); + for (TemplateReplacementMap::iterator it = _vehicles_to_templatereplace.Begin(); it != _vehicles_to_templatereplace.End(); it++) { + Train *t = it->first; + + SCOPE_INFO_FMT([t], "CallVehicleTicks: template replace: %s", scope_dumper().VehicleInfo(t)); + + _vehicles_to_autoreplace.Erase(t); + + /* Store the position of the effect as the vehicle pointer will become invalid later */ + int x = t->x_pos; + int y = t->y_pos; + int z = t->z_pos; + + tmpl_cur_company.Change(t->owner); + + bool stayInDepot = it->second; + + it->first->vehstatus |= VS_STOPPED; + CommandCost res = DoCommand(t->tile, t->index, stayInDepot ? 1 : 0, DC_EXEC, CMD_TEMPLATE_REPLACE_VEHICLE); + + if (!IsLocalCompany()) continue; + + if (res.Succeeded()) { + if (res.GetCost() != 0) { + ShowCostOrIncomeAnimation(x, y, z, res.GetCost()); + } + continue; + } + + ShowAutoReplaceAdviceMessage(res, t); + } + tmpl_cur_company.Restore(); + /* do Auto Replacement */ Backup cur_company(_current_company, FILE_LINE); for (AutoreplaceMap::iterator it = _vehicles_to_autoreplace.Begin(); it != _vehicles_to_autoreplace.End(); it++) { @@ -1161,6 +1195,10 @@ void CallVehicleTicks() /* Autoreplace needs the current company set as the vehicle owner */ cur_company.Change(v->owner); + if (v->type == VEH_TRAIN) { + assert(!_vehicles_to_templatereplace.Contains(Train::From(v))); + } + /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick() * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that * they are already leaving the depot again before being replaced. */ @@ -1187,38 +1225,6 @@ void CallVehicleTicks() } cur_company.Restore(); - /* do Template Replacement */ - Backup tmpl_cur_company(_current_company, FILE_LINE); - for (TemplateReplacementMap::iterator it = _vehicles_to_templatereplace.Begin(); it != _vehicles_to_templatereplace.End(); it++) { - Train *t = it->first; - - SCOPE_INFO_FMT([t], "CallVehicleTicks: template replace: %s", scope_dumper().VehicleInfo(t)); - - /* Store the position of the effect as the vehicle pointer will become invalid later */ - int x = t->x_pos; - int y = t->y_pos; - int z = t->z_pos; - - tmpl_cur_company.Change(t->owner); - - bool stayInDepot = it->second; - - it->first->vehstatus |= VS_STOPPED; - CommandCost res = DoCommand(t->tile, t->index, stayInDepot ? 1 : 0, DC_EXEC, CMD_TEMPLATE_REPLACE_VEHICLE); - - if (!IsLocalCompany()) continue; - - if (res.Succeeded()) { - if (res.GetCost() != 0) { - ShowCostOrIncomeAnimation(x, y, z, res.GetCost()); - } - continue; - } - - ShowAutoReplaceAdviceMessage(res, t); - } - tmpl_cur_company.Restore(); - Backup repair_cur_company(_current_company, FILE_LINE); for (Vehicle *v : _vehicles_to_pay_repair) { SCOPE_INFO_FMT([v], "CallVehicleTicks: repair: %s", scope_dumper().VehicleInfo(v));