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

This commit is contained in:
Jonathan G Rennison
2016-02-14 02:30:03 +00:00
parent 6be2efc084
commit a31e7ac87d
23 changed files with 712 additions and 588 deletions

View File

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

View File

@@ -4969,61 +4969,61 @@ STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
STR_TMPL_RPL_TITLE :{WHITE}Template Replacement STR_TMPL_RPL_TITLE :{WHITE}Template Replacement
STR_TMPL_TEMPLATE_REPLACEMENT :Template Replacement STR_TMPL_TEMPLATE_REPLACEMENT :Template Replacement
STR_TMPL_TRAINS_IN_GROUP :{BLACK}Trains in group STR_TMPL_TRAINS_IN_GROUP :{BLACK}Trains in group
STR_TMPL_AVAILABLE_TEMPLATES :{BLACK}Available Templates STR_TMPL_AVAILABLE_TEMPLATES :{BLACK}Available Templates
STR_TMPL_DEFINE_TEMPLATE :{BLACK}New STR_TMPL_DEFINE_TEMPLATE :{BLACK}New
STR_TMPL_EDIT_TEMPLATE :{BLACK}Edit STR_TMPL_EDIT_TEMPLATE :{BLACK}Edit
STR_TMPL_CREATE_CLONE_VEH :{BLACK}Clone STR_TMPL_CREATE_CLONE_VEH :{BLACK}Clone
STR_TMPL_DELETE_TEMPLATE :{BLACK}Delete STR_TMPL_DELETE_TEMPLATE :{BLACK}Delete
STR_TMPL_RPL_ALL_TMPL :{BLACK}Replace All Templates STR_TMPL_RPL_ALL_TMPL :{BLACK}Replace All Templates
STR_TMPL_NEW_VEHICLE :{BLACK}New Vehicle STR_TMPL_NEW_VEHICLE :{BLACK}New Vehicle
STR_TMPL_CONFIRM :{BLACK}Ok STR_TMPL_CONFIRM :{BLACK}Ok
STR_TMPL_CANCEL :{BLACK}Cancel STR_TMPL_CANCEL :{BLACK}Cancel
STR_TMPL_NEW :{BLACK}New Template Vehicle STR_TMPL_NEW :{BLACK}New Template Vehicle
STR_TMPL_REFIT :{BLACK}Refit STR_TMPL_REFIT :{BLACK}Refit
STR_TMPL_GROUP_INFO :{BLACK}Group Info: {ORANGE} STR_TMPL_GROUP_INFO :{BLACK}Group Info: {ORANGE}
STR_TMPL_TEMPLATE_INFO :{BLACK}Template Info: {ORANGE} STR_TMPL_TEMPLATE_INFO :{BLACK}Template Info: {ORANGE}
STR_TMPL_RPL_START :{BLACK}Start replacing STR_TMPL_RPL_START :{BLACK}Start replacing
STR_TMPL_RPL_STOP :{BLACK}Stop replacing STR_TMPL_RPL_STOP :{BLACK}Stop replacing
STR_TMPL_TRAIN_OVR_VALUE :{TINY_FONT}{BLACK}Train Value: {CURRENCY_SHORT} 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 :{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_nogold :{TINY_FONT}{BLACK}Buying Cost: {CURRENCY_LONG}
STR_TMPL_TEMPLATE_OVR_VALUE_nogoldandcurrency :{TINY_FONT}{BLACK}Buying Cost: 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_notinyfont :{BLACK}Buying Cost: {GOLD}{CURRENCY_LONG}
STR_TMPL_TEMPLATE_OVR_VALUE_notinyfontandblack :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_WARNING_FREE_WAGON :{RED}Free Chain: not runnable!
STR_TMPL_TEST :{ORANGE}Test String: {RAW_STRING} {RAW_STRING} STR_TMPL_TEST :{ORANGE}Test String: {RAW_STRING} {RAW_STRING}
STR_TMPL_GROUP_USES_TEMPLATE :{BLACK}Template in use: {NUM} STR_TMPL_GROUP_USES_TEMPLATE :{BLACK}Template in use: {NUM}
STR_TMP_TEMPLATE_IN_USE :Template is in use STR_TMP_TEMPLATE_IN_USE :Template is in use
STR_TMPL_GROUP_NUM_TRAINS :{BLACK}{NUM} STR_TMPL_GROUP_NUM_TRAINS :{BLACK}{NUM}
STR_TMPL_CREATEGUI_TITLE :{WHITE}Create/Edit Template Vehicle STR_TMPL_CREATEGUI_TITLE :{WHITE}Create/Edit Template Vehicle
STR_TMPL_MAINGUI_DEFINEDGROUPS :{BLACK}Defined Groups for Company STR_TMPL_MAINGUI_DEFINEDGROUPS :{BLACK}Defined Groups for Company
STR_TMPL_TMPLRPL_EX_DIFF_RAILTYPE :Uses Template of different rail type 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 :{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_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 :{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_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 :{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_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_USEDEPOT :use depot
STR_TMPL_CONFIG_KEEPREMAINDERS :keep rem STR_TMPL_CONFIG_KEEPREMAINDERS :keep rem
STR_TMPL_CONFIG_REFIT :refit STR_TMPL_CONFIG_REFIT :refit
STR_TMPL_NUM_TRAINS_NEED_RPL :# trains to replace: STR_TMPL_NUM_TRAINS_NEED_RPL :# trains to replace:
STR_TMPL_CARGO_SUMMARY :{CARGO_LONG} STR_TMPL_CARGO_SUMMARY :{CARGO_LONG}
STR_TMPL_CARGO_SUMMARY_MULTI :{CARGO_LONG} (x{NUM}) STR_TMPL_CARGO_SUMMARY_MULTI :{CARGO_LONG} (x{NUM})
STR_TMPL_RPLALLGUI_TITLE :{WHITE}Replace all Templace Vehicles 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 :{BLACK}Choose Vehicle Type and Replacement
STR_TMPL_RPLALLGUI_INSET_TOP_1 :{BLACK}Template Engines STR_TMPL_RPLALLGUI_INSET_TOP_1 :{BLACK}Template Engines
STR_TMPL_RPLALLGUI_INSET_TOP_2 :{BLACK}Buyable 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_INSET_BOTTOM :{BLACK}Current Template List (updated only after replacement)
STR_TMPL_RPLALLGUI_BUTTON_RPLALL :{BLACK}Replace All STR_TMPL_RPLALLGUI_BUTTON_RPLALL :{BLACK}Replace All
STR_TMPL_RPLALLGUI_BUTTON_APPLY :{BLACK}Apply STR_TMPL_RPLALLGUI_BUTTON_APPLY :{BLACK}Apply
STR_TMPL_RPLALLGUI_BUTTON_CANCEL :{BLACK}Cancel 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_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.

View File

@@ -1772,7 +1772,7 @@ void CheckOrders(const Vehicle *v)
/* Only check every 20 days, so that we don't flood the message log */ /* 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') */ /* 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; const Order *order;
StringID message = INVALID_STRING_ID; StringID message = INVALID_STRING_ID;

View File

@@ -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 "stdafx.h"
#include "gfx_func.h" #include "gfx_func.h"
@@ -29,12 +40,13 @@
#include "order_backup.h" #include "order_backup.h"
#include "group.h" #include "group.h"
#include "company_base.h" #include "company_base.h"
#include "train.h"
#include "tbtr_template_gui_create.h" #include "tbtr_template_gui_create.h"
#include "tbtr_template_vehicle.h" #include "tbtr_template_vehicle.h"
#include "tbtr_template_vehicle_func.h" #include "tbtr_template_vehicle_func.h"
#include "train.h" #include "safeguards.h"
class TemplateReplaceWindow; class TemplateReplaceWindow;
@@ -83,13 +95,13 @@ static const NWidgetPart _widgets[] = {
}; };
static WindowDesc _template_create_window_desc( static WindowDesc _template_create_window_desc(
WDP_AUTO, // window position WDP_AUTO, // window position
"template create window", // const char* ini_key "template create window", // const char* ini_key
456, 100, // window size 456, 100, // window size
WC_CREATE_TEMPLATE, // window class WC_CREATE_TEMPLATE, // window class
WC_NONE, // parent window class WC_TEMPLATEGUI_MAIN, // parent window class
WDF_CONSTRUCTION, // window flags WDF_CONSTRUCTION, // window flags
_widgets, lengthof(_widgets) // widgets + num widgets _widgets, lengthof(_widgets) // widgets + num widgets
); );
static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Vehicle *head) 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; 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 { class TemplateCreateWindow : public Window {
@@ -118,7 +131,7 @@ private:
Train* virtual_train; Train* virtual_train;
bool editMode; bool editMode;
bool *noticeParent; 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; bool virtualTrainChangedNotice;
VehicleID sel; VehicleID sel;
VehicleID vehicle_over; VehicleID vehicle_over;
@@ -142,8 +155,7 @@ public:
virtualTrainChangedNotice = false; virtualTrainChangedNotice = false;
this->editTemplate = to_edit; this->editTemplate = to_edit;
if (to_edit) editMode = true; editMode = (to_edit != NULL);
else editMode = false;
this->sel = INVALID_VEHICLE; this->sel = INVALID_VEHICLE;
this->vehicle_over = INVALID_VEHICLE; this->vehicle_over = INVALID_VEHICLE;
@@ -157,9 +169,9 @@ public:
~TemplateCreateWindow() ~TemplateCreateWindow()
{ {
if (virtual_train != nullptr) { if (virtual_train != NULL) {
DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN); DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN);
virtual_train = nullptr; virtual_train = NULL;
} }
SetWindowClassesDirty(WC_TRAINS_LIST); SetWindowClassesDirty(WC_TRAINS_LIST);
@@ -167,12 +179,11 @@ public:
/* more cleanup */ /* more cleanup */
*createWindowOpen = false; *createWindowOpen = false;
DeleteWindowById(WC_BUILD_VIRTUAL_TRAIN, this->window_number); DeleteWindowById(WC_BUILD_VIRTUAL_TRAIN, this->window_number);
} }
void SetVirtualTrain(Train* const train) void SetVirtualTrain(Train* const train)
{ {
if (virtual_train != nullptr) { if (virtual_train != NULL) {
DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN); DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN);
} }
@@ -210,19 +221,18 @@ public:
this->SetWidgetDirty(TCW_CLONE); this->SetWidgetDirty(TCW_CLONE);
this->ToggleWidgetLoweredState(TCW_CLONE); this->ToggleWidgetLoweredState(TCW_CLONE);
if (this->IsWidgetLowered(TCW_CLONE)) { if (this->IsWidgetLowered(TCW_CLONE)) {
static const CursorID clone_icon = SPR_CURSOR_CLONE_TRAIN; SetObjectToPlaceWnd(SPR_CURSOR_CLONE_TRAIN, PAL_NONE, HT_VEHICLE, this);
SetObjectToPlaceWnd(clone_icon, PAL_NONE, HT_VEHICLE, this);
} else { } else {
ResetObjectToPlace(); ResetObjectToPlace();
} }
break; break;
} }
case TCW_OK: { case TCW_OK: {
uint32 templateIndex = (editTemplate != nullptr) ? editTemplate->index : INVALID_VEHICLE; uint32 templateIndex = (editTemplate != NULL) ? editTemplate->index : INVALID_VEHICLE;
if (virtual_train != nullptr) { if (virtual_train != NULL) {
DoCommandP(0, templateIndex, virtual_train->index, CMD_REPLACE_TEMPLATE_VEHICLE); DoCommandP(0, templateIndex, virtual_train->index, CMD_REPLACE_TEMPLATE_VEHICLE);
virtual_train = nullptr; virtual_train = NULL;
} else if (templateIndex != INVALID_VEHICLE) { } else if (templateIndex != INVALID_VEHICLE) {
DoCommandP(0, templateIndex, 0, CMD_DELETE_TEMPLATE_VEHICLE); DoCommandP(0, templateIndex, 0, CMD_DELETE_TEMPLATE_VEHICLE);
} }
@@ -243,9 +253,9 @@ public:
virtual bool OnVehicleSelect(const Vehicle *v) virtual bool OnVehicleSelect(const Vehicle *v)
{ {
// throw away the current virtual train // throw away the current virtual train
if (virtual_train != nullptr) { if (virtual_train != NULL) {
DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN); DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN);
virtual_train = nullptr; virtual_train = NULL;
} }
// create a new one // create a new one
@@ -261,8 +271,8 @@ public:
{ {
switch(widget) { switch(widget) {
case TCW_NEW_TMPL_PANEL: { case TCW_NEW_TMPL_PANEL: {
if ( this->virtual_train ) { 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); 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(0, CeilDiv(virtual_train->gcache.cached_total_length * 10, TILE_SIZE));
SetDParam(1, 1); SetDParam(1, 1);
DrawString(r.left, r.right, r.top, STR_TINY_BLACK_DECIMAL, TC_BLACK, SA_RIGHT); DrawString(r.left, r.right, r.top, STR_TINY_BLACK_DECIMAL, TC_BLACK, SA_RIGHT);
@@ -270,7 +280,7 @@ public:
break; break;
} }
case TCW_INFO_PANEL: { case TCW_INFO_PANEL: {
if ( this->virtual_train ) { if (this->virtual_train) {
DrawPixelInfo tmp_dpi, *old_dpi; DrawPixelInfo tmp_dpi, *old_dpi;
if (!FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left, r.bottom - r.top)) break; 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); DrawString(8, r.right, 4 - this->vscroll->GetPosition(), STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE);
/* Draw cargo summary */ /* Draw cargo summary */
CargoArray cargo_caps; 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; cargo_caps[tmp->cargo_type] += tmp->cargo_cap;
}
int y = 30 - this->vscroll->GetPosition(); int y = 30 - this->vscroll->GetPosition();
for (CargoID i = 0; i < NUM_CARGO; ++i) { for (CargoID i = 0; i < NUM_CARGO; ++i) {
if ( cargo_caps[i] > 0 ) { if (cargo_caps[i] > 0) {
SetDParam(0, i); SetDParam(0, i);
SetDParam(1, cargo_caps[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); 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; break;
} }
} }
virtual void OnTick() virtual void OnTick()
{ {
if (virtualTrainChangedNotice) { if (virtualTrainChangedNotice) {
@@ -315,6 +326,7 @@ public:
virtualTrainChangedNotice = false; virtualTrainChangedNotice = false;
} }
} }
virtual void OnDragDrop(Point pt, int widget) virtual void OnDragDrop(Point pt, int widget)
{ {
switch (widget) { switch (widget) {
@@ -344,10 +356,11 @@ public:
Train* train_to_delete = Train::Get(this->sel); Train* train_to_delete = Train::Get(this->sel);
if (virtual_train == train_to_delete) if (virtual_train == train_to_delete) {
virtual_train = (_ctrl_pressed) ? nullptr : virtual_train->GetNextUnit(); 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; this->sel = INVALID_VEHICLE;
@@ -357,6 +370,7 @@ public:
default: default:
this->sel = INVALID_VEHICLE; this->sel = INVALID_VEHICLE;
this->SetDirty(); this->SetDirty();
break;
} }
_cursor.vehchain = false; _cursor.vehchain = false;
this->sel = INVALID_VEHICLE; this->sel = INVALID_VEHICLE;
@@ -408,15 +422,15 @@ public:
uint height = 30; uint height = 30;
CargoArray cargo_caps; CargoArray cargo_caps;
if (virtual_train != nullptr) { if (virtual_train != NULL) {
for (Train *train = virtual_train; train != nullptr; train = train->Next()) { for (Train *train = virtual_train; train != NULL; train = train->Next()) {
width += train->GetDisplayImageWidth(); width += train->GetDisplayImageWidth();
cargo_caps[train->cargo_type] += train->cargo_cap; cargo_caps[train->cargo_type] += train->cargo_cap;
} }
for (CargoID i = 0; i < NUM_CARGO; ++i) { for (CargoID i = 0; i < NUM_CARGO; ++i) {
if ( cargo_caps[i] > 0 ) { if (cargo_caps[i] > 0) {
height += this->line_height/3; height += this->line_height / 3;
} }
} }
} }
@@ -429,6 +443,7 @@ public:
this->DrawWidgets(); this->DrawWidgets();
} }
struct GetDepotVehiclePtData { struct GetDepotVehiclePtData {
const Vehicle *head; const Vehicle *head;
const Vehicle *wagon; const Vehicle *wagon;
@@ -449,7 +464,7 @@ public:
const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(TCW_NEW_TMPL_PANEL); const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(TCW_NEW_TMPL_PANEL);
/* In case of RTL the widgets are swapped as a whole */ /* In case of RTL the widgets are swapped as a whole */
if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x; if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x;
x -= TRAIN_FRONT_SPACE; x -= TRAIN_FRONT_SPACE;
uint xm = x; uint xm = x;
@@ -461,7 +476,6 @@ public:
d->head = d->wagon = v; d->head = d->wagon = v;
if (xm <= this->header_width) { if (xm <= this->header_width) {
if (wagon) return MODE_ERROR; if (wagon) return MODE_ERROR;
return MODE_SHOW_VEHICLE; return MODE_SHOW_VEHICLE;
@@ -494,7 +508,7 @@ public:
if (sel != INVALID_VEHICLE) { if (sel != INVALID_VEHICLE) {
this->sel = INVALID_VEHICLE; this->sel = INVALID_VEHICLE;
TrainDepotMoveVehicle(v, sel, gdvp.head); TrainDepotMoveVehicle(v, sel, gdvp.head);
} else if (v != NULL) { } else if (v != NULL) {
int image = v->GetImage(_current_text_dir == TD_RTL ? DIR_E : DIR_W, EIT_PURCHASE); int image = v->GetImage(_current_text_dir == TD_RTL ? DIR_E : DIR_W, EIT_PURCHASE);
SetObjectToPlaceWnd(image, GetVehiclePalette(v), HT_DRAG, this); SetObjectToPlaceWnd(image, GetVehiclePalette(v), HT_DRAG, this);
@@ -515,7 +529,7 @@ public:
void ShowTemplateCreateWindow(TemplateVehicle *to_edit, bool *noticeParent, bool *createWindowOpen, int step_h) 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); 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; VehicleID virtual_train_id = p2;
DoCommandP(0, virtual_train_id, 0, CMD_DELETE_VIRTUAL_TRAIN); DoCommandP(0, virtual_train_id, 0, CMD_DELETE_VIRTUAL_TRAIN);
} }

View File

@@ -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 #ifndef TEMPLATE_GUI_CREATE
#define TEMPLATE_GUI_CREATE #define TEMPLATE_GUI_CREATE

View File

@@ -1,4 +1,4 @@
/* $Id: build_vehicle_gui.cpp 23792 2012-01-12 19:23:00Z yexo $ */ /* $Id$ */
/* /*
* This file is part of OpenTTD. * 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/>. * 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 "stdafx.h"
#include "engine_base.h" #include "engine_base.h"
@@ -30,14 +30,14 @@
#include "engine_gui.h" #include "engine_gui.h"
#include "cargotype.h" #include "cargotype.h"
#include "core/geometry_func.hpp" #include "core/geometry_func.hpp"
#include "vehicle_gui.h"
#include "tbtr_template_gui_create_virtualtrain.h"
#include "widgets/build_vehicle_widget.h" #include "widgets/build_vehicle_widget.h"
#include "table/strings.h" #include "table/strings.h"
#include "tbtr_template_gui_create_virtualtrain.h" #include "safeguards.h"
#include "vehicle_gui.h"
static const NWidgetPart _nested_build_vehicle_widgets[] = { static const NWidgetPart _nested_build_vehicle_widgets[] = {
NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL),
@@ -425,13 +425,13 @@ struct BuildVirtualTrainWindow : Window {
byte cargo_filter_criteria; ///< Selected cargo filter byte cargo_filter_criteria; ///< Selected cargo filter
int details_height; ///< Minimal needed height of the details panels (found so far). int details_height; ///< Minimal needed height of the details panels (found so far).
Scrollbar *vscroll; 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; bool *noticeParent;
BuildVirtualTrainWindow(WindowDesc *desc, Train **vt, bool *notice) : Window(desc) BuildVirtualTrainWindow(WindowDesc *desc, Train **vt, bool *notice) : Window(desc)
{ {
this->vehicle_type = VEH_TRAIN; this->vehicle_type = VEH_TRAIN;
this->window_number = 0;//tile == INVALID_TILE ? (int)type : tile; this->window_number = 0;
this->sel_engine = INVALID_ENGINE; this->sel_engine = INVALID_ENGINE;
@@ -688,6 +688,7 @@ struct BuildVirtualTrainWindow : Window {
case WID_BV_CARGO_FILTER_DROPDOWN: case WID_BV_CARGO_FILTER_DROPDOWN:
SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]); SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]);
break;
} }
} }
@@ -717,7 +718,9 @@ struct BuildVirtualTrainWindow : Window {
{ {
switch (widget) { switch (widget) {
case WID_BV_LIST: 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; break;
case WID_BV_SORT_ASCENDING_DESCENDING: case WID_BV_SORT_ASCENDING_DESCENDING:
@@ -795,7 +798,7 @@ struct BuildVirtualTrainWindow : Window {
} else { } else {
VehicleID target = (*(this->virtual_train))->GetLastUnit()->index; 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; *noticeParent = true;
} }
@@ -814,13 +817,13 @@ void CcAddVirtualEngine(const CommandCost &result, TileIndex tile, uint32 p1, ui
} }
static WindowDesc _build_vehicle_desc( static WindowDesc _build_vehicle_desc(
WDP_AUTO, // window position WDP_AUTO, // window position
"template create virtual train",// const char* ini_key "template create virtual train", // const char* ini_key
240, 268, // window size 240, 268, // window size
WC_BUILD_VIRTUAL_TRAIN, // window class WC_BUILD_VIRTUAL_TRAIN, // window class
WC_CREATE_TEMPLATE, // parent window class WC_CREATE_TEMPLATE, // parent window class
WDF_CONSTRUCTION, // window flags WDF_CONSTRUCTION, // window flags
_nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets) // widgets + num widgets _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets) // widgets + num widgets
); );
void ShowBuildVirtualTrainWindow(Train **vt, bool *noticeParent) void ShowBuildVirtualTrainWindow(Train **vt, bool *noticeParent)

View File

@@ -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 #ifndef BUILD_VIRTUAL_TRAIN_GUI
#define BUILD_VIRTUAL_TRAIN_GUI #define BUILD_VIRTUAL_TRAIN_GUI

View File

@@ -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" /** @file tbtr_template_gui_main.cpp Template-based train replacement: main GUI. */
#include <iostream>
#include <stdio.h>
#include "stdafx.h" #include "stdafx.h"
#include "command_func.h" #include "command_func.h"
@@ -47,7 +50,11 @@
#include "tbtr_template_gui_main.h" #include "tbtr_template_gui_main.h"
#include "tbtr_template_gui_create.h" #include "tbtr_template_gui_create.h"
#include "tbtr_template_vehicle.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; typedef GUIList<const Group*> GUIGroupList;
@@ -168,7 +175,7 @@ static WindowDesc _replace_rail_vehicle_desc(
"template replace window", "template replace window",
456, 156, 456, 156,
WC_TEMPLATEGUI_MAIN, WC_TEMPLATEGUI_MAIN,
WC_NONE, // parent window class WC_NONE, // parent window class
WDF_CONSTRUCTION, WDF_CONSTRUCTION,
_widgets, lengthof(_widgets) _widgets, lengthof(_widgets)
); );
@@ -176,7 +183,7 @@ static WindowDesc _replace_rail_vehicle_desc(
class TemplateReplaceWindow : public Window { class TemplateReplaceWindow : public Window {
private: private:
GUIGroupList groups; ///< List of groups GUIGroupList groups; ///< List of groups
byte unitnumber_digits; byte unitnumber_digits;
SmallVector<int, 16> indents; ///< Indentation levels SmallVector<int, 16> indents; ///< Indentation levels
@@ -207,7 +214,7 @@ public:
this->unitnumber_digits = dig; this->unitnumber_digits = dig;
this->sel_railtype = RAILTYPE_BEGIN; 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; this->line_height = step_h;
@@ -311,7 +318,7 @@ public:
this->BuildGroupList(_local_company); this->BuildGroupList(_local_company);
if ( templateNotice ) { if (templateNotice) {
BuildTemplateGuiList(&this->templates, vscroll[1], _local_company, this->sel_railtype); BuildTemplateGuiList(&this->templates, vscroll[1], _local_company, this->sel_railtype);
templateNotice = false; templateNotice = false;
this->SetDirty(); this->SetDirty();
@@ -333,14 +340,14 @@ public:
short count_columns = 0; short count_columns = 0;
short max_columns = 2; short max_columns = 2;
for ( ; tmp; tmp=tmp->Next()) { for (; tmp != NULL; tmp = tmp->Next()) {
cargo_caps[tmp->cargo_type] += tmp->cargo_cap; cargo_caps[tmp->cargo_type] += tmp->cargo_cap;
} }
for (CargoID i = 0; i < NUM_CARGO; ++i) { for (CargoID i = 0; i < NUM_CARGO; ++i) {
if ( cargo_caps[i] > 0 ) { if (cargo_caps[i] > 0) {
if (count_columns % max_columns == 0) { if (count_columns % max_columns == 0) {
height += this->line_height/3; height += this->line_height / 3;
} }
++count_columns; ++count_columns;
@@ -356,7 +363,7 @@ public:
virtual void OnClick(Point pt, int widget, int click_count) virtual void OnClick(Point pt, int widget, int click_count)
{ {
if ( this->editInProgress ) return; if (this->editInProgress) return;
switch (widget) { switch (widget) {
case TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REUSE: { case TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REUSE: {
@@ -424,28 +431,26 @@ public:
ShowDropDownList(this, GetRailTypeDropDownList(true), sel_railtype, TRW_WIDGET_TRAIN_RAILTYPE_DROPDOWN); ShowDropDownList(this, GetRailTypeDropDownList(true), sel_railtype, TRW_WIDGET_TRAIN_RAILTYPE_DROPDOWN);
break; break;
case TRW_WIDGET_TOP_MATRIX: { 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(); 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() ) { if (newindex == this->selected_group_index || newindex >= this->groups.Length()) {
this->selected_group_index = -1; this->selected_group_index = -1;
} } else if (newindex < this->groups.Length()) {
else if ((newindex >= 0) && (newindex < this->groups.Length())) {
this->selected_group_index = newindex; this->selected_group_index = newindex;
} }
break; break;
} }
case TRW_WIDGET_BOTTOM_MATRIX: { 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(); 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; this->selected_template_index = -1;
} } else if (newindex < templates.Length()) {
else if ((newindex >= 0) && (newindex < templates.Length())) {
this->selected_template_index = newindex; this->selected_template_index = newindex;
} }
break; break;
} }
case TRW_WIDGET_START: { case TRW_WIDGET_START: {
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()) &&
(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; uint32 tv_index = ((this->templates)[selected_template_index])->index;
int current_group_index = (this->groups)[this->selected_group_index]->index; int current_group_index = (this->groups)[this->selected_group_index]->index;
@@ -454,8 +459,9 @@ public:
break; break;
} }
case TRW_WIDGET_STOP: 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; return;
}
int current_group_index = (this->groups)[this->selected_group_index]->index; int current_group_index = (this->groups)[this->selected_group_index]->index;
@@ -481,7 +487,7 @@ public:
virtual void OnDropdownSelect(int widget, int index) 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 if (temp == this->sel_railtype) return; // we didn't select a new one. No need to change anything
this->sel_railtype = temp; this->sel_railtype = temp;
/* Reset scrollbar positions */ /* Reset scrollbar positions */
@@ -508,7 +514,7 @@ public:
virtual void OnTick() virtual void OnTick()
{ {
if ( templateNotice ) { if (templateNotice) {
BuildTemplateGuiList(&this->templates, this->vscroll[1], this->owner, this->sel_railtype); BuildTemplateGuiList(&this->templates, this->vscroll[1], this->owner, this->sel_railtype);
this->SetDirty(); this->SetDirty();
templateNotice = false; templateNotice = false;
@@ -527,12 +533,13 @@ public:
short FindTemplateIndexForGroup(short gid) const short FindTemplateIndexForGroup(short gid) const
{ {
TemplateReplacement *tr = GetTemplateReplacementByGroupID(gid); TemplateReplacement *tr = GetTemplateReplacementByGroupID(gid);
if ( !tr ) if (!tr) return -1;
return -1;
for ( uint32 i=0; i<this->templates.Length(); ++i ) for (uint32 i = 0; i < this->templates.Length(); ++i) {
if ( templates[i]->index == tr->sel_template ) if (templates[i]->index == tr->sel_template) {
return i; return i;
}
}
return -1; return -1;
} }
@@ -604,47 +611,48 @@ public:
int max = min(this->vscroll[0]->GetPosition() + this->vscroll[0]->GetCapacity(), this->groups.Length()); int max = min(this->vscroll[0]->GetPosition() + this->vscroll[0]->GetCapacity(), this->groups.Length());
/* Then treat all groups defined by/for the current company */ /* 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]; const Group *g = (this->groups)[i];
short g_id = g->index; short g_id = g->index;
/* Fill the background of the current cell in a darker tone for the currently selected template */ /* Fill the background of the current cell in a darker tone for the currently selected template */
if ( this->selected_group_index == i ) { if (this->selected_group_index == i) {
GfxFillRect(left, y, right, y+(this->line_height)/2, _colour_gradient[COLOUR_GREY][3]); GfxFillRect(left, y, right, y+(this->line_height) / 2, _colour_gradient[COLOUR_GREY][3]);
} }
SetDParam(0, g_id); SetDParam(0, g_id);
StringID str = STR_GROUP_NAME; 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 */ /* Draw the template in use for this group, if there is one */
short template_in_use = FindTemplateIndexForGroup(g_id); short template_in_use = FindTemplateIndexForGroup(g_id);
if ( template_in_use >= 0 ) { if (template_in_use >= 0) {
SetDParam(0, template_in_use); SetDParam(0, template_in_use);
DrawString ( left, right, y+2, STR_TMPL_GROUP_USES_TEMPLATE, TC_BLACK, 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 */
/* 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);
else if ( GetTemplateReplacementByGroupID(g_id) ) {
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 */ /* Draw the number of trains that still need to be treated by the currently selected template replacement */
TemplateReplacement *tr = GetTemplateReplacementByGroupID(g_id); TemplateReplacement *tr = GetTemplateReplacementByGroupID(g_id);
if ( tr ) { if (tr) {
TemplateVehicle *tv = TemplateVehicle::Get(tr->sel_template); TemplateVehicle *tv = TemplateVehicle::Get(tr->sel_template);
int num_trains = NumTrainsNeedTemplateReplacement(g_id, tv); int num_trains = NumTrainsNeedTemplateReplacement(g_id, tv);
// Draw text // Draw text
TextColour color = TC_GREY; TextColour color = TC_GREY;
if ( num_trains ) color = TC_BLACK; if (num_trains) color = TC_BLACK;
DrawString(left, right-16, y+2, STR_TMPL_NUM_TRAINS_NEED_RPL, color, SA_RIGHT); DrawString(left, right - 16, y + 2, STR_TMPL_NUM_TRAINS_NEED_RPL, color, SA_RIGHT);
// Draw number // Draw number
if ( num_trains ) color = TC_ORANGE; if (num_trains ) {
else color = TC_GREY; color = TC_ORANGE;
} else {
color = TC_GREY;
}
SetDParam(0, num_trains); 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()); uint max = min(draw_vscroll->GetPosition() + draw_vscroll->GetCapacity(), this->templates.Length());
const TemplateVehicle *v; 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]; v = (this->templates)[i];
/* Fill the background of the current cell in a darker tone for the currently selected template */ /* Fill the background of the current cell in a darker tone for the currently selected template */
if ( this->selected_template_index == (int32)i ) { if (this->selected_template_index == (int32) i) {
GfxFillRect(left, y, right, y+this->line_height, _colour_gradient[COLOUR_GREY][3]); GfxFillRect(left, y, right, y + this->line_height, _colour_gradient[COLOUR_GREY][3]);
} }
/* Draw a notification string for chains that are not runnable */ /* Draw a notification string for chains that are not runnable */
if ( v->IsFreeWagonChain() ) { 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); 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 */ /* Draw the template's length in tile-units */
SetDParam(0, v->GetRealLength()); SetDParam(0, v->GetRealLength());
SetDParam(1, 1); 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 */ /* Draw the template */
DrawTemplate(v, left+50, right, y); DrawTemplate(v, left + 50, right, y);
/* Buying cost */ /* Buying cost */
SetDParam(0, CalculateOverallTemplateCost(v)); 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 */ /* Index of current template vehicle in the list of all templates for its company */
SetDParam(0, i); 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 */ /* Draw whether the current template is in use by any group */
if ( v->NumGroupsUsingTemplate() > 0 ) { 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); 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 */ /* Draw information about template configuration settings */
TextColour color; TextColour color;
if ( v->IsSetReuseDepotVehicles() ) color = TC_LIGHT_BLUE;
else color = TC_GREY; 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); 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; 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); 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; 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); DrawString(left + 500, right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 2, STR_TMPL_CONFIG_REFIT, color, SA_LEFT);
y += line_height; y += line_height;
} }
@@ -711,13 +718,15 @@ public:
void DrawTemplateInfo(int line_height, const Rect &r) const 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; return;
}
DrawPixelInfo tmp_dpi, *old_dpi; 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; return;
}
old_dpi = _cur_dpi; old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi; _cur_dpi = &tmp_dpi;
@@ -738,20 +747,21 @@ public:
short max_columns = 2; short max_columns = 2;
CargoArray cargo_caps; CargoArray cargo_caps;
for ( ; tmp; tmp=tmp->Next() ) for (; tmp != NULL; tmp = tmp->Next()) {
cargo_caps[tmp->cargo_type] += tmp->cargo_cap; cargo_caps[tmp->cargo_type] += tmp->cargo_cap;
}
int x = left; int x = left;
for (CargoID i = 0; i < NUM_CARGO; ++i) { for (CargoID i = 0; i < NUM_CARGO; ++i) {
if ( cargo_caps[i] > 0 ) { if (cargo_caps[i] > 0) {
count_columns++; count_columns++;
SetDParam(0, i); SetDParam(0, i);
SetDParam(1, cargo_caps[i]); SetDParam(1, cargo_caps[i]);
SetDParam(2, _settings_game.vehicle.freight_trains); 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); DrawString(x, r.right, top, FreightWagonMult(i) > 1 ? STR_TMPL_CARGO_SUMMARY_MULTI : STR_TMPL_CARGO_SUMMARY, TC_LIGHT_BLUE, SA_LEFT);
x += 250; x += 250;
if ( count_columns % max_columns == 0 ) { if (count_columns % max_columns == 0) {
x = left; 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); new TemplateReplaceWindow(&_replace_rail_vehicle_desc, dig, step_h);
} }

View File

@@ -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 #ifndef TEMPLATE_GUI_H
#define TEMPLATE_GUI_H #define TEMPLATE_GUI_H

View File

@@ -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 "tbtr_template_gui_replaceall.h"
#include <stdio.h> #include <stdio.h>
#include "safeguards.h"
/* /*
* A wrapper which contains a virtual train and additional info of the template vehicle it is replacing * 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 * 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 // additional info from the template
VehicleID original_index; VehicleID original_index;
bool reuse_depot_vehicles, bool reuse_depot_vehicles;
keep_remaining_vehicles, bool keep_remaining_vehicles;
refit_as_template; bool refit_as_template;
CargoID cargo_type; CargoID cargo_type;
byte cargo_subtype; byte cargo_subtype;
@@ -133,19 +162,19 @@ static int CDECL TrainEnginesThenWagonsSorter(const EngineID *a, const EngineID
class TemplateReplacementReplaceAllWindow : public Window { class TemplateReplacementReplaceAllWindow : public Window {
private: private:
uint16 line_height; uint16 line_height;
Scrollbar *vscroll_tl, Scrollbar *vscroll_tl;
*vscroll_tr, Scrollbar *vscroll_tr;
*vscroll_bo; Scrollbar *vscroll_bo;
GUIEngineList *engines_left, GUIEngineList *engines_left;
*engines_right; GUIEngineList *engines_right;
short selected_left, short selected_left;
selected_right; short selected_right;
VirtTrainList *virtualTrains; VirtTrainList *virtualTrains;
public: public:
TemplateReplacementReplaceAllWindow(WindowDesc *wdesc) : Window(wdesc) TemplateReplacementReplaceAllWindow(WindowDesc *wdesc) : Window(wdesc)
{ {
this->CreateNestedTree(wdesc != nullptr); this->CreateNestedTree(wdesc != NULL);
this->vscroll_tl = this->GetScrollbar(RPLALL_GUI_SCROLL_TL); this->vscroll_tl = this->GetScrollbar(RPLALL_GUI_SCROLL_TL);
this->vscroll_tr = this->GetScrollbar(RPLALL_GUI_SCROLL_TR); this->vscroll_tr = this->GetScrollbar(RPLALL_GUI_SCROLL_TR);
@@ -172,14 +201,15 @@ public:
~TemplateReplacementReplaceAllWindow() ~TemplateReplacementReplaceAllWindow()
{ {
for ( uint i=0; i<this->virtualTrains->Length(); ++i ) for (uint i = 0; i<this->virtualTrains->Length(); ++i) {
delete (*this->virtualTrains)[i]->vt; delete (*this->virtualTrains)[i]->vt;
}
SetWindowClassesDirty(WC_TEMPLATEGUI_MAIN); SetWindowClassesDirty(WC_TEMPLATEGUI_MAIN);
} }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) 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_TOPLEFT:
case RPLALL_GUI_MATRIX_TOPRIGHT: case RPLALL_GUI_MATRIX_TOPRIGHT:
case RPLALL_GUI_MATRIX_BOTTOM: { case RPLALL_GUI_MATRIX_BOTTOM: {
@@ -235,19 +265,21 @@ public:
switch(widget) { switch(widget) {
case RPLALL_GUI_MATRIX_TOPLEFT: { 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(); 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; this->selected_left = -1;
else } else {
this->selected_left = newindex; this->selected_left = newindex;
}
this->SetDirty(); this->SetDirty();
break; break;
} }
case RPLALL_GUI_MATRIX_TOPRIGHT: { 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(); 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; this->selected_right = -1;
else } else {
this->selected_right = newindex; this->selected_right = newindex;
}
this->SetDirty(); this->SetDirty();
break; break;
} }
@@ -257,12 +289,13 @@ public:
} }
case RPLALL_GUI_BUTTON_APPLY: { case RPLALL_GUI_BUTTON_APPLY: {
// check if we actually did anything so far, if not, applying is forbidden // check if we actually did anything so far, if not, applying is forbidden
if ( this->virtualTrains->Length() == 0 ) if (this->virtualTrains->Length() == 0) {
return; return;
}
// first delete all current templates // first delete all current templates
this->DeleteAllTemplateTrains(); this->DeleteAllTemplateTrains();
// then build a new list from the current virtual trains // 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 // the relevant info struct
VirtTrainInfo *vti = (*this->virtualTrains)[i]; VirtTrainInfo *vti = (*this->virtualTrains)[i];
// setup template from contained train // setup template from contained train
@@ -276,8 +309,9 @@ public:
tv->cargo_subtype = vti->cargo_subtype; tv->cargo_subtype = vti->cargo_subtype;
// use the original_index information to repoint the relevant TemplateReplacement if existing // use the original_index information to repoint the relevant TemplateReplacement if existing
TemplateReplacement *tr = GetTemplateReplacementByTemplateID(vti->original_index); TemplateReplacement *tr = GetTemplateReplacementByTemplateID(vti->original_index);
if ( tr ) if (tr) {
tr->sel_template = tv->index; tr->sel_template = tv->index;
}
} }
// then close this window and return to parent // then close this window and return to parent
delete this; delete this;
@@ -294,10 +328,11 @@ public:
{ {
const TemplateVehicle *tv; const TemplateVehicle *tv;
FOR_ALL_TEMPLATES(tv) { FOR_ALL_TEMPLATES(tv) {
if ( tv->Prev() || tv->owner != _local_company ) continue; if (tv->Prev() || tv->owner != _local_company) continue;
for ( const TemplateVehicle *tmp=tv; tmp; tmp=tmp->GetNextUnit() ) { for (const TemplateVehicle *tmp = tv; tmp != NULL; tmp = tmp->GetNextUnit()) {
if ( tmp->engine_type == eid ) if (tmp->engine_type == eid) {
return true; return true;
}
} }
} }
return false; return false;
@@ -309,17 +344,17 @@ public:
TemplateVehicle *tv; TemplateVehicle *tv;
FOR_ALL_TEMPLATES(tv) { FOR_ALL_TEMPLATES(tv) {
if ( !tv->Prev() && tv->owner==this->owner ) { if (!tv->Prev() && tv->owner == this->owner) {
// setup template train // setup template train
Train *newtrain = VirtualTrainFromTemplateVehicle(tv); Train *newtrain = VirtualTrainFromTemplateVehicle(tv);
VirtTrainInfo *vti = new VirtTrainInfo(newtrain); VirtTrainInfo *vti = new VirtTrainInfo(newtrain);
// store template specific stuff // store template specific stuff
vti->original_index = tv->index; vti->original_index = tv->index;
vti->reuse_depot_vehicles = tv->reuse_depot_vehicles; vti->reuse_depot_vehicles = tv->reuse_depot_vehicles;
vti->keep_remaining_vehicles = tv->keep_remaining_vehicles; vti->keep_remaining_vehicles = tv->keep_remaining_vehicles;
vti->refit_as_template = tv->refit_as_template; vti->refit_as_template = tv->refit_as_template;
vti->cargo_type = tv->cargo_type; vti->cargo_type = tv->cargo_type;
vti->cargo_subtype = tv->cargo_subtype; vti->cargo_subtype = tv->cargo_subtype;
// add new info struct // add new info struct
*this->virtualTrains->Append() = vti; *this->virtualTrains->Append() = vti;
} }
@@ -333,8 +368,9 @@ public:
TemplateVehicle *tv, *tmp; TemplateVehicle *tv, *tmp;
FOR_ALL_TEMPLATES(tv) { FOR_ALL_TEMPLATES(tv) {
tmp = tv; tmp = tv;
if ( tmp->Prev()==0 && tmp->owner==this->owner ) if (tmp->Prev() == NULL && tmp->owner == this->owner) {
delete tmp; delete tmp;
}
} }
} }
@@ -350,7 +386,7 @@ public:
EngineID eid = e->index; EngineID eid = e->index;
const RailVehicleInfo*rvi = &e->u.rail; const RailVehicleInfo*rvi = &e->u.rail;
if ( !HasTemplateWithEngine(eid) ) continue; if (!HasTemplateWithEngine(eid)) continue;
*this->engines_left->Append() = eid; *this->engines_left->Append() = eid;
@@ -366,11 +402,13 @@ public:
bool VirtualTrainHasEngineID(EngineID eid) 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; const Train *tmp = (*this->virtualTrains)[i]->vt;
for ( ; tmp; tmp=tmp->Next() ) for (; tmp != NULL; tmp = tmp->Next()) {
if ( tmp->engine_type == eid ) if (tmp->engine_type == eid) {
return true; return true;
}
}
} }
return false; return false;
} }
@@ -378,44 +416,43 @@ public:
// after 'replace all' we need to replace the currently used templates as well // after 'replace all' we need to replace the currently used templates as well
void RebuildIncludedTemplateList() { void RebuildIncludedTemplateList() {
// first remove all engine ids // 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]; EngineID entry = (*this->engines_left)[i];
if ( !VirtualTrainHasEngineID(entry) ) if (!VirtualTrainHasEngineID(entry)) {
this->engines_left->Erase(&((*this->engines_left)[i])); this->engines_left->Erase(&((*this->engines_left)[i]));
}
} }
} }
void ReplaceAll() 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_orig = (*this->engines_left)[this->selected_left];
EngineID eid_repl = (*this->engines_right)[this->selected_right]; EngineID eid_repl = (*this->engines_right)[this->selected_right];
if ( eid_orig == eid_repl ) if (eid_orig == eid_repl) return;
return;
if ( this->virtualTrains->Length() == 0 ) if (this->virtualTrains->Length() == 0) {
this->GenerateVirtualTrains(); 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; Train *tmp = (*this->virtualTrains)[i]->vt;
while ( tmp ) { while (tmp) {
if ( tmp->engine_type == eid_orig ) { if (tmp->engine_type == eid_orig) {
// build a new virtual rail vehicle and test for success // build a new virtual rail vehicle and test for success
Train *nt = CmdBuildVirtualRailVehicle(eid_repl); Train *nt = CmdBuildVirtualRailVehicle(eid_repl);
if ( !nt ) continue; if (!nt) continue;
// include the (probably) new engine into the 'included'-list // 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 // advance the tmp pointer in the chain, otherwise it would get deleted later on
Train *to_del = tmp; Train *to_del = tmp;
tmp = tmp->GetNextUnit(); tmp = tmp->GetNextUnit();
// first move the new virtual rail vehicle behind to_del // 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 // 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(); (*this->virtualTrains)[i]->vt = nt->First();
delete to_del; delete to_del;
} else { } else {
@@ -458,7 +495,7 @@ public:
this->vscroll_tr->SetCount(this->engines_right->Length()); 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; uint16 y = r.top;
uint32 eid; uint32 eid;
@@ -466,7 +503,7 @@ public:
Scrollbar *sb; Scrollbar *sb;
const GUIEngineList *el; const GUIEngineList *el;
if ( left ) { if (left) {
sb = this->vscroll_tl; sb = this->vscroll_tl;
el = this->engines_left; el = this->engines_left;
} else { } else {
@@ -474,22 +511,22 @@ public:
el = this->engines_right; el = this->engines_right;
} }
int maximum = min((int)sb->GetCapacity(), (int)el->Length()) + sb->GetPosition(); int maximum = min((int) sb->GetCapacity(), (int) el->Length()) + sb->GetPosition();
for ( int i=sb->GetPosition(); i<maximum; ++i ) {
for (int i = sb->GetPosition(); i < maximum; ++i) {
eid = (*el)[i]; eid = (*el)[i];
/* Draw a grey background rectangle if the current line is the selected one */ /* Draw a grey background rectangle if the current line is the selected one */
if ( (left && this->selected_left == i) || (!left && this->selected_right == i) ) 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]); GfxFillRect(r.left, y, r.right, y + this->line_height, _colour_gradient[COLOUR_GREY][3]);
}
/* Draw a description string of the current engine */ /* Draw a description string of the current engine */
SetDParam(0, eid); 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 */ /* 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; y += this->line_height;
} }
@@ -501,11 +538,11 @@ public:
uint16 max = min(virtualTrains->Length(), this->vscroll_bo->GetCapacity()); 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*/ /* 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;
} }
} }
}; };

View File

@@ -1,27 +1,17 @@
/* $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 header. */
#ifndef TMPL_RPLALL_GUI #ifndef TMPL_RPLALL_GUI
#define TMPL_RPLALL_GUI #define TMPL_RPLALL_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"
void ShowTemplateReplaceAllGui(); void ShowTemplateReplaceAllGui();
#endif #endif

View File

@@ -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 "stdafx.h"
#include "company_func.h" #include "company_func.h"
#include "train.h" #include "train.h"
@@ -24,7 +35,6 @@
#include "table/train_cmd.h" #include "table/train_cmd.h"
#include "tbtr_template_vehicle.h" #include "tbtr_template_vehicle.h"
// since doing stuff with sprites // since doing stuff with sprites
@@ -32,6 +42,8 @@
#include "newgrf_engine.h" #include "newgrf_engine.h"
#include "newgrf_cargo.h" #include "newgrf_cargo.h"
#include "safeguards.h"
TemplatePool _template_pool("TemplatePool"); TemplatePool _template_pool("TemplatePool");
INSTANTIATE_POOL_METHODS(Template) INSTANTIATE_POOL_METHODS(Template)
@@ -74,24 +86,28 @@ void TemplateVehicle::SetFirst(TemplateVehicle *v) { this->first = v; }
TemplateVehicle* TemplateVehicle::GetNextUnit() const TemplateVehicle* TemplateVehicle::GetNextUnit() const
{ {
TemplateVehicle *tv = this->Next(); TemplateVehicle *tv = this->Next();
while ( tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART) ) tv = tv->Next(); while (tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART)) {
if ( tv && HasBit(tv->subtype, GVSF_MULTIHEADED) && !HasBit(tv->subtype, GVSF_ENGINE) ) tv = tv->Next(); tv = tv->Next();
}
if (tv && HasBit(tv->subtype, GVSF_MULTIHEADED) && !HasBit(tv->subtype, GVSF_ENGINE)) tv = tv->Next();
return tv; return tv;
} }
TemplateVehicle* TemplateVehicle::GetPrevUnit() TemplateVehicle* TemplateVehicle::GetPrevUnit()
{ {
TemplateVehicle *tv = this->Prev(); TemplateVehicle *tv = this->Prev();
while ( tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART|GVSF_ENGINE) ) tv = tv->Prev(); while (tv && HasBit(tv->subtype, GVSF_ARTICULATED_PART|GVSF_ENGINE)) {
if ( tv && HasBit(tv->subtype, GVSF_MULTIHEADED|GVSF_ENGINE) ) tv = tv->Prev(); tv = tv->Prev();
}
if (tv && HasBit(tv->subtype, GVSF_MULTIHEADED|GVSF_ENGINE)) tv = tv->Prev();
return tv; return tv;
} }
/** setting */ /** setting */
void appendTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv) void appendTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv)
{ {
if ( !orig ) return; if (!orig) return;
while ( orig->Next() ) orig=orig->Next(); while (orig->Next()) orig = orig->Next();
orig->SetNext(newv); orig->SetNext(newv);
newv->SetPrev(orig); newv->SetPrev(orig);
newv->SetFirst(orig->First()); newv->SetFirst(orig->First());
@@ -99,7 +115,7 @@ void appendTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv)
void insertTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv, TemplateVehicle *insert_after) 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(); TemplateVehicle *insert_before = insert_after->Next();
insert_after->SetNext(newv); insert_after->SetNext(newv);
insert_before->SetPrev(newv); insert_before->SetPrev(newv);
@@ -113,9 +129,12 @@ void insertTemplateVehicle(TemplateVehicle *orig, TemplateVehicle *newv, Templat
*/ */
int TemplateVehicle::Length() const int TemplateVehicle::Length() const
{ {
int l=1; int l = 1;
const TemplateVehicle *tmp=this; const TemplateVehicle *tmp = this;
while ( tmp->Next() ) { tmp=tmp->Next(); l++; } while (tmp->Next()) {
tmp = tmp->Next();
l++;
}
return l; return l;
} }
@@ -123,32 +142,33 @@ TemplateReplacement* GetTemplateReplacementByGroupID(GroupID gid)
{ {
TemplateReplacement *tr; TemplateReplacement *tr;
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->Group() == gid ) if (tr->Group() == gid) {
return tr; return tr;
}
} }
return 0; return NULL;
} }
TemplateReplacement* GetTemplateReplacementByTemplateID(TemplateID tid) { TemplateReplacement* GetTemplateReplacementByTemplateID(TemplateID tid)
{
TemplateReplacement *tr; TemplateReplacement *tr;
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->Template() == tid ) if (tr->Template() == tid) {
return tr; return tr;
}
} }
return 0; return NULL;
} }
bool IssueTemplateReplacement(GroupID gid, TemplateID tid) { bool IssueTemplateReplacement(GroupID gid, TemplateID tid)
{
TemplateReplacement *tr = GetTemplateReplacementByGroupID(gid); TemplateReplacement *tr = GetTemplateReplacementByGroupID(gid);
if ( tr ) { if (tr) {
/* Then set the new TemplateVehicle and return */ /* Then set the new TemplateVehicle and return */
tr->SetTemplate(tid); tr->SetTemplate(tid);
return true; return true;
} } else if (TemplateReplacement::CanAllocateItem()) {
else if ( TemplateReplacement::CanAllocateItem() ) {
tr = new TemplateReplacement(gid, tid); tr = new TemplateReplacement(gid, tid);
return true; return true;
} }
@@ -161,8 +181,9 @@ short TemplateVehicle::NumGroupsUsingTemplate() const
short amount = 0; short amount = 0;
const TemplateReplacement *tr; const TemplateReplacement *tr;
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->sel_template == this->index ) if (tr->sel_template == this->index) {
amount++; amount++;
}
} }
return amount; return amount;
} }
@@ -171,9 +192,11 @@ short TemplateVehicle::CountEnginesInChain()
{ {
TemplateVehicle *tv = this->first; TemplateVehicle *tv = this->first;
short count = 0; short count = 0;
for ( ; tv; tv=tv->GetNextUnit() ) for (; tv != NULL; tv = tv->GetNextUnit()) {
if ( HasBit(tv->subtype, GVSF_ENGINE ) ) if (HasBit(tv->subtype, GVSF_ENGINE)) {
count++; count++;
}
}
return count; return count;
} }
@@ -182,46 +205,10 @@ short deleteIllegalTemplateReplacements(GroupID g_id)
short del_amount = 0; short del_amount = 0;
const TemplateReplacement *tr; const TemplateReplacement *tr;
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->group == g_id ) { if (tr->group == g_id) {
delete tr; delete tr;
del_amount++; del_amount++;
} }
} }
return del_amount; return del_amount;
} }

View File

@@ -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 #ifndef TEMPLATE_VEH_H
#define TEMPLATE_VEH_H #define TEMPLATE_VEH_H
@@ -56,7 +67,7 @@ public:
bool refit_as_template; bool refit_as_template;
// Things derived from a virtual train // 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 Money value; ///< Value of the vehicle
Owner owner; Owner owner;
OwnerByte owner_b; OwnerByte owner_b;
@@ -83,17 +94,20 @@ public:
uint32 image_width; uint32 image_width;
const SpriteGroup *sgroup; 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, RailVehicleInfo*);
TemplateVehicle(EngineID eid) {
next=0; TemplateVehicle(EngineID eid)
previous=0; {
first=this; next = NULL;
engine_type=eid; previous = NULL;
first = this;
engine_type = eid;
this->reuse_depot_vehicles = true; this->reuse_depot_vehicles = true;
this->keep_remaining_vehicles = true; this->keep_remaining_vehicles = true;
this->refit_as_template = true; this->refit_as_template = true;
} }
~TemplateVehicle(); ~TemplateVehicle();
inline TemplateVehicle* Next() const { return this->next; } inline TemplateVehicle* Next() const { return this->next; }
@@ -124,10 +138,10 @@ public:
inline bool IsFreeWagonChain() const { return HasBit(this->subtype, GVSF_FREE_WAGON); } inline bool IsFreeWagonChain() const { return HasBit(this->subtype, GVSF_FREE_WAGON); }
// since CmdBuildTemplateVehicle(...) // since CmdBuildTemplateVehicle(...)
inline void SetFrontEngine() { SetBit(this->subtype, GVSF_FRONT); } inline void SetFrontEngine() { SetBit(this->subtype, GVSF_FRONT); }
inline void SetEngine() { SetBit(this->subtype, GVSF_ENGINE); } inline void SetEngine() { SetBit(this->subtype, GVSF_ENGINE); }
inline void SetArticulatedPart() { SetBit(this->subtype, GVSF_ARTICULATED_PART); } inline void SetArticulatedPart() { SetBit(this->subtype, GVSF_ARTICULATED_PART); }
inline void SetMultiheaded() { SetBit(this->subtype, GVSF_MULTIHEADED); } inline void SetMultiheaded() { SetBit(this->subtype, GVSF_MULTIHEADED); }
inline void SetWagon() { SetBit(this->subtype, GVSF_WAGON); } inline void SetWagon() { SetBit(this->subtype, GVSF_WAGON); }
inline void SetFreeWagon() { SetBit(this->subtype, GVSF_FREE_WAGON); } inline void SetFreeWagon() { SetBit(this->subtype, GVSF_FREE_WAGON); }
@@ -138,7 +152,6 @@ public:
int Length() const; int Length() const;
SpriteID GetImage(Direction) const; SpriteID GetImage(Direction) const;
//int GetDisplayImageWidth(Point *offset = NULL) const;
SpriteID GetSpriteID() const; SpriteID GetSpriteID() const;
short NumGroupsUsingTemplate() const; short NumGroupsUsingTemplate() const;
@@ -173,11 +186,14 @@ struct TemplateReplacement : TemplateReplacementPool::PoolItem<&_template_replac
inline void SetTemplate(TemplateID tid) { this->sel_template = tid; } inline void SetTemplate(TemplateID tid) { this->sel_template = tid; }
inline TemplateID GetTemplateVehicleID() { return sel_template; } inline TemplateID GetTemplateVehicleID() { return sel_template; }
inline const TemplateVehicle* GetTemplateVehicle() {
inline const TemplateVehicle* GetTemplateVehicle()
{
const TemplateVehicle *tv; const TemplateVehicle *tv;
FOR_ALL_TEMPLATES(tv) { FOR_ALL_TEMPLATES(tv) {
if ( tv->index == this->sel_template ) if (tv->index == this->sel_template) {
return tv; return tv;
}
} }
return NULL; return NULL;
} }
@@ -190,4 +206,3 @@ bool IssueTemplateReplacement(GroupID, TemplateID);
short deleteIllegalTemplateReplacements(GroupID); short deleteIllegalTemplateReplacements(GroupID);
#endif /* TEMPLATE_VEH_H */ #endif /* TEMPLATE_VEH_H */

View File

@@ -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 "stdafx.h"
#include "window_gui.h" #include "window_gui.h"
@@ -31,6 +40,8 @@
#include <map> #include <map>
#include <stdio.h> #include <stdio.h>
#include "safeguards.h"
Vehicle *vhead, *vtmp; Vehicle *vhead, *vtmp;
static const uint MAX_ARTICULATED_PARTS = 100; static const uint MAX_ARTICULATED_PARTS = 100;
@@ -77,9 +88,9 @@ void BuildTemplateGuiList(GUITemplateList *list, Scrollbar *vscroll, Owner oid,
const TemplateVehicle *tv; const TemplateVehicle *tv;
FOR_ALL_TEMPLATES(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->Append() = tv;
}
} }
list->RebuildDone(); list->RebuildDone();
@@ -90,21 +101,22 @@ Money CalculateOverallTemplateCost(const TemplateVehicle *tv)
{ {
Money val = 0; Money val = 0;
for (; tv; tv = tv->Next()) for (; tv; tv = tv->Next()) {
val += (Engine::Get(tv->engine_type))->GetCost(); val += (Engine::Get(tv->engine_type))->GetCost();
}
return val; return val;
} }
void DrawTemplate(const TemplateVehicle *tv, int left, int right, int y) void DrawTemplate(const TemplateVehicle *tv, int left, int right, int y)
{ {
if ( !tv ) return; if (!tv) return;
const TemplateVehicle *t = tv; const TemplateVehicle *t = tv;
int offset=left; int offset = left;
while (t) { while (t) {
PaletteID pal = GetEnginePalette(t->engine_type, _current_company); 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; offset += t->image_width;
t = t->Next(); t = t->Next();
@@ -145,17 +157,18 @@ inline void SetupTemplateVehicleFromVirtual(TemplateVehicle *tmp, TemplateVehicl
// create a full TemplateVehicle based train according to a virtual train // create a full TemplateVehicle based train according to a virtual train
TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt) TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt)
{ {
if ( !virt ) if (!virt) return NULL;
return 0;
Train *init_virt = virt; Train *init_virt = virt;
int len = CountVehiclesInChain(virt); int len = CountVehiclesInChain(virt);
if ( !TemplateVehicle::CanAllocateItem(len) ) if (!TemplateVehicle::CanAllocateItem(len)) {
return 0; return NULL;
}
TemplateVehicle *tmp, *prev=0; TemplateVehicle *tmp;
for ( ; virt; virt=virt->Next() ) { TemplateVehicle *prev = NULL;
for (; virt; virt = virt->Next()) {
tmp = new TemplateVehicle(virt->engine_type); tmp = new TemplateVehicle(virt->engine_type);
SetupTemplateVehicleFromVirtual(tmp, prev, virt); SetupTemplateVehicleFromVirtual(tmp, prev, virt);
prev = tmp; 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) // 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) { inline TemplateVehicle* Last(TemplateVehicle *chain)
if ( !chain ) return 0; {
while ( chain->Next() ) chain = chain->Next(); if (!chain) return NULL;
while (chain->Next()) {
chain = chain->Next();
}
return chain; return chain;
} }
inline Train* Last(Train *chain) { inline Train* Last(Train *chain)
if ( !chain ) return 0; {
while ( chain->GetNextUnit() ) chain = chain->GetNextUnit(); if (!chain) return NULL;
while (chain->GetNextUnit()) {
chain = chain->GetNextUnit();
}
return chain; return chain;
} }
// return: pointer to former vehicle // return: pointer to former vehicle
TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle *todel) TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle *todel)
{ {
if ( !todel ) if (!todel) return NULL;
return 0;
TemplateVehicle *cur = todel; TemplateVehicle *cur = todel;
delete todel; delete todel;
return cur; return cur;
@@ -192,7 +210,7 @@ TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle *todel)
CommandCost CmdSellRailWagon(DoCommandFlag, Vehicle*, uint16, uint32); CommandCost CmdSellRailWagon(DoCommandFlag, Vehicle*, uint16, uint32);
Train* DeleteVirtualTrain(Train *chain, Train *to_del) { Train* DeleteVirtualTrain(Train *chain, Train *to_del) {
if ( chain != to_del ) { if (chain != to_del) {
CmdSellRailWagon(DC_EXEC, to_del, 0, 0); CmdSellRailWagon(DC_EXEC, to_del, 0, 0);
return chain; return chain;
} }
@@ -208,17 +226,20 @@ TemplateVehicle* GetTemplateVehicleByGroupID(GroupID gid) {
TemplateReplacement *tr; TemplateReplacement *tr;
// first try to find a templatereplacement issued for the given groupid // first try to find a templatereplacement issued for the given groupid
FOR_ALL_TEMPLATE_REPLACEMENTS(tr) { FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->Group() == gid ) if (tr->Group() == gid) {
return TemplateVehicle::GetIfValid(tr->Template()); // there can be only one return TemplateVehicle::GetIfValid(tr->Template()); // there can be only one
}
} }
// if that didn't work, try to find a templatereplacement for ALL_GROUP // 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) { FOR_ALL_TEMPLATE_REPLACEMENTS(tr) {
if ( tr->Group() == ALL_GROUP ) if (tr->Group() == ALL_GROUP) {
return TemplateVehicle::GetIfValid(tr->Template()); return TemplateVehicle::GetIfValid(tr->Template());
}
} }
}
// if all failed, just return null // 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) bool TemplateVehicleContainsEngineOfRailtype(const TemplateVehicle *tv, RailType type)
{ {
/* For standard rail engines, allow only those */ /* For standard rail engines, allow only those */
if ( type == RAILTYPE_BEGIN || type == RAILTYPE_RAIL ) { if (type == RAILTYPE_BEGIN || type == RAILTYPE_RAIL) {
while ( tv ) { while (tv) {
if ( tv->railtype != type ) if (tv->railtype != type) {
return false; return false;
tv = tv->GetNextUnit(); }
tv = tv->GetNextUnit();
} }
return true; return true;
} }
/* For electrified rail engines, standard wagons or engines are allowed to be included */ /* For electrified rail engines, standard wagons or engines are allowed to be included */
while ( tv ) { while (tv) {
if ( tv->railtype == type ) if (tv->railtype == type) {
return true; return true;
}
tv = tv->GetNextUnit(); tv = tv->GetNextUnit();
} }
return false; return false;
} }
//helper //helper
bool ChainContainsVehicle(Train *chain, Train *mem) { bool ChainContainsVehicle(Train *chain, Train *mem)
for (; chain; chain=chain->Next()) {
if ( chain == mem ) for (; chain; chain = chain->Next()) {
if (chain == mem) {
return true; return true;
}
}
return false; return false;
} }
@@ -257,27 +283,30 @@ Train* ChainContainsEngine(EngineID eid, Train *chain) {
for (; chain; chain=chain->GetNextUnit()) for (; chain; chain=chain->GetNextUnit())
if (chain->engine_type == eid) if (chain->engine_type == eid)
return chain; return chain;
return 0; return NULL;
} }
// has O(n^2) // 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; Train *t;
FOR_ALL_TRAINS(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' // 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 '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 // 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 // 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->IsPrimaryVehicle() && t->IsStoppedInDepot()) || t->IsFreeWagon())
&& t->engine_type==eid && t->engine_type == eid
&& (not_in==0 || ChainContainsVehicle(not_in, t)==0)) && (not_in == NULL || ChainContainsVehicle(not_in, t) == false)) {
return t; 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); DoCommand(to->tile, from->group_id, to->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP);
to->cargo_type = from->cargo_type; to->cargo_type = from->cargo_type;
to->cargo_subtype = from->cargo_subtype; to->cargo_subtype = from->cargo_subtype;
@@ -286,117 +315,133 @@ void CopyStatus(Train *from, Train *to) {
char *tmp = to->name; char *tmp = to->name;
to->name = from->name; to->name = from->name;
from->name = tmp; 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(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 | 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, FreeUnitIDGenerator(VEH_TRAIN, t->owner).NextID(), DC_EXEC, CMD_SET_VEHICLE_UNIT_NUMBER);
DoCommand(0, t->index, 0, DC_EXEC, CMD_RENAME_VEHICLE, NULL); DoCommand(0, t->index, 0, DC_EXEC, CMD_RENAME_VEHICLE, NULL);
} }
bool TrainMatchesTemplate(const Train *t, TemplateVehicle *tv) { bool TrainMatchesTemplate(const Train *t, TemplateVehicle *tv) {
while ( t && tv ) { while (t && tv) {
if ( t->engine_type != tv->engine_type ) if (t->engine_type != tv->engine_type) {
return false; return false;
}
t = t->GetNextUnit(); t = t->GetNextUnit();
tv = tv->GetNextUnit(); tv = tv->GetNextUnit();
} }
if ( (t && !tv) || (!t && tv) ) if ((t && !tv) || (!t && tv)) {
return false; return false;
}
return true; return true;
} }
bool TrainMatchesTemplateRefit(const Train *t, TemplateVehicle *tv) bool TrainMatchesTemplateRefit(const Train *t, TemplateVehicle *tv)
{ {
if ( !tv->refit_as_template ) if (!tv->refit_as_template) {
return true; return true;
}
while ( t && tv ) { while (t && tv) {
if ( t->cargo_type != tv->cargo_type || t->cargo_subtype != tv->cargo_subtype ) if (t->cargo_type != tv->cargo_type || t->cargo_subtype != tv->cargo_subtype) {
return false; return false;
}
t = t->GetNextUnit(); t = t->GetNextUnit();
tv = tv->GetNextUnit(); tv = tv->GetNextUnit();
} }
return true; return true;
} }
void BreakUpRemainders(Train *t) {
while ( t ) { void BreakUpRemainders(Train *t)
{
while (t) {
Train *move; Train *move;
if ( HasBit(t->subtype, GVSF_ENGINE) ) { if (HasBit(t->subtype, GVSF_ENGINE)) {
move = t; move = t;
t = t->Next(); t = t->Next();
DoCommand(move->tile, move->index, INVALID_VEHICLE, DC_EXEC, CMD_MOVE_RAIL_VEHICLE); DoCommand(move->tile, move->index, INVALID_VEHICLE, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
NeutralizeStatus( move ); NeutralizeStatus(move);
} } else {
else
t = t->Next(); t = t->Next();
}
} }
} }
short CountEnginesInChain(Train *t) short CountEnginesInChain(Train *t)
{ {
short count = 0; short count = 0;
for ( ; t; t=t->GetNextUnit() ) for (; t != NULL; t = t->GetNextUnit()) {
if ( HasBit(t->subtype, GVSF_ENGINE) ) if (HasBit(t->subtype, GVSF_ENGINE)) {
count++; count++;
}
}
return count; return count;
} }
int countOccurrencesInTrain(Train *t, EngineID eid) { int countOccurrencesInTrain(Train *t, EngineID eid)
{
int count = 0; int count = 0;
Train *tmp = t; Train *tmp = t;
for ( ; tmp; tmp=tmp->GetNextUnit() ) for (; tmp != NULL; tmp = tmp->GetNextUnit()) {
if ( tmp->engine_type == eid ) if (tmp->engine_type == eid) {
count++; count++;
}
}
return count; return count;
} }
int countOccurrencesInTemplateVehicle(TemplateVehicle *contain, EngineID eid) { int countOccurrencesInTemplateVehicle(TemplateVehicle *contain, EngineID eid)
{
int count = 0; int count = 0;
for ( ; contain; contain=contain->GetNextUnit() ) for (; contain; contain=contain->GetNextUnit()) {
if ( contain->engine_type == eid ) if (contain->engine_type == eid) {
count++; count++;
}
}
return 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; int count = 0;
Vehicle *v; Vehicle *v;
FOR_ALL_VEHICLES(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' // 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 'not_in' is NULL, no check is needed
if ( v->tile==tile && v->IsStoppedInDepot() && v->engine_type==eid && if (v->tile == tile && v->IsStoppedInDepot() && v->engine_type == eid &&
(not_in==0 || ChainContainsVehicle(not_in, (Train*)v)==0)) (not_in == 0 || ChainContainsVehicle(not_in, (Train*)v) == false)) {
count++; count++;
}
} }
return count; return count;
} }
// basically does the same steps as CmdTemplateReplaceVehicle but without actually moving things around // 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; TileIndex tile = incoming->tile;
TemplateVehicle *tv = GetTemplateVehicleByGroupID(incoming->group_id); TemplateVehicle *tv = GetTemplateVehicleByGroupID(incoming->group_id);
CommandCost estimate(EXPENSES_NEW_VEHICLES); CommandCost estimate(EXPENSES_NEW_VEHICLES);
// count for each different eid in the incoming train // count for each different eid in the incoming train
std::map<EngineID, short> unique_eids; 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]++; unique_eids[tmp->engine_type]++;
}
std::map<EngineID, short>::iterator it = unique_eids.begin(); 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 -= countOccurrencesInTrain(incoming, it->first);
it->second -= countOccurrencesInDepot(incoming->tile, it->first, incoming); 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 // get overall buying cost
for ( it=unique_eids.begin(); it!=unique_eids.end(); it++ ) { for (it = unique_eids.begin(); it != unique_eids.end(); it++) {
for ( int j=0; j<it->second; j++ ) { for (int j = 0; j < it->second; j++) {
estimate.AddCost(DoCommand(tile, it->first, 0, DC_NONE, CMD_BUILD_VEHICLE)); 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 // 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_type = from->cargo_type;
to->cargo_subtype = from->cargo_subtype; to->cargo_subtype = from->cargo_subtype;
} }
@@ -413,19 +459,20 @@ void CopyWagonStatus(TemplateVehicle *from, Train *to) {
int NumTrainsNeedTemplateReplacement(GroupID g_id, TemplateVehicle *tv) int NumTrainsNeedTemplateReplacement(GroupID g_id, TemplateVehicle *tv)
{ {
int count = 0; int count = 0;
if ( !tv ) return count; if (!tv) return count;
const Train *t; const Train *t;
FOR_ALL_TRAINS(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++; count++;
}
} }
return count; return count;
} }
// refit each vehicle in t as is in tv, assume t and tv contain the same types of vehicles // 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) void CmdRefitTrainFromTemplate(Train *t, TemplateVehicle *tv, DoCommandFlag flags)
{ {
while ( t && tv ) { while (t && tv) {
// refit t as tv // refit t as tv
uint32 cb = GetCmdRefitVeh(t); uint32 cb = GetCmdRefitVeh(t);
@@ -445,8 +492,9 @@ CommandCost TestBuyAllTemplateVehiclesInChain(TemplateVehicle *tv, TileIndex til
{ {
CommandCost cost(EXPENSES_NEW_VEHICLES); CommandCost cost(EXPENSES_NEW_VEHICLES);
for ( ; tv; tv=tv->GetNextUnit() ) for (; tv; tv = tv->GetNextUnit()) {
cost.AddCost( DoCommand(tile, tv->engine_type, 0, DC_NONE, CMD_BUILD_VEHICLE) ); cost.AddCost(DoCommand(tile, tv->engine_type, 0, DC_NONE, CMD_BUILD_VEHICLE));
}
return cost; 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. /** 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) * 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. * to store the cargo from the given single vehicle.
* @param old_veh: ptr to the single vehicle, which's cargo shall be moved * @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 * @param new_head: ptr to the head of the chain, which shall obtain old_veh's cargo
* @return: amount of moved cargo TODO * @return: amount of moved cargo, TODO
*/ */
void TransferCargoForTrain(Train *old_veh, Train *new_head) 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) // how much cargo has to be moved (if possible)
uint remainingAmount = old_veh->cargo.TotalCount(); 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 // 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()) for (Train *tmp = new_head; tmp != NULL && remainingAmount > 0; tmp = tmp->GetNextUnit()) {
{ if (tmp->cargo_type == _cargo_type && tmp->cargo_subtype == _cargo_subtype) {
if (tmp->cargo_type == _cargo_type && tmp->cargo_subtype == _cargo_subtype)
{
// calculate the free space for new cargo on the current vehicle // calculate the free space for new cargo on the current vehicle
uint curCap = tmp->cargo_cap - tmp->cargo.TotalCount(); uint curCap = tmp->cargo_cap - tmp->cargo.TotalCount();
uint moveAmount = min(remainingAmount, curCap); uint moveAmount = min(remainingAmount, curCap);
// move (parts of) the old vehicle's cargo onto the current vehicle of the new chain // 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); old_veh->cargo.Shift(moveAmount, &tmp->cargo);
remainingAmount -= moveAmount; 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 */ /* Update train weight etc., the old vehicle will be sold anyway */
new_head->ConsistChanged(CCF_LOADUNLOAD); new_head->ConsistChanged(CCF_LOADUNLOAD);
} }

View File

@@ -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 #ifndef TEMPLATE_VEHICLE_FUNC_H
#define TEMPLATE_VEHICLE_FUNC_H #define TEMPLATE_VEHICLE_FUNC_H
@@ -7,9 +17,6 @@
#include "tbtr_template_vehicle.h" #include "tbtr_template_vehicle.h"
//void DrawTemplateVehicle(TemplateVehicle*, int, const Rect&);
Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv); Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv);
void DrawTemplateVehicle(const TemplateVehicle*, int, int, int, VehicleID, int, VehicleID); void DrawTemplateVehicle(const TemplateVehicle*, int, int, int, VehicleID, int, VehicleID);
@@ -32,8 +39,6 @@ void setupVirtTrain(const TemplateVehicle*, Train*);
TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt); TemplateVehicle* TemplateVehicleFromVirtualTrain(Train *virt);
//Train* VirtualTrainFromTemplateVehicle(TemplateVehicle*);
inline TemplateVehicle* Last(TemplateVehicle*); inline TemplateVehicle* Last(TemplateVehicle*);
TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle*); TemplateVehicle *DeleteTemplateVehicle(TemplateVehicle*);

View File

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

View File

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

View File

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

View File

@@ -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_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_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_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. */ /** Cached often queried values common to all vehicles. */
@@ -517,7 +517,7 @@ public:
Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); } Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
void SetNext(Vehicle *next); 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. * Get the next vehicle of this vehicle.

View File

@@ -426,8 +426,8 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles,
* @param p1 vehicle ID to refit * @param p1 vehicle ID to refit
* @param p2 various bitstuffed elements * @param p2 various bitstuffed elements
* - p2 = (bit 0-4) - New cargo type to refit to. * - 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 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 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 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. * - 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; 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. */ /* Allow auto-refitting only during loading and normal refitting only in a depot. */
if ( ! is_virtual_train ) { 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 (!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 (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. 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); InvalidateWindowClassesData(GetWindowClassForVehicleType(v->type), 0);
} }
/* virtual vehicles get their cargo changed by the TemplateCreateWindow, so set this dirty instead of a depot window */ /* 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); if (HasBit(v->subtype, GVSF_VIRTUAL)) {
else SetWindowDirty(WC_VEHICLE_DEPOT, front->tile); SetWindowClassesDirty(WC_CREATE_TEMPLATE);
} else {
SetWindowDirty(WC_VEHICLE_DEPOT, front->tile);
}
} else { } else {
/* Always invalidate the cache; querycost might have filled it. */ /* Always invalidate the cache; querycost might have filled it. */
v->InvalidateNewGRFCacheOfChain(); v->InvalidateNewGRFCacheOfChain();
@@ -825,8 +830,9 @@ CommandCost CmdToggleReuseDepotVehicles(TileIndex tile, DoCommandFlag flags, uin
// Identify template to toggle // Identify template to toggle
TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1); TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1);
if (template_vehicle == NULL) if (template_vehicle == NULL) {
return CMD_ERROR; return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0; bool should_execute = (flags & DC_EXEC) != 0;
@@ -853,8 +859,9 @@ CommandCost CmdToggleKeepRemainingVehicles(TileIndex tile, DoCommandFlag flags,
// Identify template to toggle // Identify template to toggle
TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1); TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1);
if (template_vehicle == NULL) if (template_vehicle == NULL) {
return CMD_ERROR; return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0; bool should_execute = (flags & DC_EXEC) != 0;
@@ -881,8 +888,9 @@ CommandCost CmdToggleRefitAsTemplate(TileIndex tile, DoCommandFlag flags, uint32
// Identify template to toggle // Identify template to toggle
TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1); TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1);
if (template_vehicle == NULL) if (template_vehicle == NULL) {
return CMD_ERROR; return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0; bool should_execute = (flags & DC_EXEC) != 0;
@@ -910,16 +918,18 @@ CommandCost CmdVirtualTrainFromTemplateVehicle(TileIndex tile, DoCommandFlag fla
TemplateVehicle* tv = TemplateVehicle::GetIfValid(template_vehicle_id); TemplateVehicle* tv = TemplateVehicle::GetIfValid(template_vehicle_id);
if (tv == NULL) if (tv == NULL) {
return CMD_ERROR; return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0; bool should_execute = (flags & DC_EXEC) != 0;
if (should_execute) { if (should_execute) {
Train* train = VirtualTrainFromTemplateVehicle(tv); Train* train = VirtualTrainFromTemplateVehicle(tv);
if (train == nullptr) if (train == NULL) {
return CMD_ERROR; return CMD_ERROR;
}
} }
return CommandCost(); return CommandCost();
@@ -931,16 +941,16 @@ Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv)
Train *tmp, *head, *tail; Train *tmp, *head, *tail;
head = CmdBuildVirtualRailVehicle(tv->engine_type); head = CmdBuildVirtualRailVehicle(tv->engine_type);
if ( !head ) return nullptr; if (!head) return NULL;
tail = head; tail = head;
tv = tv->GetNextUnit(); tv = tv->GetNextUnit();
while ( tv ) { while (tv) {
tmp = CmdBuildVirtualRailVehicle(tv->engine_type); tmp = CmdBuildVirtualRailVehicle(tv->engine_type);
if ( tmp ) { if (tmp) {
tmp->cargo_type = tv->cargo_type; tmp->cargo_type = tv->cargo_type;
tmp->cargo_subtype = tv->cargo_subtype; 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; tail = tmp;
} }
tv = tv->GetNextUnit(); tv = tv->GetNextUnit();
@@ -965,8 +975,9 @@ CommandCost CmdVirtualTrainFromTrain(TileIndex tile, DoCommandFlag flags, uint32
VehicleID vehicle_id = p1; VehicleID vehicle_id = p1;
Vehicle* vehicle = Vehicle::GetIfValid(vehicle_id); Vehicle* vehicle = Vehicle::GetIfValid(vehicle_id);
if (vehicle == nullptr || vehicle->type != VEH_TRAIN) if (vehicle == NULL || vehicle->type != VEH_TRAIN) {
return CMD_ERROR; return CMD_ERROR;
}
Train* train = Train::From(vehicle); Train* train = Train::From(vehicle);
@@ -977,16 +988,16 @@ CommandCost CmdVirtualTrainFromTrain(TileIndex tile, DoCommandFlag flags, uint32
Train *tmp, *head, *tail; Train *tmp, *head, *tail;
head = CmdBuildVirtualRailVehicle(train->engine_type); head = CmdBuildVirtualRailVehicle(train->engine_type);
if ( !head ) return CMD_ERROR; if (!head) return CMD_ERROR;
tail = head; tail = head;
train = train->GetNextUnit(); train = train->GetNextUnit();
while ( train ) { while (train) {
tmp = CmdBuildVirtualRailVehicle(train->engine_type); tmp = CmdBuildVirtualRailVehicle(train->engine_type);
if ( tmp ) { if (tmp) {
tmp->cargo_type = train->cargo_type; tmp->cargo_type = train->cargo_type;
tmp->cargo_subtype = train->cargo_subtype; 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; tail = tmp;
} }
train = train->GetNextUnit(); train = train->GetNextUnit();
@@ -1013,8 +1024,9 @@ CommandCost CmdDeleteVirtualTrain(TileIndex tile, DoCommandFlag flags, uint32 p1
Vehicle* vehicle = Vehicle::GetIfValid(vehicle_id); Vehicle* vehicle = Vehicle::GetIfValid(vehicle_id);
if (vehicle == nullptr || vehicle->type != VEH_TRAIN) if (vehicle == NULL || vehicle->type != VEH_TRAIN) {
return CMD_ERROR; return CMD_ERROR;
}
Train* train = Train::From(vehicle); Train* train = Train::From(vehicle);
@@ -1044,8 +1056,9 @@ CommandCost CmdReplaceTemplateVehicle(TileIndex tile, DoCommandFlag flags, uint3
TemplateVehicle* template_vehicle = TemplateVehicle::GetIfValid(template_vehicle_id); TemplateVehicle* template_vehicle = TemplateVehicle::GetIfValid(template_vehicle_id);
Vehicle* vehicle = Vehicle::GetIfValid(virtual_train_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; return CMD_ERROR;
}
Train* train = Train::From(vehicle); Train* train = Train::From(vehicle);
@@ -1054,16 +1067,17 @@ CommandCost CmdReplaceTemplateVehicle(TileIndex tile, DoCommandFlag flags, uint3
if (should_execute) { if (should_execute) {
VehicleID old_ID = INVALID_VEHICLE; VehicleID old_ID = INVALID_VEHICLE;
if (template_vehicle != nullptr) { if (template_vehicle != NULL) {
old_ID = template_vehicle->index; old_ID = template_vehicle->index;
delete template_vehicle; delete template_vehicle;
template_vehicle = nullptr; template_vehicle = NULL;
} }
template_vehicle = TemplateVehicleFromVirtualTrain(train); template_vehicle = TemplateVehicleFromVirtualTrain(train);
if (template_vehicle == nullptr) if (template_vehicle == NULL) {
return CMD_ERROR; return CMD_ERROR;
}
// Make sure our replacements still point to the correct thing. // Make sure our replacements still point to the correct thing.
if (old_ID != template_vehicle->index) { if (old_ID != template_vehicle->index) {
@@ -1098,20 +1112,21 @@ CommandCost CmdTemplateVehicleFromTrain(TileIndex tile, DoCommandFlag flags, uin
Vehicle *t = Vehicle::GetIfValid(p1); Vehicle *t = Vehicle::GetIfValid(p1);
Train *clicked = Train::GetIfValid(t->index); Train *clicked = Train::GetIfValid(t->index);
if (!clicked) if (!clicked) return CMD_ERROR;
return CMD_ERROR;
Train *init_clicked = clicked; Train *init_clicked = clicked;
int len = CountVehiclesInChain(clicked); int len = CountVehiclesInChain(clicked);
if (!TemplateVehicle::CanAllocateItem(len)) if (!TemplateVehicle::CanAllocateItem(len)) {
return CMD_ERROR; return CMD_ERROR;
}
bool should_execute = (flags & DC_EXEC) != 0; bool should_execute = (flags & DC_EXEC) != 0;
if (should_execute) { if (should_execute) {
TemplateVehicle *tmp, *prev=0; TemplateVehicle *tmp;
for (; clicked; clicked=clicked->Next()) { TemplateVehicle *prev = NULL;
for (; clicked != NULL; clicked = clicked->Next()) {
tmp = new TemplateVehicle(clicked->engine_type); tmp = new TemplateVehicle(clicked->engine_type);
SetupTemplateVehicleFromVirtual(tmp, prev, clicked); SetupTemplateVehicleFromVirtual(tmp, prev, clicked);
prev = tmp; 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)); tmp->First()->SetRealLength(CeilDiv(init_clicked->gcache.cached_total_length * 10, TILE_SIZE));
tv = tmp->First(); tv = tmp->First();
if (!tv) return CMD_ERROR; if (!tv) return CMD_ERROR;
InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0); InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0);
} }
@@ -1142,8 +1157,7 @@ CommandCost CmdDeleteTemplateVehicle(TileIndex tile, DoCommandFlag flags, uint32
// Identify template to delete // Identify template to delete
TemplateVehicle *del = TemplateVehicle::GetIfValid(p1); TemplateVehicle *del = TemplateVehicle::GetIfValid(p1);
if (del == NULL) if (del == NULL) return CMD_ERROR;
return CMD_ERROR;
bool should_execute = (flags & DC_EXEC) != 0; bool should_execute = (flags & DC_EXEC) != 0;
@@ -1181,8 +1195,9 @@ CommandCost CmdIssueTemplateReplacement(TileIndex tile, DoCommandFlag flags, uin
if (should_execute) { if (should_execute) {
bool succeeded = IssueTemplateReplacement(group_id, template_id); bool succeeded = IssueTemplateReplacement(group_id, template_id);
if (!succeeded) if (!succeeded) {
return CMD_ERROR; return CMD_ERROR;
}
InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0); InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0);
} }
@@ -1207,8 +1222,9 @@ CommandCost CmdDeleteTemplateReplacement(TileIndex tile, DoCommandFlag flags, ui
if (should_execute) { if (should_execute) {
TemplateReplacement* tr = GetTemplateReplacementByGroupID(group_id); TemplateReplacement* tr = GetTemplateReplacementByGroupID(group_id);
if (tr != NULL) if (tr != NULL) {
delete tr; delete tr;
}
InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0); InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0);
} }

View File

@@ -42,6 +42,7 @@
#include "safeguards.h" #include "safeguards.h"
Sorting _sorting; Sorting _sorting;
static GUIVehicleList::SortFunction VehicleNumberSorter; static GUIVehicleList::SortFunction VehicleNumberSorter;
@@ -952,7 +953,10 @@ struct RefitWindow : public Window {
if (this->order == INVALID_VEH_ORDER_ID) { if (this->order == INVALID_VEH_ORDER_ID) {
bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX; 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 { } 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; 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;
} }

View File

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

View File

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