Initial whitespace, formatting, file headers and NULL usage fixes.

pull/6/merge
Jonathan G Rennison 8 years ago
parent 6be2efc084
commit a31e7ac87d

@ -25,6 +25,7 @@
#include "vehicle_gui_base.h"
#include "core/geometry_func.hpp"
#include "company_base.h"
#include "tbtr_template_gui_main.h"
#include "widgets/group_widget.h"
@ -34,8 +35,6 @@
static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels
#include "tbtr_template_gui_main.h"
typedef GUIList<const Group*> GUIGroupList;
static const NWidgetPart _nested_group_widgets[] = {
@ -787,8 +786,9 @@ public:
switch (index) {
case ADI_TEMPLATE_REPLACE: // TemplateReplace Window
if ( vli.vtype == VEH_TRAIN )
if (vli.vtype == VEH_TRAIN) {
ShowTemplateReplaceWindow(this->unitnumber_digits, this->resize.step_height);
}
break;
case ADI_REPLACE: // Replace window
ShowReplaceGroupVehicleWindow(this->vli.index, this->vli.vtype);

@ -4969,61 +4969,61 @@ STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
STR_TMPL_RPL_TITLE :{WHITE}Template Replacement
STR_TMPL_TEMPLATE_REPLACEMENT :Template Replacement
STR_TMPL_TRAINS_IN_GROUP :{BLACK}Trains in group
STR_TMPL_AVAILABLE_TEMPLATES :{BLACK}Available Templates
STR_TMPL_DEFINE_TEMPLATE :{BLACK}New
STR_TMPL_EDIT_TEMPLATE :{BLACK}Edit
STR_TMPL_CREATE_CLONE_VEH :{BLACK}Clone
STR_TMPL_DELETE_TEMPLATE :{BLACK}Delete
STR_TMPL_RPL_ALL_TMPL :{BLACK}Replace All Templates
STR_TMPL_NEW_VEHICLE :{BLACK}New Vehicle
STR_TMPL_CONFIRM :{BLACK}Ok
STR_TMPL_CANCEL :{BLACK}Cancel
STR_TMPL_NEW :{BLACK}New Template Vehicle
STR_TMPL_REFIT :{BLACK}Refit
STR_TMPL_GROUP_INFO :{BLACK}Group Info: {ORANGE}
STR_TMPL_TEMPLATE_INFO :{BLACK}Template Info: {ORANGE}
STR_TMPL_RPL_START :{BLACK}Start replacing
STR_TMPL_RPL_STOP :{BLACK}Stop replacing
STR_TMPL_TRAIN_OVR_VALUE :{TINY_FONT}{BLACK}Train Value: {CURRENCY_SHORT}
STR_TMPL_TEMPLATE_OVR_VALUE :{TINY_FONT}{BLACK}Buying Cost: {GOLD}{CURRENCY_LONG}
STR_TMPL_TEMPLATE_OVR_VALUE_nogold :{TINY_FONT}{BLACK}Buying Cost: {CURRENCY_LONG}
STR_TMPL_TEMPLATE_OVR_VALUE_nogoldandcurrency :{TINY_FONT}{BLACK}Buying Cost:
STR_TMPL_TEMPLATE_OVR_VALUE_notinyfont :{BLACK}Buying Cost: {GOLD}{CURRENCY_LONG}
STR_TMPL_TEMPLATE_OVR_VALUE_notinyfontandblack :Buying Cost: {GOLD}{CURRENCY_LONG}
STR_TMPL_WARNING_FREE_WAGON :{RED}Free Chain: not runnable!
STR_TMPL_TEST :{ORANGE}Test String: {RAW_STRING} {RAW_STRING}
STR_TMPL_GROUP_USES_TEMPLATE :{BLACK}Template in use: {NUM}
STR_TMP_TEMPLATE_IN_USE :Template is in use
STR_TMPL_GROUP_NUM_TRAINS :{BLACK}{NUM}
STR_TMPL_CREATEGUI_TITLE :{WHITE}Create/Edit Template Vehicle
STR_TMPL_MAINGUI_DEFINEDGROUPS :{BLACK}Defined Groups for Company
STR_TMPL_TMPLRPL_EX_DIFF_RAILTYPE :Uses Template of different rail type
STR_TMPL_SET_USEDEPOT :{BLACK}Use vehicles in depot
STR_TMPL_SET_USEDEPOT_TIP :{BLACK}Use vehicles inside the depot that are in a neutral and idle state to compose trains on template replacement in order to reduce buying costs
STR_TMPL_SET_KEEPREMAINDERS :{BLACK}Keep remainders
STR_TMPL_SET_KEEPREMAINDERS_TIP :{BLACK}After finishing template replacement keep all remaining vehicles from the old train in a neutral and idle state for later use
STR_TMPL_SET_REFIT :{BLACK}Use Refit
STR_TMPL_SET_REFIT_TIP :{BLACK}If set, the train will use exactly the cargo refit specified by the template. If not every wagon that is to be newly bought or retrieved from the depot, will *attempt* to be refitted as the old one was. Standard refit if this is impossible.
STR_TMPL_CONFIG_USEDEPOT :use depot
STR_TMPL_CONFIG_KEEPREMAINDERS :keep rem
STR_TMPL_CONFIG_REFIT :refit
STR_TMPL_NUM_TRAINS_NEED_RPL :# trains to replace:
STR_TMPL_CARGO_SUMMARY :{CARGO_LONG}
STR_TMPL_CARGO_SUMMARY_MULTI :{CARGO_LONG} (x{NUM})
STR_TMPL_RPLALLGUI_TITLE :{WHITE}Replace all Templace Vehicles
STR_TMPL_RPLALLGUI_INSET_TOP :{BLACK}Choose Vehicle Type and Replacement
STR_TMPL_RPLALLGUI_INSET_TOP_1 :{BLACK}Template Engines
STR_TMPL_RPLALLGUI_INSET_TOP_2 :{BLACK}Buyable Engines
STR_TMPL_RPLALLGUI_INSET_BOTTOM :{BLACK}Current Template List (updated only after replacement)
STR_TMPL_RPLALLGUI_BUTTON_RPLALL :{BLACK}Replace All
STR_TMPL_RPLALLGUI_BUTTON_APPLY :{BLACK}Apply
STR_TMPL_RPLALLGUI_BUTTON_CANCEL :{BLACK}Cancel
STR_TMPL_RPLALLGUI_USE_TIP :{BLACK}Select a vehicle type from each list and press 'Replace All'. If you are happy with the result displayed in the template list, press 'Apply' to actually apply these changes.
STR_TMPL_RPL_TITLE :{WHITE}Template Replacement
STR_TMPL_TEMPLATE_REPLACEMENT :Template Replacement
STR_TMPL_TRAINS_IN_GROUP :{BLACK}Trains in group
STR_TMPL_AVAILABLE_TEMPLATES :{BLACK}Available Templates
STR_TMPL_DEFINE_TEMPLATE :{BLACK}New
STR_TMPL_EDIT_TEMPLATE :{BLACK}Edit
STR_TMPL_CREATE_CLONE_VEH :{BLACK}Clone
STR_TMPL_DELETE_TEMPLATE :{BLACK}Delete
STR_TMPL_RPL_ALL_TMPL :{BLACK}Replace All Templates
STR_TMPL_NEW_VEHICLE :{BLACK}New Vehicle
STR_TMPL_CONFIRM :{BLACK}Ok
STR_TMPL_CANCEL :{BLACK}Cancel
STR_TMPL_NEW :{BLACK}New Template Vehicle
STR_TMPL_REFIT :{BLACK}Refit
STR_TMPL_GROUP_INFO :{BLACK}Group Info: {ORANGE}
STR_TMPL_TEMPLATE_INFO :{BLACK}Template Info: {ORANGE}
STR_TMPL_RPL_START :{BLACK}Start replacing
STR_TMPL_RPL_STOP :{BLACK}Stop replacing
STR_TMPL_TRAIN_OVR_VALUE :{TINY_FONT}{BLACK}Train Value: {CURRENCY_SHORT}
STR_TMPL_TEMPLATE_OVR_VALUE :{TINY_FONT}{BLACK}Buying Cost: {GOLD}{CURRENCY_LONG}
STR_TMPL_TEMPLATE_OVR_VALUE_nogold :{TINY_FONT}{BLACK}Buying Cost: {CURRENCY_LONG}
STR_TMPL_TEMPLATE_OVR_VALUE_nogoldandcurrency :{TINY_FONT}{BLACK}Buying Cost:
STR_TMPL_TEMPLATE_OVR_VALUE_notinyfont :{BLACK}Buying Cost: {GOLD}{CURRENCY_LONG}
STR_TMPL_TEMPLATE_OVR_VALUE_notinyfontandblack :Buying Cost: {GOLD}{CURRENCY_LONG}
STR_TMPL_WARNING_FREE_WAGON :{RED}Free Chain: not runnable!
STR_TMPL_TEST :{ORANGE}Test String: {RAW_STRING} {RAW_STRING}
STR_TMPL_GROUP_USES_TEMPLATE :{BLACK}Template in use: {NUM}
STR_TMP_TEMPLATE_IN_USE :Template is in use
STR_TMPL_GROUP_NUM_TRAINS :{BLACK}{NUM}
STR_TMPL_CREATEGUI_TITLE :{WHITE}Create/Edit Template Vehicle
STR_TMPL_MAINGUI_DEFINEDGROUPS :{BLACK}Defined Groups for Company
STR_TMPL_TMPLRPL_EX_DIFF_RAILTYPE :Uses Template of different rail type
STR_TMPL_SET_USEDEPOT :{BLACK}Use vehicles in depot
STR_TMPL_SET_USEDEPOT_TIP :{BLACK}Use vehicles inside the depot that are in a neutral and idle state to compose trains on template replacement in order to reduce buying costs
STR_TMPL_SET_KEEPREMAINDERS :{BLACK}Keep remainders
STR_TMPL_SET_KEEPREMAINDERS_TIP :{BLACK}After finishing template replacement keep all remaining vehicles from the old train in a neutral and idle state for later use
STR_TMPL_SET_REFIT :{BLACK}Use Refit
STR_TMPL_SET_REFIT_TIP :{BLACK}If set, the train will use exactly the cargo refit specified by the template. If not every wagon that is to be newly bought or retrieved from the depot, will *attempt* to be refitted as the old one was. Standard refit if this is impossible.
STR_TMPL_CONFIG_USEDEPOT :use depot
STR_TMPL_CONFIG_KEEPREMAINDERS :keep rem
STR_TMPL_CONFIG_REFIT :refit
STR_TMPL_NUM_TRAINS_NEED_RPL :# trains to replace:
STR_TMPL_CARGO_SUMMARY :{CARGO_LONG}
STR_TMPL_CARGO_SUMMARY_MULTI :{CARGO_LONG} (x{NUM})
STR_TMPL_RPLALLGUI_TITLE :{WHITE}Replace all Templace Vehicles
STR_TMPL_RPLALLGUI_INSET_TOP :{BLACK}Choose Vehicle Type and Replacement
STR_TMPL_RPLALLGUI_INSET_TOP_1 :{BLACK}Template Engines
STR_TMPL_RPLALLGUI_INSET_TOP_2 :{BLACK}Buyable Engines
STR_TMPL_RPLALLGUI_INSET_BOTTOM :{BLACK}Current Template List (updated only after replacement)
STR_TMPL_RPLALLGUI_BUTTON_RPLALL :{BLACK}Replace All
STR_TMPL_RPLALLGUI_BUTTON_APPLY :{BLACK}Apply
STR_TMPL_RPLALLGUI_BUTTON_CANCEL :{BLACK}Cancel
STR_TMPL_RPLALLGUI_USE_TIP :{BLACK}Select a vehicle type from each list and press 'Replace All'. If you are happy with the result displayed in the template list, press 'Apply' to actually apply these changes.

@ -1772,7 +1772,7 @@ void CheckOrders(const Vehicle *v)
/* Only check every 20 days, so that we don't flood the message log */
/* The check is skipped entirely in case the current vehicle is virtual (a.k.a a 'template train') */
if (v->owner == _local_company && v->day_counter % 20 == 0 && !HasBit(v->subtype, GVSF_VIRTUAL) ) {
if (v->owner == _local_company && v->day_counter % 20 == 0 && !HasBit(v->subtype, GVSF_VIRTUAL)) {
const Order *order;
StringID message = INVALID_STRING_ID;

@ -1,3 +1,14 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_gui_create.cpp Template-based train replacement: template creation GUI. */
#include "stdafx.h"
#include "gfx_func.h"
@ -29,12 +40,13 @@
#include "order_backup.h"
#include "group.h"
#include "company_base.h"
#include "train.h"
#include "tbtr_template_gui_create.h"
#include "tbtr_template_vehicle.h"
#include "tbtr_template_vehicle_func.h"
#include "train.h"
#include "safeguards.h"
class TemplateReplaceWindow;
@ -83,13 +95,13 @@ static const NWidgetPart _widgets[] = {
};
static WindowDesc _template_create_window_desc(
WDP_AUTO, // window position
"template create window", // const char* ini_key
456, 100, // window size
WC_CREATE_TEMPLATE, // window class
WC_NONE, // parent window class
WDF_CONSTRUCTION, // window flags
_widgets, lengthof(_widgets) // widgets + num widgets
WDP_AUTO, // window position
"template create window", // const char* ini_key
456, 100, // window size
WC_CREATE_TEMPLATE, // window class
WC_TEMPLATEGUI_MAIN, // parent window class
WDF_CONSTRUCTION, // window flags
_widgets, lengthof(_widgets) // widgets + num widgets
);
static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Vehicle *head)
@ -107,7 +119,8 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh
if (wagon == v) return;
DoCommandP(v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20 | 1 << 21, wagon == NULL ? INVALID_VEHICLE : wagon->index, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE), CcVirtualTrainWaggonsMoved);
DoCommandP(v->tile, v->index | ((_ctrl_pressed ? 1 : 0) << 20) | (1 << 21) , wagon == NULL ? INVALID_VEHICLE : wagon->index,
CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE), CcVirtualTrainWaggonsMoved);
}
class TemplateCreateWindow : public Window {
@ -118,7 +131,7 @@ private:
Train* virtual_train;
bool editMode;
bool *noticeParent;
bool *createWindowOpen; /// used to notify main window of progress (dummy way of disabling 'delete' while editing a template)
bool *createWindowOpen; /// used to notify main window of progress (dummy way of disabling 'delete' while editing a template)
bool virtualTrainChangedNotice;
VehicleID sel;
VehicleID vehicle_over;
@ -142,8 +155,7 @@ public:
virtualTrainChangedNotice = false;
this->editTemplate = to_edit;
if (to_edit) editMode = true;
else editMode = false;
editMode = (to_edit != NULL);
this->sel = INVALID_VEHICLE;
this->vehicle_over = INVALID_VEHICLE;
@ -157,9 +169,9 @@ public:
~TemplateCreateWindow()
{
if (virtual_train != nullptr) {
if (virtual_train != NULL) {
DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN);
virtual_train = nullptr;
virtual_train = NULL;
}
SetWindowClassesDirty(WC_TRAINS_LIST);
@ -167,12 +179,11 @@ public:
/* more cleanup */
*createWindowOpen = false;
DeleteWindowById(WC_BUILD_VIRTUAL_TRAIN, this->window_number);
}
void SetVirtualTrain(Train* const train)
{
if (virtual_train != nullptr) {
if (virtual_train != NULL) {
DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN);
}
@ -210,19 +221,18 @@ public:
this->SetWidgetDirty(TCW_CLONE);
this->ToggleWidgetLoweredState(TCW_CLONE);
if (this->IsWidgetLowered(TCW_CLONE)) {
static const CursorID clone_icon = SPR_CURSOR_CLONE_TRAIN;
SetObjectToPlaceWnd(clone_icon, PAL_NONE, HT_VEHICLE, this);
SetObjectToPlaceWnd(SPR_CURSOR_CLONE_TRAIN, PAL_NONE, HT_VEHICLE, this);
} else {
ResetObjectToPlace();
}
break;
}
case TCW_OK: {
uint32 templateIndex = (editTemplate != nullptr) ? editTemplate->index : INVALID_VEHICLE;
if (virtual_train != nullptr) {
uint32 templateIndex = (editTemplate != NULL) ? editTemplate->index : INVALID_VEHICLE;
if (virtual_train != NULL) {
DoCommandP(0, templateIndex, virtual_train->index, CMD_REPLACE_TEMPLATE_VEHICLE);
virtual_train = nullptr;
virtual_train = NULL;
} else if (templateIndex != INVALID_VEHICLE) {
DoCommandP(0, templateIndex, 0, CMD_DELETE_TEMPLATE_VEHICLE);
}
@ -243,9 +253,9 @@ public:
virtual bool OnVehicleSelect(const Vehicle *v)
{
// throw away the current virtual train
if (virtual_train != nullptr) {
if (virtual_train != NULL) {
DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN);
virtual_train = nullptr;
virtual_train = NULL;
}
// create a new one
@ -261,8 +271,8 @@ public:
{
switch(widget) {
case TCW_NEW_TMPL_PANEL: {
if ( this->virtual_train ) {
DrawTrainImage(virtual_train, r.left+TRAIN_FRONT_SPACE, r.right-25, r.top+2, this->sel, EIT_PURCHASE, this->hscroll->GetPosition(), this->vehicle_over);
if (this->virtual_train) {
DrawTrainImage(virtual_train, r.left+TRAIN_FRONT_SPACE, r.right - 25, r.top + 2, this->sel, EIT_PURCHASE, this->hscroll->GetPosition(), this->vehicle_over);
SetDParam(0, CeilDiv(virtual_train->gcache.cached_total_length * 10, TILE_SIZE));
SetDParam(1, 1);
DrawString(r.left, r.right, r.top, STR_TINY_BLACK_DECIMAL, TC_BLACK, SA_RIGHT);
@ -270,7 +280,7 @@ public:
break;
}
case TCW_INFO_PANEL: {
if ( this->virtual_train ) {
if (this->virtual_train) {
DrawPixelInfo tmp_dpi, *old_dpi;
if (!FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left, r.bottom - r.top)) break;
@ -287,16 +297,16 @@ public:
DrawString(8, r.right, 4 - this->vscroll->GetPosition(), STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE);
/* Draw cargo summary */
CargoArray cargo_caps;
for ( const Train *tmp=this->virtual_train; tmp; tmp=tmp->Next() )
for (const Train *tmp = this->virtual_train; tmp != NULL; tmp = tmp->Next()) {
cargo_caps[tmp->cargo_type] += tmp->cargo_cap;
}
int y = 30 - this->vscroll->GetPosition();
for (CargoID i = 0; i < NUM_CARGO; ++i) {
if ( cargo_caps[i] > 0 ) {
if (cargo_caps[i] > 0) {
SetDParam(0, i);
SetDParam(1, cargo_caps[i]);
SetDParam(2, _settings_game.vehicle.freight_trains);
DrawString(8, r.right, y, STR_TMPL_CARGO_SUMMARY, TC_LIGHT_BLUE, SA_LEFT);
y += this->line_height/3;
y += this->line_height / 3;
}
}
@ -308,6 +318,7 @@ public:
break;
}
}
virtual void OnTick()
{
if (virtualTrainChangedNotice) {
@ -315,6 +326,7 @@ public:
virtualTrainChangedNotice = false;
}
}
virtual void OnDragDrop(Point pt, int widget)
{
switch (widget) {
@ -344,10 +356,11 @@ public:
Train* train_to_delete = Train::Get(this->sel);
if (virtual_train == train_to_delete)
virtual_train = (_ctrl_pressed) ? nullptr : virtual_train->GetNextUnit();
if (virtual_train == train_to_delete) {
virtual_train = (_ctrl_pressed) ? NULL : virtual_train->GetNextUnit();
}
DoCommandP(0, this->sel | sell_cmd << 20 | 1 << 21, 0, GetCmdSellVeh(VEH_TRAIN));
DoCommandP(0, this->sel | (sell_cmd << 20) | (1 << 21), 0, GetCmdSellVeh(VEH_TRAIN));
this->sel = INVALID_VEHICLE;
@ -357,6 +370,7 @@ public:
default:
this->sel = INVALID_VEHICLE;
this->SetDirty();
break;
}
_cursor.vehchain = false;
this->sel = INVALID_VEHICLE;
@ -408,15 +422,15 @@ public:
uint height = 30;
CargoArray cargo_caps;
if (virtual_train != nullptr) {
for (Train *train = virtual_train; train != nullptr; train = train->Next()) {
if (virtual_train != NULL) {
for (Train *train = virtual_train; train != NULL; train = train->Next()) {
width += train->GetDisplayImageWidth();
cargo_caps[train->cargo_type] += train->cargo_cap;
}
for (CargoID i = 0; i < NUM_CARGO; ++i) {
if ( cargo_caps[i] > 0 ) {
height += this->line_height/3;
if (cargo_caps[i] > 0) {
height += this->line_height / 3;
}
}
}
@ -429,6 +443,7 @@ public:
this->DrawWidgets();
}
struct GetDepotVehiclePtData {
const Vehicle *head;
const Vehicle *wagon;
@ -449,7 +464,7 @@ public:
const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(TCW_NEW_TMPL_PANEL);
/* In case of RTL the widgets are swapped as a whole */
if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x;
x -= TRAIN_FRONT_SPACE;
uint xm = x;
@ -461,7 +476,6 @@ public:
d->head = d->wagon = v;
if (xm <= this->header_width) {
if (wagon) return MODE_ERROR;
return MODE_SHOW_VEHICLE;
@ -494,7 +508,7 @@ public:
if (sel != INVALID_VEHICLE) {
this->sel = INVALID_VEHICLE;
TrainDepotMoveVehicle(v, sel, gdvp.head);
TrainDepotMoveVehicle(v, sel, gdvp.head);
} else if (v != NULL) {
int image = v->GetImage(_current_text_dir == TD_RTL ? DIR_E : DIR_W, EIT_PURCHASE);
SetObjectToPlaceWnd(image, GetVehiclePalette(v), HT_DRAG, this);
@ -515,7 +529,7 @@ public:
void ShowTemplateCreateWindow(TemplateVehicle *to_edit, bool *noticeParent, bool *createWindowOpen, int step_h)
{
if ( BringWindowToFrontById(WC_CREATE_TEMPLATE, VEH_TRAIN) != NULL ) return;
if (BringWindowToFrontById(WC_CREATE_TEMPLATE, VEH_TRAIN) != NULL) return;
new TemplateCreateWindow(&_template_create_window_desc, to_edit, noticeParent, createWindowOpen, step_h);
}
@ -546,4 +560,4 @@ void CcDeleteVirtualTrain(const CommandCost &result, TileIndex tile, uint32 p1,
{
VehicleID virtual_train_id = p2;
DoCommandP(0, virtual_train_id, 0, CMD_DELETE_VIRTUAL_TRAIN);
}
}

@ -1,4 +1,13 @@
// template creation gui
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_gui_create.h Template-based train replacement: template creation GUI header. */
#ifndef TEMPLATE_GUI_CREATE
#define TEMPLATE_GUI_CREATE

@ -1,4 +1,4 @@
/* $Id: build_vehicle_gui.cpp 23792 2012-01-12 19:23:00Z yexo $ */
/* $Id$ */
/*
* This file is part of OpenTTD.
@ -7,7 +7,7 @@
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file build_vehicle_gui.cpp GUI for building vehicles. */
/** @file tbtr_template_gui_create_virtualtrain.cpp Template-based train replacement: template creation vehicle build GUI. */
#include "stdafx.h"
#include "engine_base.h"
@ -30,14 +30,14 @@
#include "engine_gui.h"
#include "cargotype.h"
#include "core/geometry_func.hpp"
#include "vehicle_gui.h"
#include "tbtr_template_gui_create_virtualtrain.h"
#include "widgets/build_vehicle_widget.h"
#include "table/strings.h"
#include "tbtr_template_gui_create_virtualtrain.h"
#include "vehicle_gui.h"
#include "safeguards.h"
static const NWidgetPart _nested_build_vehicle_widgets[] = {
NWidget(NWID_HORIZONTAL),
@ -425,13 +425,13 @@ struct BuildVirtualTrainWindow : Window {
byte cargo_filter_criteria; ///< Selected cargo filter
int details_height; ///< Minimal needed height of the details panels (found so far).
Scrollbar *vscroll;
Train **virtual_train; ///< the virtual train that is currently being created
Train **virtual_train; ///< the virtual train that is currently being created
bool *noticeParent;
BuildVirtualTrainWindow(WindowDesc *desc, Train **vt, bool *notice) : Window(desc)
{
this->vehicle_type = VEH_TRAIN;
this->window_number = 0;//tile == INVALID_TILE ? (int)type : tile;
this->window_number = 0;
this->sel_engine = INVALID_ENGINE;
@ -688,6 +688,7 @@ struct BuildVirtualTrainWindow : Window {
case WID_BV_CARGO_FILTER_DROPDOWN:
SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]);
break;
}
}
@ -717,7 +718,9 @@ struct BuildVirtualTrainWindow : Window {
{
switch (widget) {
case WID_BV_LIST:
DrawEngineList(this->vehicle_type, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, &this->eng_list, this->vscroll->GetPosition(), min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.Length()), this->sel_engine, false, DEFAULT_GROUP);
DrawEngineList(this->vehicle_type, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP,
&this->eng_list, this->vscroll->GetPosition(), min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(),
this->eng_list.Length()), this->sel_engine, false, DEFAULT_GROUP);
break;
case WID_BV_SORT_ASCENDING_DESCENDING:
@ -795,7 +798,7 @@ struct BuildVirtualTrainWindow : Window {
} else {
VehicleID target = (*(this->virtual_train))->GetLastUnit()->index;
DoCommandP(0, (1<<21) | toadd->index, target, CMD_MOVE_RAIL_VEHICLE);
DoCommandP(0, (1 << 21) | toadd->index, target, CMD_MOVE_RAIL_VEHICLE);
}
*noticeParent = true;
}
@ -814,13 +817,13 @@ void CcAddVirtualEngine(const CommandCost &result, TileIndex tile, uint32 p1, ui
}
static WindowDesc _build_vehicle_desc(
WDP_AUTO, // window position
"template create virtual train",// const char* ini_key
240, 268, // window size
WC_BUILD_VIRTUAL_TRAIN, // window class
WC_CREATE_TEMPLATE, // parent window class
WDF_CONSTRUCTION, // window flags
_nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets) // widgets + num widgets
WDP_AUTO, // window position
"template create virtual train", // const char* ini_key
240, 268, // window size
WC_BUILD_VIRTUAL_TRAIN, // window class
WC_CREATE_TEMPLATE, // parent window class
WDF_CONSTRUCTION, // window flags
_nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets) // widgets + num widgets
);
void ShowBuildVirtualTrainWindow(Train **vt, bool *noticeParent)

@ -1,3 +1,14 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_gui_create_virtualtrain.cpp Template-based train replacement: template creation vehicle build GUI header. */
#ifndef BUILD_VIRTUAL_TRAIN_GUI
#define BUILD_VIRTUAL_TRAIN_GUI

@ -1,10 +1,13 @@
// mygui.c
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
//#include "tbtr_mygui.h"
#include <iostream>
#include <stdio.h>
/** @file tbtr_template_gui_main.cpp Template-based train replacement: main GUI. */
#include "stdafx.h"
#include "command_func.h"
@ -47,7 +50,11 @@
#include "tbtr_template_gui_main.h"
#include "tbtr_template_gui_create.h"
#include "tbtr_template_vehicle.h"
//#include "tbtr_template_vehicle_func.h"
#include <iostream>
#include <stdio.h>
#include "safeguards.h"
typedef GUIList<const Group*> GUIGroupList;
@ -168,7 +175,7 @@ static WindowDesc _replace_rail_vehicle_desc(
"template replace window",
456, 156,
WC_TEMPLATEGUI_MAIN,
WC_NONE, // parent window class
WC_NONE, // parent window class
WDF_CONSTRUCTION,
_widgets, lengthof(_widgets)
);
@ -176,7 +183,7 @@ static WindowDesc _replace_rail_vehicle_desc(
class TemplateReplaceWindow : public Window {
private:
GUIGroupList groups; ///< List of groups
GUIGroupList groups; ///< List of groups
byte unitnumber_digits;
SmallVector<int, 16> indents; ///< Indentation levels
@ -207,7 +214,7 @@ public:
this->unitnumber_digits = dig;
this->sel_railtype = RAILTYPE_BEGIN;
this->details_height = 10 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
this->details_height = 10 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
this->line_height = step_h;
@ -311,7 +318,7 @@ public:
this->BuildGroupList(_local_company);
if ( templateNotice ) {
if (templateNotice) {
BuildTemplateGuiList(&this->templates, vscroll[1], _local_company, this->sel_railtype);
templateNotice = false;
this->SetDirty();
@ -333,14 +340,14 @@ public:
short count_columns = 0;
short max_columns = 2;
for ( ; tmp; tmp=tmp->Next()) {
for (; tmp != NULL; tmp = tmp->Next()) {
cargo_caps[tmp->cargo_type] += tmp->cargo_cap;
}
for (CargoID i = 0; i < NUM_CARGO; ++i) {
if ( cargo_caps[i] > 0 ) {
if (cargo_caps[i] > 0) {
if (count_columns % max_columns == 0) {
height += this->line_height/3;
height += this->line_height / 3;
}
++count_columns;
@ -356,7 +363,7 @@ public:
virtual void OnClick(Point pt, int widget, int click_count)
{
if ( this->editInProgress ) return;
if (this->editInProgress) return;
switch (widget) {
case TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REUSE: {
@ -424,28 +431,26 @@ public:
ShowDropDownList(this, GetRailTypeDropDownList(true), sel_railtype, TRW_WIDGET_TRAIN_RAILTYPE_DROPDOWN);
break;
case TRW_WIDGET_TOP_MATRIX: {
uint16 newindex = (uint16)((pt.y - this->nested_array[TRW_WIDGET_TOP_MATRIX]->pos_y) / (this->line_height/2) ) + this->vscroll[0]->GetPosition();
if ( newindex == this->selected_group_index || newindex >= this->groups.Length() ) {
uint16 newindex = (uint16)((pt.y - this->nested_array[TRW_WIDGET_TOP_MATRIX]->pos_y) / (this->line_height / 2) ) + this->vscroll[0]->GetPosition();
if (newindex == this->selected_group_index || newindex >= this->groups.Length()) {
this->selected_group_index = -1;
}
else if ((newindex >= 0) && (newindex < this->groups.Length())) {
} else if (newindex < this->groups.Length()) {
this->selected_group_index = newindex;
}
break;
}
case TRW_WIDGET_BOTTOM_MATRIX: {
uint16 newindex = (uint16)((pt.y - this->nested_array[TRW_WIDGET_BOTTOM_MATRIX]->pos_y) / this->line_height) + this->vscroll[1]->GetPosition();
if ( newindex == this->selected_template_index || newindex >= templates.Length() ) {
if (newindex == this->selected_template_index || newindex >= templates.Length()) {
this->selected_template_index = -1;
}
else if ((newindex >= 0) && (newindex < templates.Length())) {
} else if (newindex < templates.Length()) {
this->selected_template_index = newindex;
}
break;
}
case TRW_WIDGET_START: {
if ((this->selected_template_index >= 0) && (this->selected_template_index < (short)this->templates.Length()) &&
(this->selected_group_index >= 0) && (this->selected_group_index < (short)this->groups.Length())) {
(this->selected_group_index >= 0) && (this->selected_group_index < (short)this->groups.Length())) {
uint32 tv_index = ((this->templates)[selected_template_index])->index;
int current_group_index = (this->groups)[this->selected_group_index]->index;
@ -454,8 +459,9 @@ public:
break;
}
case TRW_WIDGET_STOP:
if ((this->selected_group_index < 0) || (this->selected_group_index >= (short)this->groups.Length()))
if ((this->selected_group_index < 0) || (this->selected_group_index >= (short)this->groups.Length())) {
return;
}
int current_group_index = (this->groups)[this->selected_group_index]->index;
@ -481,7 +487,7 @@ public:
virtual void OnDropdownSelect(int widget, int index)
{
RailType temp = (RailType)index;
RailType temp = (RailType) index;
if (temp == this->sel_railtype) return; // we didn't select a new one. No need to change anything
this->sel_railtype = temp;
/* Reset scrollbar positions */
@ -508,7 +514,7 @@ public:
virtual void OnTick()
{
if ( templateNotice ) {
if (templateNotice) {
BuildTemplateGuiList(&this->templates, this->vscroll[1], this->owner, this->sel_railtype);
this->SetDirty();
templateNotice = false;
@ -527,12 +533,13 @@ public:
short FindTemplateIndexForGroup(short gid) const
{
TemplateReplacement *tr = GetTemplateReplacementByGroupID(gid);
if ( !tr )
return -1;
if (!tr) return -1;
for ( uint32 i=0; i<this->templates.Length(); ++i )
if ( templates[i]->index == tr->sel_template )
for (uint32 i = 0; i < this->templates.Length(); ++i) {
if (templates[i]->index == tr->sel_template) {
return i;
}
}
return -1;
}
@ -604,47 +611,48 @@ public:
int max = min(this->vscroll[0]->GetPosition() + this->vscroll[0]->GetCapacity(), this->groups.Length());
/* Then treat all groups defined by/for the current company */
for ( int i=this->vscroll[0]->GetPosition(); i<max; ++i ) {
for (int i = this->vscroll[0]->GetPosition(); i < max; ++i) {
const Group *g = (this->groups)[i];
short g_id = g->index;
/* Fill the background of the current cell in a darker tone for the currently selected template */
if ( this->selected_group_index == i ) {
GfxFillRect(left, y, right, y+(this->line_height)/2, _colour_gradient[COLOUR_GREY][3]);
if (this->selected_group_index == i) {
GfxFillRect(left, y, right, y+(this->line_height) / 2, _colour_gradient[COLOUR_GREY][3]);
}
SetDParam(0, g_id);
StringID str = STR_GROUP_NAME;
DrawString(left+30+ this->indents[i] * 10, right, y+2, str, TC_BLACK);
DrawString(left + 30 + this->indents[i] * 10, right, y + 2, str, TC_BLACK);
/* Draw the template in use for this group, if there is one */
short template_in_use = FindTemplateIndexForGroup(g_id);
if ( template_in_use >= 0 ) {
if (template_in_use >= 0) {
SetDParam(0, template_in_use);
DrawString ( left, right, y+2, STR_TMPL_GROUP_USES_TEMPLATE, TC_BLACK, SA_HOR_CENTER);
}
/* If there isn't a template applied from the current group, check if there is one for another rail type */
else if ( GetTemplateReplacementByGroupID(g_id) ) {
DrawString ( left, right, y+2, STR_TMPL_TMPLRPL_EX_DIFF_RAILTYPE, TC_SILVER, SA_HOR_CENTER);
DrawString (left, right, y + 2, STR_TMPL_GROUP_USES_TEMPLATE, TC_BLACK, SA_HOR_CENTER);
} else if (GetTemplateReplacementByGroupID(g_id)) { /* If there isn't a template applied from the current group, check if there is one for another rail type */
DrawString (left, right, y + 2, STR_TMPL_TMPLRPL_EX_DIFF_RAILTYPE, TC_SILVER, SA_HOR_CENTER);
}
/* Draw the number of trains that still need to be treated by the currently selected template replacement */
TemplateReplacement *tr = GetTemplateReplacementByGroupID(g_id);
if ( tr ) {
if (tr) {
TemplateVehicle *tv = TemplateVehicle::Get(tr->sel_template);
int num_trains = NumTrainsNeedTemplateReplacement(g_id, tv);
// Draw text
TextColour color = TC_GREY;
if ( num_trains ) color = TC_BLACK;
DrawString(left, right-16, y+2, STR_TMPL_NUM_TRAINS_NEED_RPL, color, SA_RIGHT);
if (num_trains) color = TC_BLACK;
DrawString(left, right - 16, y + 2, STR_TMPL_NUM_TRAINS_NEED_RPL, color, SA_RIGHT);
// Draw number
if ( num_trains ) color = TC_ORANGE;
else color = TC_GREY;
if (num_trains ) {
color = TC_ORANGE;
} else {
color = TC_GREY;
}
SetDParam(0, num_trains);
DrawString(left, right-4, y+2, STR_JUST_INT, color, SA_RIGHT);
DrawString(left, right - 4, y + 2, STR_JUST_INT, color, SA_RIGHT);
}
y+=line_height / 2;
y += line_height / 2;
}
}
@ -658,52 +666,51 @@ public:
uint max = min(draw_vscroll->GetPosition() + draw_vscroll->GetCapacity(), this->templates.Length());
const TemplateVehicle *v;
for ( uint i = draw_vscroll->GetPosition(); i < max; ++i) {
for (uint i = draw_vscroll->GetPosition(); i < max; ++i) {
v = (this->templates)[i];
/* Fill the background of the current cell in a darker tone for the currently selected template */
if ( this->selected_template_index == (int32)i ) {
GfxFillRect(left, y, right, y+this->line_height, _colour_gradient[COLOUR_GREY][3]);
if (this->selected_template_index == (int32) i) {
GfxFillRect(left, y, right, y + this->line_height, _colour_gradient[COLOUR_GREY][3]);
}
/* Draw a notification string for chains that are not runnable */
if ( v->IsFreeWagonChain() ) {
DrawString(left, right-2, y+line_height-FONT_HEIGHT_SMALL-WD_FRAMERECT_BOTTOM - 2, STR_TMPL_WARNING_FREE_WAGON, TC_RED, SA_RIGHT);
if (v->IsFreeWagonChain()) {
DrawString(left, right - 2, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_WARNING_FREE_WAGON, TC_RED, SA_RIGHT);
}
/* Draw the template's length in tile-units */
SetDParam(0, v->GetRealLength());
SetDParam(1, 1);
DrawString(left, right-4, y+2, STR_TINY_BLACK_DECIMAL, TC_BLACK, SA_RIGHT);
DrawString(left, right - 4, y + 2, STR_TINY_BLACK_DECIMAL, TC_BLACK, SA_RIGHT);
/* Draw the template */
DrawTemplate(v, left+50, right, y);
DrawTemplate(v, left + 50, right, y);
/* Buying cost */
SetDParam(0, CalculateOverallTemplateCost(v));
DrawString(left+35, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_TEMPLATE_OVR_VALUE_notinyfont, TC_BLUE, SA_LEFT);
DrawString(left + 35, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_TEMPLATE_OVR_VALUE_notinyfont, TC_BLUE, SA_LEFT);
/* Index of current template vehicle in the list of all templates for its company */
SetDParam(0, i);
DrawString(left+5, left+25, y + 2, STR_BLACK_INT, TC_BLACK, SA_RIGHT);
DrawString(left + 5, left + 25, y + 2, STR_BLACK_INT, TC_BLACK, SA_RIGHT);
/* Draw whether the current template is in use by any group */
if ( v->NumGroupsUsingTemplate() > 0 ) {
DrawString(left+35, right, y + line_height - FONT_HEIGHT_SMALL * 2 - 4 - WD_FRAMERECT_BOTTOM - 2, STR_TMP_TEMPLATE_IN_USE, TC_GREEN, SA_LEFT);
if (v->NumGroupsUsingTemplate() > 0) {
DrawString(left + 35, right, y + line_height - FONT_HEIGHT_SMALL * 2 - 4 - WD_FRAMERECT_BOTTOM - 2, STR_TMP_TEMPLATE_IN_USE, TC_GREEN, SA_LEFT);
}
/* Draw information about template configuration settings */
TextColour color;
if ( v->IsSetReuseDepotVehicles() ) color = TC_LIGHT_BLUE;
else color = TC_GREY;
DrawString(left+300, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_CONFIG_USEDEPOT, color, SA_LEFT);
if ( v->IsSetKeepRemainingVehicles() ) color = TC_LIGHT_BLUE;
else color = TC_GREY;
DrawString(left+400, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_CONFIG_KEEPREMAINDERS, color, SA_LEFT);
if ( v->IsSetRefitAsTemplate() ) color = TC_LIGHT_BLUE;
else color = TC_GREY;
DrawString(left+500, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_CONFIG_REFIT, color, SA_LEFT);
color = v->IsSetReuseDepotVehicles() ? TC_LIGHT_BLUE : TC_GREY;
DrawString(left + 300, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_CONFIG_USEDEPOT, color, SA_LEFT);
color = v->IsSetKeepRemainingVehicles() ? TC_LIGHT_BLUE : TC_GREY;
DrawString(left + 400, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_CONFIG_KEEPREMAINDERS, color, SA_LEFT);
color = v->IsSetRefitAsTemplate() ? TC_LIGHT_BLUE : TC_GREY;
DrawString(left + 500, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_CONFIG_REFIT, color, SA_LEFT);
y += line_height;
}
@ -711,13 +718,15 @@ public:
void DrawTemplateInfo(int line_height, const Rect &r) const
{
if ((this->selected_template_index < 0) || (this->selected_template_index >= (short)this->templates.Length()))
if ((this->selected_template_index < 0) || (this->selected_template_index >= (short)this->templates.Length())) {
return;
}
DrawPixelInfo tmp_dpi, *old_dpi;
if (!FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left, r.bottom - r.top))
if (!FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left, r.bottom - r.top)) {
return;
}
old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi;
@ -738,20 +747,21 @@ public:
short max_columns = 2;
CargoArray cargo_caps;
for ( ; tmp; tmp=tmp->Next() )
for (; tmp != NULL; tmp = tmp->Next()) {
cargo_caps[tmp->cargo_type] += tmp->cargo_cap;
}
int x = left;
for (CargoID i = 0; i < NUM_CARGO; ++i) {
if ( cargo_caps[i] > 0 ) {
if (cargo_caps[i] > 0) {
count_columns++;
SetDParam(0, i);
SetDParam(1, cargo_caps[i]);
SetDParam(2, _settings_game.vehicle.freight_trains);
DrawString(x, r.right, top, FreightWagonMult(i) > 1 ? STR_TMPL_CARGO_SUMMARY_MULTI : STR_TMPL_CARGO_SUMMARY, TC_LIGHT_BLUE, SA_LEFT);
x += 250;
if ( count_columns % max_columns == 0 ) {
if (count_columns % max_columns == 0) {
x = left;
top += this->line_height/3;
top += this->line_height / 3;
}
}
}
@ -764,4 +774,3 @@ void ShowTemplateReplaceWindow(byte dig, int step_h)
{
new TemplateReplaceWindow(&_replace_rail_vehicle_desc, dig, step_h);
}

@ -1,4 +1,13 @@
// _template_gui_main.h
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_gui_main.h Template-based train replacement: main GUI header. */
#ifndef TEMPLATE_GUI_H
#define TEMPLATE_GUI_H

@ -1,9 +1,38 @@
// replace all gui impl
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_gui_replaceall.cpp Template-based train replacement: replace all GUI. */
#include "stdafx.h"
#include "window_gui.h"
#include "window_func.h"
#include "company_func.h"
#include "engine_base.h"
#include "engine_func.h"
#include "engine_gui.h"
#include "train.h"
#include "strings_func.h"
#include "vehicle_base.h"
#include "vehicle_func.h"
#include "tbtr_template_vehicle.h"
#include "tbtr_template_vehicle_func.h"
#include "core/math_func.hpp"
#include "table/strings.h"
#include "tbtr_template_gui_replaceall.h"
#include <stdio.h>
#include "safeguards.h"
/*
* A wrapper which contains a virtual train and additional info of the template vehicle it is replacing
* We will restore this additional info when creating a new template from the changed virtual train
@ -15,9 +44,9 @@ struct VirtTrainInfo {
// additional info from the template
VehicleID original_index;
bool reuse_depot_vehicles,
keep_remaining_vehicles,
refit_as_template;
bool reuse_depot_vehicles;
bool keep_remaining_vehicles;
bool refit_as_template;
CargoID cargo_type;
byte cargo_subtype;
@ -133,19 +162,19 @@ static int CDECL TrainEnginesThenWagonsSorter(const EngineID *a, const EngineID
class TemplateReplacementReplaceAllWindow : public Window {
private:
uint16 line_height;
Scrollbar *vscroll_tl,
*vscroll_tr,
*vscroll_bo;
GUIEngineList *engines_left,
*engines_right;
short selected_left,
selected_right;
Scrollbar *vscroll_tl;
Scrollbar *vscroll_tr;
Scrollbar *vscroll_bo;
GUIEngineList *engines_left;
GUIEngineList *engines_right;
short selected_left;
short selected_right;
VirtTrainList *virtualTrains;
public:
TemplateReplacementReplaceAllWindow(WindowDesc *wdesc) : Window(wdesc)
{
this->CreateNestedTree(wdesc != nullptr);
this->CreateNestedTree(wdesc != NULL);
this->vscroll_tl = this->GetScrollbar(RPLALL_GUI_SCROLL_TL);
this->vscroll_tr = this->GetScrollbar(RPLALL_GUI_SCROLL_TR);
@ -172,14 +201,15 @@ public:
~TemplateReplacementReplaceAllWindow()
{
for ( uint i=0; i<this->virtualTrains->Length(); ++i )
for (uint i = 0; i<this->virtualTrains->Length(); ++i) {
delete (*this->virtualTrains)[i]->vt;
}
SetWindowClassesDirty(WC_TEMPLATEGUI_MAIN);
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
switch ( widget ) {
switch (widget) {
case RPLALL_GUI_MATRIX_TOPLEFT:
case RPLALL_GUI_MATRIX_TOPRIGHT:
case RPLALL_GUI_MATRIX_BOTTOM: {
@ -235,19 +265,21 @@ public:
switch(widget) {
case RPLALL_GUI_MATRIX_TOPLEFT: {
uint16 newindex = (uint16)((pt.y - this->nested_array[RPLALL_GUI_MATRIX_TOPLEFT]->pos_y) / this->line_height) + this->vscroll_tl->GetPosition();
if ( newindex >= this->engines_left->Length() || newindex==this->selected_left )
if (newindex >= this->engines_left->Length() || newindex == this->selected_left) {
this->selected_left = -1;
else
} else {
this->selected_left = newindex;
}
this->SetDirty();
break;
}
case RPLALL_GUI_MATRIX_TOPRIGHT: {
uint16 newindex = (uint16)((pt.y - this->nested_array[RPLALL_GUI_MATRIX_TOPRIGHT]->pos_y) / this->line_height) + this->vscroll_tr->GetPosition();
if ( newindex > this->engines_right->Length() || newindex==this->selected_right )
if (newindex > this->engines_right->Length() || newindex==this->selected_right) {
this->selected_right = -1;
else
} else {
this->selected_right = newindex;
}
this->SetDirty();
break;
}
@ -257,12 +289,13 @@ public:
}
case RPLALL_GUI_BUTTON_APPLY: {
// check if we actually did anything so far, if not, applying is forbidden
if ( this->virtualTrains->Length() == 0 )
if (this->virtualTrains->Length() == 0) {
return;
}
// first delete all current templates
this->DeleteAllTemplateTrains();
// then build a new list from the current virtual trains
for ( uint i=0; i<this->virtualTrains->Length(); ++i ) {
for (uint i = 0; i < this->virtualTrains->Length(); ++i) {
// the relevant info struct
VirtTrainInfo *vti = (*this->virtualTrains)[i];
// setup template from contained train
@ -276,8 +309,9 @@ public:
tv->cargo_subtype = vti->cargo_subtype;
// use the original_index information to repoint the relevant TemplateReplacement if existing
TemplateReplacement *tr = GetTemplateReplacementByTemplateID(vti->original_index);
if ( tr )
if (tr) {
tr->sel_template = tv->index;
}
}
// then close this window and return to parent
delete this;
@ -294,10 +328,11 @@ public:
{
const TemplateVehicle *tv;
FOR_ALL_TEMPLATES(tv) {
if ( tv->Prev() || tv->owner != _local_company ) continue;
for ( const TemplateVehicle *tmp=tv; tmp; tmp=tmp->GetNextUnit() ) {
if ( tmp->engine_type == eid )
if (tv->Prev() || tv->owner != _local_company) continue;
for (const TemplateVehicle *tmp = tv; tmp != NULL; tmp = tmp->GetNextUnit()) {
if (tmp->engine_type == eid) {
return true;
}
}
}
return false;
@ -309,17 +344,17 @@ public:
TemplateVehicle *tv;
FOR_ALL_TEMPLATES(tv) {
if ( !tv->Prev() && tv->owner==this->owner ) {
if (!tv->Prev() && tv->owner == this->owner) {
// setup template train
Train *newtrain = VirtualTrainFromTemplateVehicle(tv);
VirtTrainInfo *vti = new VirtTrainInfo(newtrain);
// store template specific stuff
vti->original_index = tv->index;
vti->reuse_depot_vehicles = tv->reuse_depot_vehicles;
vti->keep_remaining_vehicles = tv->keep_remaining_vehicles;
vti->refit_as_template = tv->refit_as_template;
vti->cargo_type = tv->cargo_type;
vti->cargo_subtype = tv->cargo_subtype;
vti->original_index = tv->index;
vti->reuse_depot_vehicles = tv->reuse_depot_vehicles;
vti->keep_remaining_vehicles = tv->keep_remaining_vehicles;
vti->refit_as_template = tv->refit_as_template;
vti->cargo_type = tv->cargo_type;
vti->cargo_subtype = tv->cargo_subtype;
// add new info struct
*this->virtualTrains->Append() = vti;
}
@ -333,8 +368,9 @@ public:
TemplateVehicle *tv, *tmp;
FOR_ALL_TEMPLATES(tv) {
tmp = tv;
if ( tmp->Prev()==0 && tmp->owner==this->owner )
if (tmp->Prev() == NULL && tmp->owner == this->owner) {
delete tmp;
}
}
}
@ -350,7 +386,7 @@ public:
EngineID eid = e->index;
const RailVehicleInfo*rvi = &e->u.rail;
if ( !HasTemplateWithEngine(eid) ) continue;
if (!HasTemplateWithEngine(eid)) continue;
*this->engines_left->Append() = eid;
@ -366,11 +402,13 @@ public:
bool VirtualTrainHasEngineID(EngineID eid)
{
for ( uint i=0; i<this->virtualTrains->Length(); ++i ) {
for (uint i = 0; i < this->virtualTrains->Length(); ++i) {
const Train *tmp = (*this->virtualTrains)[i]->vt;
for ( ; tmp; tmp=tmp->Next() )
if ( tmp->engine_type == eid )
for (; tmp != NULL; tmp = tmp->Next()) {
if (tmp->engine_type == eid) {
return true;
}
}
}
return false;
}
@ -378,44 +416,43 @@ public:
// after 'replace all' we need to replace the currently used templates as well
void RebuildIncludedTemplateList() {
// first remove all engine ids
for ( uint i=0; i<this->engines_left->Length(); ++i ) {
for (uint i = 0; i < this->engines_left->Length(); ++i) {
EngineID entry = (*this->engines_left)[i];
if ( !VirtualTrainHasEngineID(entry) )
if (!VirtualTrainHasEngineID(entry)) {
this->engines_left->Erase(&((*this->engines_left)[i]));
}
}
}
void ReplaceAll()
{
if ( this->selected_left==-1 || this->selected_right==-1 )
return;
if (this->selected_left == -1 || this->selected_right == -1) return;
EngineID eid_orig = (*this->engines_left)[this->selected_left];
EngineID eid_repl = (*this->engines_right)[this->selected_right];
if ( eid_orig == eid_repl )
return;
if (eid_orig == eid_repl) return;
if ( this->virtualTrains->Length() == 0 )
if (this->virtualTrains->Length() == 0) {
this->GenerateVirtualTrains();
}
for ( uint i=0; i<this->virtualTrains->Length(); ++i ) {
for (uint i = 0; i < this->virtualTrains->Length(); ++i) {
Train *tmp = (*this->virtualTrains)[i]->vt;
while ( tmp ) {
if ( tmp->engine_type == eid_orig ) {
while (tmp) {
if (tmp->engine_type == eid_orig) {
// build a new virtual rail vehicle and test for success
Train *nt = CmdBuildVirtualRailVehicle(eid_repl);
if ( !nt ) continue;
if (!nt) continue;
// include the (probably) new engine into the 'included'-list
this->engines_left->Include( nt->engine_type );
this->engines_left->Include(nt->engine_type);
// advance the tmp pointer in the chain, otherwise it would get deleted later on
Train *to_del = tmp;
tmp = tmp->GetNextUnit();
// first move the new virtual rail vehicle behind to_del
CommandCost move = CmdMoveRailVehicle(INVALID_TILE, DC_EXEC, nt->index|(1<<21), to_del->index, 0);
CommandCost move = CmdMoveRailVehicle(INVALID_TILE, DC_EXEC, nt->index | (1 << 21), to_del->index, 0);
// then move to_del away from the chain and delete it
move = CmdMoveRailVehicle(INVALID_TILE, DC_EXEC, to_del->index|(1<<21), INVALID_VEHICLE, 0);
move = CmdMoveRailVehicle(INVALID_TILE, DC_EXEC, to_del->index | (1 << 21), INVALID_VEHICLE, 0);
(*this->virtualTrains)[i]->vt = nt->First();
delete to_del;
} else {
@ -458,7 +495,7 @@ public:
this->vscroll_tr->SetCount(this->engines_right->Length());
}
void DrawEngineList(const Rect &r, bool left) const//, GUIEngineList el, Scrollbar* sb) const
void DrawEngineList(const Rect &r, bool left) const
{
uint16 y = r.top;
uint32 eid;
@ -466,7 +503,7 @@ public:
Scrollbar *sb;
const GUIEngineList *el;
if ( left ) {
if (left) {
sb = this->vscroll_tl;
el = this->engines_left;
} else {
@ -474,22 +511,22 @@ public:
el = this->engines_right;
}
int maximum = min((int)sb->GetCapacity(), (int)el->Length()) + sb->GetPosition();
for ( int i=sb->GetPosition(); i<maximum; ++i ) {
int maximum = min((int) sb->GetCapacity(), (int) el->Length()) + sb->GetPosition();
for (int i = sb->GetPosition(); i < maximum; ++i) {
eid = (*el)[i];
/* Draw a grey background rectangle if the current line is the selected one */
if ( (left && this->selected_left == i) || (!left && this->selected_right == i) )
GfxFillRect(r.left, y, r.right, y+this->line_height, _colour_gradient[COLOUR_GREY][3]);
if ((left && this->selected_left == i) || (!left && this->selected_right == i)) {
GfxFillRect(r.left, y, r.right, y + this->line_height, _colour_gradient[COLOUR_GREY][3]);
}
/* Draw a description string of the current engine */
SetDParam(0, eid);
DrawString(r.left+100, r.right, y+4, STR_ENGINE_NAME, TC_BLACK);
DrawString(r.left + 100, r.right, y + 4, STR_ENGINE_NAME, TC_BLACK);
/* Draw the engine */
DrawVehicleEngine( r.left, r.right, r.left+29, y+8, eid, GetEnginePalette(eid, _local_company), EIT_PURCHASE );
DrawVehicleEngine(r.left, r.right, r.left + 29, y + 8, eid, GetEnginePalette(eid, _local_company), EIT_PURCHASE);
y += this->line_height;
}
@ -501,11 +538,11 @@ public:
uint16 max = min(virtualTrains->Length(), this->vscroll_bo->GetCapacity());
for ( uint16 i=vscroll_bo->GetPosition(); i<max+vscroll_bo->GetPosition(); ++i ) {
for (uint16 i = vscroll_bo->GetPosition(); i < max + vscroll_bo->GetPosition(); ++i) {
/* Draw a virtual train*/
DrawTrainImage( (*this->virtualTrains)[i]->vt, r.left+32, r.right, y, INVALID_VEHICLE, EIT_PURCHASE, 0, -1 );
DrawTrainImage((*this->virtualTrains)[i]->vt, r.left + 32, r.right, y, INVALID_VEHICLE, EIT_PURCHASE, 0, -1);
y+= this->line_height;
y += this->line_height;
}
}
};

@ -1,27 +1,17 @@
#ifndef TMPL_RPLALL_GUI
#define TMPL_RPLALL_GUI
/* $Id$ */
#include "stdafx.h"
#include "window_gui.h"
#include "window_func.h"
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
#include "company_func.h"
#include "engine_base.h"
#include "engine_func.h"
#include "engine_gui.h"
#include "train.h"
#include "strings_func.h"
#include "vehicle_base.h"
#include "vehicle_func.h"
/** @file tbtr_template_gui_replaceall.cpp Template-based train replacement: replace all GUI header. */
#include "tbtr_template_vehicle.h"
#include "tbtr_template_vehicle_func.h"
#include "core/math_func.hpp"
#include "table/strings.h"
#ifndef TMPL_RPLALL_GUI
#define TMPL_RPLALL_GUI
void ShowTemplateReplaceAllGui();
#endif
#endif

@ -1,3 +1,14 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_vehicle.cpp Template-based train replacement: template vehicle. */
#include "stdafx.h"
#include "company_func.h"
#include "train.h"
@ -24,7 +35,6 @@
#include "table/train_cmd.h"
#include "tbtr_template_vehicle.h"
// since doing stuff with sprites
@ -32,6 +42,8 @@
#include "newgrf_engine.h"
#include "newgrf_cargo.h"
#include "safeguards.h"
TemplatePool _template_pool("TemplatePool");
INSTANTIATE_POOL_METHODS(Template)
@ -74,24 +86,28 @@ void TemplateVehicle::SetFirst(TemplateVehicle *v) { this->first = v; }
TemplateVehicle* TemplateVehicle::GetNextUnit() const
{
TemplateVehicle *tv = this->Next();
while ( tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART) ) tv = tv->Next();
if ( tv && HasBit(tv->subtype, GVSF_MULTIHEADED) && !HasBit(tv->subtype, GVSF_ENGINE) ) tv = tv->Next();
while (tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART)) {
tv = tv->Next();
}
if (tv && HasBit(tv->subtype, GVSF_MULTIHEADED) && !HasBit(tv->subtype, GVSF_ENGINE)) tv = tv->Next();
return tv;
}
TemplateVehicle* TemplateVehicle::GetPrevUnit()
{
TemplateVehicle *tv = this->Prev();
while ( tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART|GVSF_ENGINE) ) tv = tv->Prev();
if ( tv && HasBit(tv->subtype, GVSF_MULTIHEADED|GVSF_ENGINE) ) tv = tv->Prev();
while (tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART|GVSF_ENGINE)) {
tv = tv->Prev();
}
if (tv && HasBit(tv->subtype, GVSF_MULTIHEADED|GVSF_ENGINE)) tv = tv->Prev();
return tv;
}
/** setting */
void appendTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv)
{
if ( !orig ) return;
while ( orig->Next() ) orig=orig->Next();
if (!orig) return;
while (orig->Next()) orig = orig->Next();
orig->SetNext(newv);
newv->SetPrev(orig);
newv->SetFirst(orig->First());
@ -99,7 +115,7 @@ void appendTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv)
void insertTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv, TemplateVehicle *insert_after)
{
if ( !orig || !insert_after ) return;
if (!orig || !insert_after) return;
TemplateVehicle *insert_before = insert_after->Next();
insert_after->SetNext(newv);
insert_before->SetPrev(newv);
@ -113,9 +129,12 @@ void insertTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv, Templat
*/
int TemplateVehicle::Length() const
{
int l=1;
const TemplateVehicle *tmp=this;
while ( tmp->Next() ) { tmp=tmp->Next(); l++; }
int l = 1;
const TemplateVehicle *tmp = this;
while (tmp->Next()) {
tmp = tmp->Next();
l++;
}
return l;
}
@ -123,32 +142,33 @@ TemplateReplacement* GetTemplateReplacementByGroupID(GroupID gid)
{
TemplateReplacement *tr;
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->Group() == gid )
if (tr->Group() == gid) {
return tr;
}
}
return 0;
return NULL;
}
TemplateReplacement* GetTemplateReplacementByTemplateID(TemplateID tid) {
TemplateReplacement* GetTemplateReplacementByTemplateID(TemplateID tid)
{
TemplateReplacement *tr;
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->Template() == tid )
if (tr->Template() == tid) {
return tr;
}
}
return 0;
return NULL;
}
bool IssueTemplateReplacement(GroupID gid, TemplateID tid) {
bool IssueTemplateReplacement(GroupID gid, TemplateID tid)
{
TemplateReplacement *tr = GetTemplateReplacementByGroupID(gid);
if ( tr ) {
if (tr) {
/* Then set the new TemplateVehicle and return */
tr->SetTemplate(tid);
return true;
}
else if ( TemplateReplacement::CanAllocateItem() ) {
} else if (TemplateReplacement::CanAllocateItem()) {
tr = new TemplateReplacement(gid, tid);
return true;
}
@ -161,8 +181,9 @@ short TemplateVehicle::NumGroupsUsingTemplate() const
short amount = 0;
const TemplateReplacement *tr;
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->sel_template == this->index )
if (tr->sel_template == this->index) {
amount++;
}
}
return amount;
}
@ -171,9 +192,11 @@ short TemplateVehicle::CountEnginesInChain()
{
TemplateVehicle *tv = this->first;
short count = 0;
for ( ; tv; tv=tv->GetNextUnit() )
if ( HasBit(tv->subtype, GVSF_ENGINE ) )
for (; tv != NULL; tv = tv->GetNextUnit()) {
if (HasBit(tv->subtype, GVSF_ENGINE)) {
count++;
}
}
return count;
}
@ -182,46 +205,10 @@ short deleteIllegalTemplateReplacements(GroupID g_id)
short del_amount = 0;
const TemplateReplacement *tr;
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->group == g_id ) {
if (tr->group == g_id) {
delete tr;
del_amount++;
}
}
return del_amount;
}

@ -1,3 +1,14 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_vehicle.h Template-based train replacement: template vehicle header. */
#ifndef TEMPLATE_VEH_H
#define TEMPLATE_VEH_H
@ -56,7 +67,7 @@ public:
bool refit_as_template;
// Things derived from a virtual train
TemplateVehicle *other_multiheaded_part; ///< Multiheaded Engine support
TemplateVehicle *other_multiheaded_part; ///< Multiheaded Engine support
Money value; ///< Value of the vehicle
Owner owner;
OwnerByte owner_b;
@ -83,17 +94,20 @@ public:
uint32 image_width;
const SpriteGroup *sgroup;
TemplateVehicle(VehicleType type=VEH_INVALID, EngineID e=INVALID_ENGINE, byte B=0, Owner=_local_company);
TemplateVehicle(VehicleType type = VEH_INVALID, EngineID e = INVALID_ENGINE, byte B = 0, Owner = _local_company);
TemplateVehicle(EngineID, RailVehicleInfo*);
TemplateVehicle(EngineID eid) {
next=0;
previous=0;
first=this;
engine_type=eid;
TemplateVehicle(EngineID eid)
{
next = NULL;
previous = NULL;
first = this;
engine_type = eid;
this->reuse_depot_vehicles = true;
this->keep_remaining_vehicles = true;
this->refit_as_template = true;
}
~TemplateVehicle();
inline TemplateVehicle* Next() const { return this->next; }
@ -124,10 +138,10 @@ public:
inline bool IsFreeWagonChain() const { return HasBit(this->subtype, GVSF_FREE_WAGON); }
// since CmdBuildTemplateVehicle(...)
inline void SetFrontEngine() { SetBit(this->subtype, GVSF_FRONT); }
inline void SetEngine() { SetBit(this->subtype, GVSF_ENGINE); }
inline void SetArticulatedPart() { SetBit(this->subtype, GVSF_ARTICULATED_PART); }
inline void SetMultiheaded() { SetBit(this->subtype, GVSF_MULTIHEADED); }
inline void SetFrontEngine() { SetBit(this->subtype, GVSF_FRONT); }
inline void SetEngine() { SetBit(this->subtype, GVSF_ENGINE); }
inline void SetArticulatedPart() { SetBit(this->subtype, GVSF_ARTICULATED_PART); }
inline void SetMultiheaded() { SetBit(this->subtype, GVSF_MULTIHEADED); }
inline void SetWagon() { SetBit(this->subtype, GVSF_WAGON); }
inline void SetFreeWagon() { SetBit(this->subtype, GVSF_FREE_WAGON); }
@ -138,7 +152,6 @@ public:
int Length() const;
SpriteID GetImage(Direction) const;
//int GetDisplayImageWidth(Point *offset = NULL) const;
SpriteID GetSpriteID() const;
short NumGroupsUsingTemplate() const;
@ -173,11 +186,14 @@ struct TemplateReplacement : TemplateReplacementPool::PoolItem<&_template_replac
inline void SetTemplate(TemplateID tid) { this->sel_template = tid; }
inline TemplateID GetTemplateVehicleID() { return sel_template; }
inline const TemplateVehicle* GetTemplateVehicle() {
inline const TemplateVehicle* GetTemplateVehicle()
{
const TemplateVehicle *tv;
FOR_ALL_TEMPLATES(tv) {
if ( tv->index == this->sel_template )
if (tv->index == this->sel_template) {
return tv;
}
}
return NULL;
}
@ -190,4 +206,3 @@ bool IssueTemplateReplacement(GroupID, TemplateID);
short deleteIllegalTemplateReplacements(GroupID);
#endif /* TEMPLATE_VEH_H */

@ -1,4 +1,13 @@
// template_vehicle_func.cpp
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_vehicle_func.cpp Template-based train replacement: template vehicle functions. */
#include "stdafx.h"
#include "window_gui.h"
@ -31,6 +40,8 @@
#include <map>
#include <stdio.h>
#include "safeguards.h"
Vehicle *vhead, *vtmp;
static const uint MAX_ARTICULATED_PARTS = 100;
@ -77,9 +88,9 @@ void BuildTemplateGuiList(GUITemplateList *list, Scrollbar *vscroll, Owner oid,
const TemplateVehicle *tv;
FOR_ALL_TEMPLATES(tv) {
if (tv->owner == oid && (tv->IsPrimaryVehicle() || tv->IsFreeWagonChain()) && TemplateVehicleContainsEngineOfRailtype(tv, railtype))
if (tv->owner == oid && (tv->IsPrimaryVehicle() || tv->IsFreeWagonChain()) && TemplateVehicleContainsEngineOfRailtype(tv, railtype)) {
*list->Append() = tv;
}
}
list->RebuildDone();
@ -90,21 +101,22 @@ Money CalculateOverallTemplateCost(const TemplateVehicle *tv)
{
Money val = 0;
for (; tv; tv = tv->Next())
for (; tv; tv = tv->Next()) {
val += (Engine::Get(tv->engine_type))->GetCost();
}
return val;
}
void DrawTemplate(const TemplateVehicle *tv, int left, int right, int y)
{
if ( !tv ) return;
if (!tv) return;
const TemplateVehicle *t = tv;
int offset=left;
int offset = left;
while (t) {
PaletteID pal = GetEnginePalette(t->engine_type, _current_company);
DrawSprite(t->cur_image, pal, offset, y+12);
DrawSprite(t->cur_image, pal, offset, y + 12);
offset += t->image_width;
t = t->Next();
@ -145,17 +157,18 @@ inline void SetupTemplateVehicleFromVirtual(TemplateVehicle *tmp, TemplateVehicl
// create a full TemplateVehicle based train according to a virtual train
TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt)
{
if ( !virt )
return 0;
if (!virt) return NULL;
Train *init_virt = virt;
int len = CountVehiclesInChain(virt);
if ( !TemplateVehicle::CanAllocateItem(len) )
return 0;
if (!TemplateVehicle::CanAllocateItem(len)) {
return NULL;
}
TemplateVehicle *tmp, *prev=0;
for ( ; virt; virt=virt->Next() ) {
TemplateVehicle *tmp;
TemplateVehicle *prev = NULL;
for (; virt; virt = virt->Next()) {
tmp = new TemplateVehicle(virt->engine_type);
SetupTemplateVehicleFromVirtual(tmp, prev, virt);
prev = tmp;
@ -166,23 +179,28 @@ TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt)
}
// return last in a chain (really last, so even a singular articulated part of a vehicle if the last one is artic)
inline TemplateVehicle* Last(TemplateVehicle *chain) {
if ( !chain ) return 0;
while ( chain->Next() ) chain = chain->Next();
inline TemplateVehicle* Last(TemplateVehicle *chain)
{
if (!chain) return NULL;
while (chain->Next()) {
chain = chain->Next();
}
return chain;
}
inline Train* Last(Train *chain) {
if ( !chain ) return 0;
while ( chain->GetNextUnit() ) chain = chain->GetNextUnit();
inline Train* Last(Train *chain)
{
if (!chain) return NULL;
while (chain->GetNextUnit()) {
chain = chain->GetNextUnit();
}
return chain;
}
// return: pointer to former vehicle
TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle *todel)
{
if ( !todel )
return 0;
if (!todel) return NULL;
TemplateVehicle *cur = todel;
delete todel;
return cur;
@ -192,7 +210,7 @@ TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle *todel)
CommandCost CmdSellRailWagon(DoCommandFlag, Vehicle*, uint16, uint32);
Train* DeleteVirtualTrain(Train *chain, Train *to_del) {
if ( chain != to_del ) {
if (chain != to_del) {
CmdSellRailWagon(DC_EXEC, to_del, 0, 0);
return chain;
}
@ -208,17 +226,20 @@ TemplateVehicle* GetTemplateVehicleByGroupID(GroupID gid) {
TemplateReplacement *tr;
// first try to find a templatereplacement issued for the given groupid
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->Group() == gid )
return TemplateVehicle::GetIfValid(tr->Template()); // there can be only one
if (tr->Group() == gid) {
return TemplateVehicle::GetIfValid(tr->Template()); // there can be only one
}
}
// if that didn't work, try to find a templatereplacement for ALL_GROUP
if ( gid != ALL_GROUP )
if (gid != ALL_GROUP) {
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->Group() == ALL_GROUP )
if (tr->Group() == ALL_GROUP) {
return TemplateVehicle::GetIfValid(tr->Template());
}
}
}
// if all failed, just return null
return 0;
return NULL;
}
/**
@ -227,28 +248,33 @@ TemplateVehicle* GetTemplateVehicleByGroupID(GroupID gid) {
bool TemplateVehicleContainsEngineOfRailtype(const TemplateVehicle *tv, RailType type)
{
/* For standard rail engines, allow only those */
if ( type == RAILTYPE_BEGIN || type == RAILTYPE_RAIL ) {
while ( tv ) {
if ( tv->railtype != type )
return false;
tv = tv->GetNextUnit();
if (type == RAILTYPE_BEGIN || type == RAILTYPE_RAIL) {
while (tv) {
if (tv->railtype != type) {
return false;
}
tv = tv->GetNextUnit();
}
return true;
}
/* For electrified rail engines, standard wagons or engines are allowed to be included */
while ( tv ) {
if ( tv->railtype == type )
while (tv) {
if (tv->railtype == type) {
return true;
}
tv = tv->GetNextUnit();
}
return false;
}
//helper
bool ChainContainsVehicle(Train *chain, Train *mem) {
for (; chain; chain=chain->Next())
if ( chain == mem )
bool ChainContainsVehicle(Train *chain, Train *mem)
{
for (; chain; chain = chain->Next()) {
if (chain == mem) {
return true;
}
}
return false;
}
@ -257,27 +283,30 @@ Train* ChainContainsEngine(EngineID eid, Train *chain) {
for (; chain; chain=chain->GetNextUnit())
if (chain->engine_type == eid)
return chain;
return 0;
return NULL;
}
// has O(n^2)
Train* DepotContainsEngine(TileIndex tile, EngineID eid, Train *not_in=0) {
Train* DepotContainsEngine(TileIndex tile, EngineID eid, Train *not_in = NULL)
{
Train *t;
FOR_ALL_TRAINS(t) {
// conditions: v is stopped in the given depot, has the right engine and if 'not_in' is given v must not be contained within 'not_in'
// if 'not_in' is NULL, no check is needed
if ( t->tile==tile
if (t->tile == tile
// If the veh belongs to a chain, wagons will not return true on IsStoppedInDepot(), only primary vehicles will
// in case of t not a primary veh, we demand it to be a free wagon to consider it for replacement
&& ((t->IsPrimaryVehicle() && t->IsStoppedInDepot()) || t->IsFreeWagon())
&& t->engine_type==eid
&& (not_in==0 || ChainContainsVehicle(not_in, t)==0))
&& t->engine_type == eid
&& (not_in == NULL || ChainContainsVehicle(not_in, t) == false)) {
return t;
}
}
return 0;
return NULL;
}
void CopyStatus(Train *from, Train *to) {
void CopyStatus(Train *from, Train *to)
{
DoCommand(to->tile, from->group_id, to->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP);
to->cargo_type = from->cargo_type;
to->cargo_subtype = from->cargo_subtype;
@ -286,117 +315,133 @@ void CopyStatus(Train *from, Train *to) {
char *tmp = to->name;
to->name = from->name;
from->name = tmp;
/*if ( !from->name || !to->name ) {
int tmpind = from->index;
from->index = to->index;
to->index = tmpind;
}*/
}
void NeutralizeStatus(Train *t) {
void NeutralizeStatus(Train *t)
{
DoCommand(t->tile, DEFAULT_GROUP, t->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP);
DoCommand(0, t->index | CO_UNSHARE << 30, 0, DC_EXEC, CMD_CLONE_ORDER);
DoCommand(0, t->index, FreeUnitIDGenerator(VEH_TRAIN, t->owner).NextID(), DC_EXEC, CMD_SET_VEHICLE_UNIT_NUMBER);
DoCommand(0, t->index, 0, DC_EXEC, CMD_RENAME_VEHICLE, NULL);
}
bool TrainMatchesTemplate(const Train *t, TemplateVehicle *tv) {
while ( t && tv ) {
if ( t->engine_type != tv->engine_type )
while (t && tv) {
if (t->engine_type != tv->engine_type) {
return false;
}
t = t->GetNextUnit();
tv = tv->GetNextUnit();
}
if ( (t && !tv) || (!t && tv) )
if ((t && !tv) || (!t && tv)) {
return false;
}
return true;
}
bool TrainMatchesTemplateRefit(const Train *t, TemplateVehicle *tv)
{
if ( !tv->refit_as_template )
if (!tv->refit_as_template) {
return true;
}
while ( t && tv ) {
if ( t->cargo_type != tv->cargo_type || t->cargo_subtype != tv->cargo_subtype )
while (t && tv) {
if (t->cargo_type != tv->cargo_type || t->cargo_subtype != tv->cargo_subtype) {
return false;
}
t = t->GetNextUnit();
tv = tv->GetNextUnit();
}
return true;
}
void BreakUpRemainders(Train *t) {
while ( t ) {
void BreakUpRemainders(Train *t)
{
while (t) {
Train *move;
if ( HasBit(t->subtype, GVSF_ENGINE) ) {
if (HasBit(t->subtype, GVSF_ENGINE)) {
move = t;
t = t->Next();
DoCommand(move->tile, move->index, INVALID_VEHICLE, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
NeutralizeStatus( move );
}
else
NeutralizeStatus(move);
} else {
t = t->Next();
}
}
}
short CountEnginesInChain(Train *t)
{
short count = 0;
for ( ; t; t=t->GetNextUnit() )
if ( HasBit(t->subtype, GVSF_ENGINE) )
for (; t != NULL; t = t->GetNextUnit()) {
if (HasBit(t->subtype, GVSF_ENGINE)) {
count++;
}
}
return count;
}
int countOccurrencesInTrain(Train *t, EngineID eid) {
int countOccurrencesInTrain(Train *t, EngineID eid)
{
int count = 0;
Train *tmp = t;
for ( ; tmp; tmp=tmp->GetNextUnit() )
if ( tmp->engine_type == eid )
for (; tmp != NULL; tmp = tmp->GetNextUnit()) {
if (tmp->engine_type == eid) {
count++;
}
}
return count;
}
int countOccurrencesInTemplateVehicle(TemplateVehicle *contain, EngineID eid) {
int countOccurrencesInTemplateVehicle(TemplateVehicle *contain, EngineID eid)
{
int count = 0;
for ( ; contain; contain=contain->GetNextUnit() )
if ( contain->engine_type == eid )
for (; contain; contain=contain->GetNextUnit()) {
if (contain->engine_type == eid) {
count++;
}
}
return count;
}
int countOccurrencesInDepot(TileIndex tile, EngineID eid, Train *not_in=0) {
int countOccurrencesInDepot(TileIndex tile, EngineID eid, Train *not_in = NULL)
{
int count = 0;
Vehicle *v;
FOR_ALL_VEHICLES(v) {
// conditions: v is stopped in the given depot, has the right engine and if 'not_in' is given v must not be contained within 'not_in'
// if 'not_in' is NULL, no check is needed
if ( v->tile==tile && v->IsStoppedInDepot() && v->engine_type==eid &&
(not_in==0 || ChainContainsVehicle(not_in, (Train*)v)==0))
if (v->tile == tile && v->IsStoppedInDepot() && v->engine_type == eid &&
(not_in == 0 || ChainContainsVehicle(not_in, (Train*)v) == false)) {
count++;
}
}
return count;
}
// basically does the same steps as CmdTemplateReplaceVehicle but without actually moving things around
CommandCost CalculateTemplateReplacementCost(Train *incoming) {
CommandCost CalculateTemplateReplacementCost(Train *incoming)
{
TileIndex tile = incoming->tile;
TemplateVehicle *tv = GetTemplateVehicleByGroupID(incoming->group_id);
CommandCost estimate(EXPENSES_NEW_VEHICLES);
// count for each different eid in the incoming train
std::map<EngineID, short> unique_eids;
for ( TemplateVehicle *tmp=tv; tmp; tmp=tmp->GetNextUnit() )
for (TemplateVehicle *tmp = tv; tmp != NULL; tmp = tmp->GetNextUnit()) {
unique_eids[tmp->engine_type]++;
}
std::map<EngineID, short>::iterator it = unique_eids.begin();
for ( ; it!=unique_eids.end(); it++ ) {
for (; it != unique_eids.end(); it++) {
it->second -= countOccurrencesInTrain(incoming, it->first);
it->second -= countOccurrencesInDepot(incoming->tile, it->first, incoming);
if ( it->second < 0 ) it->second = 0;
if (it->second < 0) it->second = 0;
}
// get overall buying cost
for ( it=unique_eids.begin(); it!=unique_eids.end(); it++ ) {
for ( int j=0; j<it->second; j++ ) {
for (it = unique_eids.begin(); it != unique_eids.end(); it++) {
for (int j = 0; j < it->second; j++) {
estimate.AddCost(DoCommand(tile, it->first, 0, DC_NONE, CMD_BUILD_VEHICLE));
}
}
@ -405,7 +450,8 @@ CommandCost CalculateTemplateReplacementCost(Train *incoming) {
}
// make sure the real train wagon has the right cargo
void CopyWagonStatus(TemplateVehicle *from, Train *to) {
void CopyWagonStatus(TemplateVehicle *from, Train *to)
{
to->cargo_type = from->cargo_type;
to->cargo_subtype = from->cargo_subtype;
}
@ -413,19 +459,20 @@ void CopyWagonStatus(TemplateVehicle *from, Train *to) {
int NumTrainsNeedTemplateReplacement(GroupID g_id, TemplateVehicle *tv)
{
int count = 0;
if ( !tv ) return count;
if (!tv) return count;
const Train *t;
FOR_ALL_TRAINS(t) {
if ( t->IsPrimaryVehicle() && t->group_id == g_id && (!TrainMatchesTemplate(t, tv) || !TrainMatchesTemplateRefit(t, tv)) )
if (t->IsPrimaryVehicle() && t->group_id == g_id && (!TrainMatchesTemplate(t, tv) || !TrainMatchesTemplateRefit(t, tv))) {
count++;
}
}
return count;
}
// refit each vehicle in t as is in tv, assume t and tv contain the same types of vehicles
void CmdRefitTrainFromTemplate(Train *t, TemplateVehicle *tv, DoCommandFlag flags)
{
while ( t && tv ) {
while (t && tv) {
// refit t as tv
uint32 cb = GetCmdRefitVeh(t);
@ -445,8 +492,9 @@ CommandCost TestBuyAllTemplateVehiclesInChain(TemplateVehicle *tv, TileIndex til
{
CommandCost cost(EXPENSES_NEW_VEHICLES);
for ( ; tv; tv=tv->GetNextUnit() )
cost.AddCost( DoCommand(tile, tv->engine_type, 0, DC_NONE, CMD_BUILD_VEHICLE) );
for (; tv; tv = tv->GetNextUnit()) {
cost.AddCost(DoCommand(tile, tv->engine_type, 0, DC_NONE, CMD_BUILD_VEHICLE));
}
return cost;
}
@ -455,9 +503,9 @@ CommandCost TestBuyAllTemplateVehiclesInChain(TemplateVehicle *tv, TileIndex til
/** Transfer as much cargo from a given (single train) vehicle onto a chain of vehicles.
* I.e., iterate over the chain from head to tail and use all available cargo capacity (w.r.t. cargo type of course)
* to store the cargo from the given single vehicle.
* @param old_veh: ptr to the single vehicle, which's cargo shall be moved
* @param new_head: ptr to the head of the chain, which shall obtain old_veh's cargo
* @return: amount of moved cargo TODO
* @param old_veh: ptr to the single vehicle, which's cargo shall be moved
* @param new_head: ptr to the head of the chain, which shall obtain old_veh's cargo
* @return: amount of moved cargo, TODO
*/
void TransferCargoForTrain(Train *old_veh, Train *new_head)
{
@ -469,16 +517,13 @@ void TransferCargoForTrain(Train *old_veh, Train *new_head)
// how much cargo has to be moved (if possible)
uint remainingAmount = old_veh->cargo.TotalCount();
// each vehicle in the new chain shall be given as much of the old cargo as possible, until none is left
for (Train *tmp=new_head; tmp!=NULL && remainingAmount>0; tmp=tmp->GetNextUnit())
{
if (tmp->cargo_type == _cargo_type && tmp->cargo_subtype == _cargo_subtype)
{
for (Train *tmp = new_head; tmp != NULL && remainingAmount > 0; tmp = tmp->GetNextUnit()) {
if (tmp->cargo_type == _cargo_type && tmp->cargo_subtype == _cargo_subtype) {
// calculate the free space for new cargo on the current vehicle
uint curCap = tmp->cargo_cap - tmp->cargo.TotalCount();
uint moveAmount = min(remainingAmount, curCap);
// move (parts of) the old vehicle's cargo onto the current vehicle of the new chain
if (moveAmount > 0)
{
if (moveAmount > 0) {
old_veh->cargo.Shift(moveAmount, &tmp->cargo);
remainingAmount -= moveAmount;
}
@ -493,33 +538,3 @@ void TransferCargoForTrain(Train *old_veh, Train *new_head)
/* Update train weight etc., the old vehicle will be sold anyway */
new_head->ConsistChanged(CCF_LOADUNLOAD);
}

@ -1,4 +1,14 @@
// template_vehicle_func.h
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file tbtr_template_vehicle_func.h Template-based train replacement: template vehicle functions headers. */
#ifndef TEMPLATE_VEHICLE_FUNC_H
#define TEMPLATE_VEHICLE_FUNC_H
@ -7,9 +17,6 @@
#include "tbtr_template_vehicle.h"
//void DrawTemplateVehicle(TemplateVehicle*, int, const Rect&);
Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv);
void DrawTemplateVehicle(const TemplateVehicle*, int, int, int, VehicleID, int, VehicleID);
@ -32,8 +39,6 @@ void setupVirtTrain(const TemplateVehicle*, Train*);
TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt);
//Train* VirtualTrainFromTemplateVehicle(TemplateVehicle*);
inline TemplateVehicle* Last(TemplateVehicle*);
TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle*);

@ -169,7 +169,9 @@ struct Train FINAL : public GroundVehicle<Train, VEH_TRAIN> {
*/
inline Train *GetLastUnit() {
Train *tmp = this;
while ( tmp->GetNextUnit() ) tmp = tmp->GetNextUnit();
while (tmp->GetNextUnit()) {
tmp = tmp->GetNextUnit();
}
return tmp;
}

@ -262,7 +262,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes)
if (this->IsFrontEngine()) {
this->UpdateAcceleration();
if ( !HasBit(this->subtype, GVSF_VIRTUAL) ) SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
if (!HasBit(this->subtype, GVSF_VIRTUAL)) SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
InvalidateWindowData(WC_VEHICLE_REFIT, this->index, VIWD_CONSIST_CHANGED);
InvalidateWindowData(WC_VEHICLE_ORDERS, this->index, VIWD_CONSIST_CHANGED);
InvalidateNewGRFInspectWindow(GSF_TRAINS, this->index);
@ -1161,7 +1161,7 @@ static void NormaliseTrainHead(Train *head)
* @param p1 various bitstuffed elements
* - p1 (bit 0 - 19) source vehicle index
* - p1 (bit 20) move all vehicles following the source vehicle
* - p1 (bit 21) this is a virtual vehicle (for creating TemplateVehicles)
* - p1 (bit 21) this is a virtual vehicle (for creating TemplateVehicles)
* @param p2 what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
* @param text unused
* @return the cost of this operation or an error
@ -1227,13 +1227,15 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* Check if all vehicles in the source train are stopped inside a depot. */
/* Do this check only if the vehicle to be moved is non-virtual */
if ( !HasBit(p1, 21) )
if (!HasBit(p1, 21)) {
if (!src_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
}
/* Check if all vehicles in the destination train are stopped inside a depot. */
/* Do this check only if the destination vehicle is non-virtual */
if ( !HasBit(p1, 21) )
if (!HasBit(p1, 21)) {
if (dst_head != NULL && !dst_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
}
/* First make a backup of the order of the trains. That way we can do
* whatever we want with the order and later on easily revert. */
@ -1343,7 +1345,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* We are undoubtedly changing something in the depot and train list. */
/* But only if the moved vehicle is not virtual */
if ( !HasBit(src->subtype, GVSF_VIRTUAL) ) {
if (!HasBit(src->subtype, GVSF_VIRTUAL)) {
InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
}
@ -1430,7 +1432,7 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3
/* We are undoubtedly changing something in the depot and train list. */
/* Unless its a virtual train */
if ( !HasBit(v->subtype, GVSF_VIRTUAL) ) {
if (!HasBit(v->subtype, GVSF_VIRTUAL)) {
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
}
@ -3762,7 +3764,7 @@ Money Train::CalculateCurrentOverallValue() const
const Train *v = this;
do {
ovr_value += v->value;
} while ( (v=v->GetNextVehicle()) != NULL );
} while ((v = v->GetNextVehicle()) != NULL);
return ovr_value;
}
@ -4060,7 +4062,6 @@ Trackdir Train::GetVehicleTrackdir() const
return TrackDirectionToTrackdir(FindFirstTrack(this->track), this->direction);
}
/* Get the pixel-width of the image that is used for the train vehicle
* @return: the image width number in pixel
*/
@ -4079,7 +4080,6 @@ int GetDisplayImageWidth(Train *t, Point *offset)
offset->x = reference_width / 2;
offset->y = vehicle_pitch;
}
//printf(" refwid:%d gdiw.cachedvehlen(%d):%d ", reference_width, this->engine_type, this->gcache.cached_veh_length);
return t->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH;
}
@ -4098,7 +4098,7 @@ Train* CmdBuildVirtualRailWagon(const Engine *e)
v->gcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
v->direction = DIR_W;
v->tile = 0;//INVALID_TILE;
v->tile = 0; // INVALID_TILE;
v->owner = _current_company;
v->track = TRACK_BIT_DEPOT;
@ -4147,18 +4147,21 @@ Train* CmdBuildVirtualRailWagon(const Engine *e)
*/
Train* CmdBuildVirtualRailVehicle(EngineID eid)
{
if (!IsEngineBuildable(eid, VEH_TRAIN, _current_company))
return nullptr;
if (!IsEngineBuildable(eid, VEH_TRAIN, _current_company)) {
return NULL;
}
const Engine* e = Engine::Get(eid);
const RailVehicleInfo *rvi = &e->u.rail;
int num_vehicles = (e->u.rail.railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) + CountArticulatedParts(eid, false);
if (!Train::CanAllocateItem(num_vehicles))
return nullptr;
if (!Train::CanAllocateItem(num_vehicles)) {
return NULL;
}
if (rvi->railveh_type == RAILVEH_WAGON)
if (rvi->railveh_type == RAILVEH_WAGON) {
return CmdBuildVirtualRailWagon(e);
}
Train *v = new Train();
@ -4166,7 +4169,7 @@ Train* CmdBuildVirtualRailVehicle(EngineID eid)
v->y_pos = 0;
v->direction = DIR_W;
v->tile = 0;//INVALID_TILE;
v->tile = 0; // INVALID_TILE;
v->owner = _current_company;
v->track = TRACK_BIT_DEPOT;
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
@ -4225,15 +4228,15 @@ Train* CmdBuildVirtualRailVehicle(EngineID eid)
CommandCost CmdBuildVirtualRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
EngineID eid = p1;
CommandCost cost = CommandCost();
bool should_execute = (flags & DC_EXEC) != 0;
if (should_execute) {
Train* train = CmdBuildVirtualRailVehicle(eid);
if (train == nullptr)
if (train == NULL) {
return CMD_ERROR;
}
}
return CommandCost();
@ -4254,20 +4257,22 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
Vehicle* vehicle = Vehicle::GetIfValid(vehicle_id);
if (vehicle == nullptr || vehicle->type != VEH_TRAIN)
if (vehicle == NULL || vehicle->type != VEH_TRAIN) {
return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0;
if (!should_execute)
if (!should_execute) {
return CommandCost();
}
Train* incoming = Train::From(vehicle);
bool stayInDepot = p2 != 0;
Train *new_chain = 0,
*remainder_chain = 0,
*tmp_chain = 0;
Train *new_chain = NULL;
Train *remainder_chain = NULL;
Train *tmp_chain = NULL;
TemplateVehicle *tv = GetTemplateVehicleByGroupID(incoming->group_id);
EngineID eid = tv->engine_type;
@ -4277,8 +4282,7 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
/* first some tests on necessity and sanity */
if (!tv)
return buy;
if (tv == NULL) return buy;
bool need_replacement = !TrainMatchesTemplate(incoming, tv);
bool need_refit = !TrainMatchesTemplateRefit(incoming, tv);
bool use_refit = tv->refit_as_template;
@ -4286,7 +4290,7 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
short store_refit_csubt = 0;
// if a train shall keep its old refit, store the refit setting of its first vehicle
if (!use_refit) {
for (Train *getc = incoming; getc; getc = getc->GetNextUnit())
for (Train *getc = incoming; getc != NULL; getc = getc->GetNextUnit())
if (getc->cargo_type != CT_INVALID) {
store_refit_ct = getc->cargo_type;
break;
@ -4300,8 +4304,7 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
if (!stayInDepot) incoming->vehstatus &= ~VS_STOPPED;
return buy;
}
}
else {
} else {
CommandCost buyCost = TestBuyAllTemplateVehiclesInChain(tv, tile);
if (!buyCost.Succeeded() || !CheckCompanyHasMoney(buyCost)) {
if (!stayInDepot) incoming->vehstatus &= ~VS_STOPPED;
@ -4314,35 +4317,34 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
bool keepRemainders = tv->IsSetKeepRemainingVehicles();
if (need_replacement) {
/// step 1: generate primary for newchain and generate remainder_chain
// step 1: generate primary for newchain and generate remainder_chain
// 1. primary of incoming might already fit the template
// leave incoming's primary as is and move the rest to a free chain = remainder_chain
// leave incoming's primary as is and move the rest to a free chain = remainder_chain
// 2. needed primary might be one of incoming's member vehicles
// 3. primary might be available as orphan vehicle in the depot
// 4. we need to buy a new engine for the primary
// all options other than 1. need to make sure to copy incoming's primary's status
if (eid == incoming->engine_type) { // 1
if (eid == incoming->engine_type) { // 1
new_chain = incoming;
remainder_chain = incoming->GetNextUnit();
if (remainder_chain)
if (remainder_chain) {
move_cost.AddCost(CmdMoveRailVehicle(tile, flags, remainder_chain->index | (1 << 20), INVALID_VEHICLE, 0));
}
else if ((tmp_chain = ChainContainsEngine(eid, incoming)) && tmp_chain != NULL) { // 2
}
} else if ((tmp_chain = ChainContainsEngine(eid, incoming)) && tmp_chain != NULL) { // 2
// new_chain is the needed engine, move it to an empty spot in the depot
new_chain = tmp_chain;
move_cost.AddCost(DoCommand(tile, new_chain->index, INVALID_VEHICLE, flags, CMD_MOVE_RAIL_VEHICLE));
remainder_chain = incoming;
}
else if (reuseDepot && (tmp_chain = DepotContainsEngine(tile, eid, incoming)) && tmp_chain != NULL) { // 3
} else if (reuseDepot && (tmp_chain = DepotContainsEngine(tile, eid, incoming)) && tmp_chain != NULL) { // 3
new_chain = tmp_chain;
move_cost.AddCost(DoCommand(tile, new_chain->index, INVALID_VEHICLE, flags, CMD_MOVE_RAIL_VEHICLE));
remainder_chain = incoming;
}
else { // 4
} else { // 4
tmp_result = DoCommand(tile, eid, 0, flags, CMD_BUILD_VEHICLE);
/* break up in case buying the vehicle didn't succeed */
if (!tmp_result.Succeeded())
if (!tmp_result.Succeeded()) {
return tmp_result;
}
buy.AddCost(tmp_result);
new_chain = Train::Get(_new_vehicle_id);
/* make sure the newly built engine is not attached to any free wagons inside the depot */
@ -4355,29 +4357,28 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
CopyHeadSpecificThings(incoming, new_chain, flags);
NeutralizeStatus(incoming);
// additionally, if we don't want to use the template refit, refit as incoming
// the template refit will be set further down, if we use it at all
if (!use_refit) {
uint32 cb = GetCmdRefitVeh(new_chain);
DoCommand(new_chain->tile, new_chain->index, store_refit_ct | store_refit_csubt << 8 | 1 << 16 | (1 << 5), flags, cb);
}
}
/// step 2: fill up newchain according to the template
// step 2: fill up newchain according to the template
// foreach member of template (after primary):
// 1. needed engine might be within remainder_chain already
// 2. needed engine might be orphaned within the depot (copy status)
// 3. we need to buy (again) (copy status)
// 3. we need to buy (again) (copy status)
TemplateVehicle *cur_tmpl = tv->GetNextUnit();
Train *last_veh = new_chain;
while (cur_tmpl) {
// 1. engine contained in remainder chain
if ((tmp_chain = ChainContainsEngine(cur_tmpl->engine_type, remainder_chain)) && tmp_chain != NULL) {
// advance remainder_chain (if necessary) to not lose track of it
if (tmp_chain == remainder_chain)
if (tmp_chain == remainder_chain) {
remainder_chain = remainder_chain->GetNextUnit();
}
move_cost.AddCost(CmdMoveRailVehicle(tile, flags, tmp_chain->index, last_veh->index, 0));
}
// 2. engine contained somewhere else in the depot
@ -4397,13 +4398,11 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
if (need_refit && flags == DC_EXEC) {
if (use_refit) {
uint32 cb = GetCmdRefitVeh(tmp_chain);
DoCommand(tmp_chain->tile, tmp_chain->index, cur_tmpl->cargo_type | cur_tmpl->cargo_subtype << 8 | 1 << 16 | (1 << 5), flags, cb);
// old
// CopyWagonStatus(cur_tmpl, tmp_chain);
DoCommand(tmp_chain->tile, tmp_chain->index, cur_tmpl->cargo_type | (cur_tmpl->cargo_subtype << 8) | (1 << 16) | (1 << 5), flags, cb);
}
else {
uint32 cb = GetCmdRefitVeh(tmp_chain);
DoCommand(tmp_chain->tile, tmp_chain->index, store_refit_ct | store_refit_csubt << 8 | 1 << 16 | (1 << 5), flags, cb);
DoCommand(tmp_chain->tile, tmp_chain->index, store_refit_ct | (store_refit_csubt << 8) | (1 << 16) | (1 << 5), flags, cb);
}
}
cur_tmpl = cur_tmpl->GetNextUnit();
@ -4424,18 +4423,21 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
CmdRefitTrainFromTemplate(new_chain, tv, flags);
}
if (new_chain && remainder_chain)
for (Train *ct = remainder_chain; ct; ct = ct->GetNextUnit())
if (new_chain && remainder_chain) {
for (Train *ct = remainder_chain; ct; ct = ct->GetNextUnit()) {
TransferCargoForTrain(ct, new_chain);
}
}
// point incoming to the newly created train so that starting/stopping from the calling function can be done
incoming = new_chain;
if (!stayInDepot && flags == DC_EXEC)
if (!stayInDepot && flags == DC_EXEC) {
new_chain->vehstatus &= ~VS_STOPPED;
}
if (remainder_chain && keepRemainders && flags == DC_EXEC)
if (remainder_chain && keepRemainders && flags == DC_EXEC) {
BreakUpRemainders(remainder_chain);
else if (remainder_chain) {
} else if (remainder_chain) {
buy.AddCost(DoCommand(tile, remainder_chain->index | (1 << 20), 0, flags, CMD_SELL_VEHICLE));
}

@ -52,13 +52,12 @@
#include "gamelog.h"
#include "linkgraph/linkgraph.h"
#include "linkgraph/refresh.h"
#include "tbtr_template_vehicle_func.h"
#include "table/strings.h"
#include "safeguards.h"
#include "tbtr_template_vehicle_func.h"
#define GEN_HASH(x, y) ((GB((y), 6 + ZOOM_LVL_SHIFT, 6) << 6) + GB((x), 7 + ZOOM_LVL_SHIFT, 6))
VehicleID _new_vehicle_id;
@ -840,22 +839,21 @@ void VehicleEnteredDepotThisTick(Vehicle *v)
/* Template Replacement Setup stuff */
bool stayInDepot = v->current_order.GetDepotActionType();
TemplateReplacement *tr = GetTemplateReplacementByGroupID(v->group_id);
if ( tr ) {
if ( stayInDepot ) _vehicles_to_templatereplace[(Train*)v] = true;
else _vehicles_to_templatereplace[(Train*)v] = false;
}
/* Moved the assignment for auto replacement here to prevent auto replacement
* from happening if template replacement is also scheduled */
else
if (tr != NULL) {
_vehicles_to_templatereplace[(Train*) v] = stayInDepot;
} else {
/* Moved the assignment for auto replacement here to prevent auto replacement
* from happening if template replacement is also scheduled */
/* Vehicle should stop in the depot if it was in 'stopping' state */
_vehicles_to_autoreplace[v] = !(v->vehstatus & VS_STOPPED);
}
/* We ALWAYS set the stopped state. Even when the vehicle does not plan on
* stopping in the depot, so we stop it to ensure that it will not reserve
* the path out of the depot before we might autoreplace it to a different
* engine. The new engine would not own the reserved path we store that we
* stopped the vehicle, so autoreplace can start it again */
v->vehstatus |= VS_STOPPED;
}
@ -1024,7 +1022,6 @@ void CallVehicleTicks()
/* do Template Replacement */
Backup<CompanyByte> 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;
tmpl_cur_company.Change(t->owner);

@ -117,7 +117,7 @@ enum GroundVehicleSubtypeFlags {
GVSF_ENGINE = 3, ///< Engine that can be front engine, but might be placed behind another engine (not used for road vehicles).
GVSF_FREE_WAGON = 4, ///< First in a wagon chain (in depot) (not used for road vehicles).
GVSF_MULTIHEADED = 5, ///< Engine is multiheaded (not used for road vehicles).
GVSF_VIRTUAL = 6, ///< Used for virtual trains during template design, it is needed to skip checks for tile or depot status
GVSF_VIRTUAL = 6, ///< Used for virtual trains during template design, it is needed to skip checks for tile or depot status
};
/** Cached often queried values common to all vehicles. */
@ -517,7 +517,7 @@ public:
Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
void SetNext(Vehicle *next);
inline void SetFirst(Vehicle *f) { this->first=f; }
inline void SetFirst(Vehicle *f) { this->first = f; }
/**
* Get the next vehicle of this vehicle.

@ -426,8 +426,8 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles,
* @param p1 vehicle ID to refit
* @param p2 various bitstuffed elements
* - p2 = (bit 0-4) - New cargo type to refit to.
* - p2 = (bit 5) - Is a virtual train (used by template replacement to allow refitting without stopped-in-depot checks)
* - p2 = (bit 6) - Automatic refitting.
* - p2 = (bit 5) - Is a virtual train (used by template replacement to allow refitting without stopped-in-depot checks)
* - p2 = (bit 7) - Refit only this vehicle. Used only for cloning vehicles.
* - p2 = (bit 8-15) - New cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType().
* - p2 = (bit 16-23) - Number of vehicles to refit (not counting articulated parts). Zero means all vehicles.
@ -457,8 +457,10 @@ CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
if (v != front && (v->type == VEH_SHIP || v->type == VEH_AIRCRAFT)) return CMD_ERROR;
/* Allow auto-refitting only during loading and normal refitting only in a depot. */
if ( ! is_virtual_train ) {
if (!free_wagon && (!auto_refit || !front->current_order.IsType(OT_LOADING)) && !front->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type);
if (!is_virtual_train) {
if (!free_wagon && (!auto_refit || !front->current_order.IsType(OT_LOADING)) && !front->IsStoppedInDepot()) {
return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type);
}
if (front->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_VEHICLE_IS_DESTROYED);
}
if ((flags & DC_QUERY_COST) == 0 && // used by the refit GUI, including the order refit GUI.
@ -511,8 +513,11 @@ CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
InvalidateWindowClassesData(GetWindowClassForVehicleType(v->type), 0);
}
/* virtual vehicles get their cargo changed by the TemplateCreateWindow, so set this dirty instead of a depot window */
if ( HasBit(v->subtype, GVSF_VIRTUAL) ) SetWindowClassesDirty(WC_CREATE_TEMPLATE);
else SetWindowDirty(WC_VEHICLE_DEPOT, front->tile);
if (HasBit(v->subtype, GVSF_VIRTUAL)) {
SetWindowClassesDirty(WC_CREATE_TEMPLATE);
} else {
SetWindowDirty(WC_VEHICLE_DEPOT, front->tile);
}
} else {
/* Always invalidate the cache; querycost might have filled it. */
v->InvalidateNewGRFCacheOfChain();
@ -825,8 +830,9 @@ CommandCost CmdToggleReuseDepotVehicles(TileIndex tile, DoCommandFlag flags, uin
// Identify template to toggle
TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1);
if (template_vehicle == NULL)
if (template_vehicle == NULL) {
return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0;
@ -853,8 +859,9 @@ CommandCost CmdToggleKeepRemainingVehicles(TileIndex tile, DoCommandFlag flags,
// Identify template to toggle
TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1);
if (template_vehicle == NULL)
if (template_vehicle == NULL) {
return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0;
@ -881,8 +888,9 @@ CommandCost CmdToggleRefitAsTemplate(TileIndex tile, DoCommandFlag flags, uint32
// Identify template to toggle
TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1);
if (template_vehicle == NULL)
if (template_vehicle == NULL) {
return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0;
@ -910,16 +918,18 @@ CommandCost CmdVirtualTrainFromTemplateVehicle(TileIndex tile, DoCommandFlag fla
TemplateVehicle* tv = TemplateVehicle::GetIfValid(template_vehicle_id);
if (tv == NULL)
if (tv == NULL) {
return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0;
if (should_execute) {
Train* train = VirtualTrainFromTemplateVehicle(tv);
if (train == nullptr)
if (train == NULL) {
return CMD_ERROR;
}
}
return CommandCost();
@ -931,16 +941,16 @@ Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv)
Train *tmp, *head, *tail;
head = CmdBuildVirtualRailVehicle(tv->engine_type);
if ( !head ) return nullptr;
if (!head) return NULL;
tail = head;
tv = tv->GetNextUnit();
while ( tv ) {
while (tv) {
tmp = CmdBuildVirtualRailVehicle(tv->engine_type);
if ( tmp ) {
if (tmp) {
tmp->cargo_type = tv->cargo_type;
tmp->cargo_subtype = tv->cargo_subtype;
CmdMoveRailVehicle(INVALID_TILE, DC_EXEC, (1<<21) | tmp->index, tail->index, 0);
CmdMoveRailVehicle(INVALID_TILE, DC_EXEC, (1 << 21) | tmp->index, tail->index, 0);
tail = tmp;
}
tv = tv->GetNextUnit();
@ -965,8 +975,9 @@ CommandCost CmdVirtualTrainFromTrain(TileIndex tile, DoCommandFlag flags, uint32
VehicleID vehicle_id = p1;
Vehicle* vehicle = Vehicle::GetIfValid(vehicle_id);
if (vehicle == nullptr || vehicle->type != VEH_TRAIN)
if (vehicle == NULL || vehicle->type != VEH_TRAIN) {
return CMD_ERROR;
}
Train* train = Train::From(vehicle);
@ -977,16 +988,16 @@ CommandCost CmdVirtualTrainFromTrain(TileIndex tile, DoCommandFlag flags, uint32
Train *tmp, *head, *tail;
head = CmdBuildVirtualRailVehicle(train->engine_type);
if ( !head ) return CMD_ERROR;
if (!head) return CMD_ERROR;
tail = head;
train = train->GetNextUnit();
while ( train ) {
while (train) {
tmp = CmdBuildVirtualRailVehicle(train->engine_type);
if ( tmp ) {
if (tmp) {
tmp->cargo_type = train->cargo_type;
tmp->cargo_subtype = train->cargo_subtype;
CmdMoveRailVehicle(0, DC_EXEC, (1<<21) | tmp->index, tail->index, 0);
CmdMoveRailVehicle(0, DC_EXEC, (1 << 21) | tmp->index, tail->index, 0);
tail = tmp;
}
train = train->GetNextUnit();
@ -1013,8 +1024,9 @@ CommandCost CmdDeleteVirtualTrain(TileIndex tile, DoCommandFlag flags, uint32 p1
Vehicle* vehicle = Vehicle::GetIfValid(vehicle_id);
if (vehicle == nullptr || vehicle->type != VEH_TRAIN)
if (vehicle == NULL || vehicle->type != VEH_TRAIN) {
return CMD_ERROR;
}
Train* train = Train::From(vehicle);
@ -1044,8 +1056,9 @@ CommandCost CmdReplaceTemplateVehicle(TileIndex tile, DoCommandFlag flags, uint3
TemplateVehicle* template_vehicle = TemplateVehicle::GetIfValid(template_vehicle_id);
Vehicle* vehicle = Vehicle::GetIfValid(virtual_train_id);
if (vehicle == nullptr || vehicle->type != VEH_TRAIN)
if (vehicle == NULL || vehicle->type != VEH_TRAIN) {
return CMD_ERROR;
}
Train* train = Train::From(vehicle);
@ -1054,16 +1067,17 @@ CommandCost CmdReplaceTemplateVehicle(TileIndex tile, DoCommandFlag flags, uint3
if (should_execute) {
VehicleID old_ID = INVALID_VEHICLE;
if (template_vehicle != nullptr) {
if (template_vehicle != NULL) {
old_ID = template_vehicle->index;
delete template_vehicle;
template_vehicle = nullptr;
template_vehicle = NULL;
}
template_vehicle = TemplateVehicleFromVirtualTrain(train);
if (template_vehicle == nullptr)
if (template_vehicle == NULL) {
return CMD_ERROR;
}
// Make sure our replacements still point to the correct thing.
if (old_ID != template_vehicle->index) {
@ -1098,20 +1112,21 @@ CommandCost CmdTemplateVehicleFromTrain(TileIndex tile, DoCommandFlag flags, uin
Vehicle *t = Vehicle::GetIfValid(p1);
Train *clicked = Train::GetIfValid(t->index);
if (!clicked)
return CMD_ERROR;
if (!clicked) return CMD_ERROR;
Train *init_clicked = clicked;
int len = CountVehiclesInChain(clicked);
if (!TemplateVehicle::CanAllocateItem(len))
if (!TemplateVehicle::CanAllocateItem(len)) {
return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0;
if (should_execute) {
TemplateVehicle *tmp, *prev=0;
for (; clicked; clicked=clicked->Next()) {
TemplateVehicle *tmp;
TemplateVehicle *prev = NULL;
for (; clicked != NULL; clicked = clicked->Next()) {
tmp = new TemplateVehicle(clicked->engine_type);
SetupTemplateVehicleFromVirtual(tmp, prev, clicked);
prev = tmp;
@ -1120,7 +1135,7 @@ CommandCost CmdTemplateVehicleFromTrain(TileIndex tile, DoCommandFlag flags, uin
tmp->First()->SetRealLength(CeilDiv(init_clicked->gcache.cached_total_length * 10, TILE_SIZE));
tv = tmp->First();
if (!tv) return CMD_ERROR;
if (!tv) return CMD_ERROR;
InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0);
}
@ -1142,8 +1157,7 @@ CommandCost CmdDeleteTemplateVehicle(TileIndex tile, DoCommandFlag flags, uint32
// Identify template to delete
TemplateVehicle *del = TemplateVehicle::GetIfValid(p1);
if (del == NULL)
return CMD_ERROR;
if (del == NULL) return CMD_ERROR;
bool should_execute = (flags & DC_EXEC) != 0;
@ -1181,8 +1195,9 @@ CommandCost CmdIssueTemplateReplacement(TileIndex tile, DoCommandFlag flags, uin
if (should_execute) {
bool succeeded = IssueTemplateReplacement(group_id, template_id);
if (!succeeded)
if (!succeeded) {
return CMD_ERROR;
}
InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0);
}
@ -1207,8 +1222,9 @@ CommandCost CmdDeleteTemplateReplacement(TileIndex tile, DoCommandFlag flags, ui
if (should_execute) {
TemplateReplacement* tr = GetTemplateReplacementByGroupID(group_id);
if (tr != NULL)
if (tr != NULL) {
delete tr;
}
InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0);
}

@ -42,6 +42,7 @@
#include "safeguards.h"
Sorting _sorting;
static GUIVehicleList::SortFunction VehicleNumberSorter;
@ -952,7 +953,10 @@ struct RefitWindow : public Window {
if (this->order == INVALID_VEH_ORDER_ID) {
bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX;
if (DoCommandP(v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16 | this->is_virtual_train << 5, GetCmdRefitVeh(v)) && delete_window) delete this;
if (DoCommandP(v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16 | this->is_virtual_train << 5,
GetCmdRefitVeh(v)) && delete_window) {
delete this;
}
} else {
if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->cargo->subtype << 8 | this->order << 16 | this->is_virtual_train << 5, CMD_ORDER_REFIT)) delete this;
}

@ -2192,7 +2192,7 @@ bool HandleViewportClicked(const ViewPort *vp, int x, int y)
WindowClass wc = _thd.GetCallbackWnd()->window_class;
if (_ctrl_pressed && v->owner == _local_company) {
StartStopVehicle(v, true);
} else if ( wc != WC_CREATE_TEMPLATE && wc != WC_TEMPLATEGUI_MAIN) {
} else if (wc != WC_CREATE_TEMPLATE && wc != WC_TEMPLATEGUI_MAIN) {
ShowVehicleViewWindow(v);
}
}

@ -26,7 +26,6 @@ enum BuildVehicleWidgets {
WID_BV_SHOW_HIDE, ///< Button to hide or show the selected engine.
WID_BV_BUILD_SEL, ///< Build button.
WID_BV_RENAME, ///< Rename button.
BUILD_VEHICLE_WIDGET_BUILD, /// TODO: own
};
#endif /* WIDGETS_BUILD_VEHICLE_WIDGET_H */

Loading…
Cancel
Save