Allow cloning trains directly from the template train list

See: #312
pull/306/head
Jonathan G Rennison 3 years ago
parent a4c73e71c3
commit a026d82c6b

@ -215,6 +215,7 @@ CommandProc CmdIssueTemplateReplacement;
CommandProc CmdDeleteTemplateReplacement;
CommandProc CmdCloneVehicle;
CommandProc CmdCloneVehicleFromTemplate;
CommandProc CmdStartStopVehicle;
CommandProc CmdMassStartStopVehicle;
CommandProc CmdAutoreplaceVehicle;
@ -450,6 +451,7 @@ static const Command _command_proc_table[] = {
DEF_CMD(CmdDeleteTemplateReplacement, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_DELETE_TEMPLATE_REPLACEMENT
DEF_CMD(CmdCloneVehicle, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION ), // CMD_CLONE_VEHICLE; NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost
DEF_CMD(CmdCloneVehicleFromTemplate, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION ), // CMD_CLONE_VEHICLE_FROM_TEMPLATE; NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost
DEF_CMD(CmdStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_START_STOP_VEHICLE
DEF_CMD(CmdMassStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_MASS_START_STOP
DEF_CMD(CmdAutoreplaceVehicle, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_AUTOREPLACE_VEHICLE

@ -396,6 +396,7 @@ enum Commands {
CMD_DELETE_TEMPLATE_REPLACEMENT, ///< delete a template replacement from a vehicle group
CMD_CLONE_VEHICLE, ///< clone a vehicle
CMD_CLONE_VEHICLE_FROM_TEMPLATE, ///< clone a vehicle from a template
CMD_START_STOP_VEHICLE, ///< start or stop a vehicle
CMD_MASS_START_STOP, ///< start/stop all vehicles (in a depot)
CMD_AUTOREPLACE_VEHICLE, ///< replace/renew a vehicle while it is in a depot

@ -28,6 +28,7 @@
#include "infrastructure_func.h"
#include "order_backup.h"
#include "zoom_func.h"
#include "tbtr_template_vehicle.h"
#include "widgets/depot_widget.h"
@ -917,6 +918,21 @@ struct DepotWindow : Window {
return true;
}
/**
* Clones a vehicle
* @param v the original vehicle to clone
* @return Always true.
*/
bool OnTemplateVehicleSelect(const TemplateVehicle *v) override
{
/* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to changs things on new vehicle) */
if (DoCommandP(this->window_number, v->index, 0, CMD_CLONE_VEHICLE_FROM_TEMPLATE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN), CcCloneVehicle)) {
ResetObjectToPlace();
}
return true;
}
void OnPlaceObjectAbort() override
{
/* abort clone */

@ -447,6 +447,8 @@ public:
if (newindex == this->selected_template_index || newindex >= templates.size()) {
this->selected_template_index = -1;
} else if (newindex < templates.size()) {
const TemplateVehicle *tmp = this->templates[newindex];
if (tmp != nullptr && TemplateVehicleClicked(tmp)) return;
this->selected_template_index = newindex;
}
this->UpdateButtonState();
@ -840,3 +842,19 @@ void ShowTemplateReplaceWindow()
new TemplateReplaceWindow(&_replace_rail_vehicle_desc);
}
}
/**
* Dispatch a "template vehicle selected" event if any window waits for it.
* @param v selected vehicle;
* @return did any window accept vehicle selection?
*/
bool TemplateVehicleClicked(const TemplateVehicle *v)
{
assert(v != nullptr);
if (!(_thd.place_mode & HT_VEHICLE)) return false;
v = v->First();
if (!v->IsPrimaryVehicle()) return false;
return _thd.GetCallbackWnd()->OnTemplateVehicleSelect(v);
}

@ -23,4 +23,6 @@ typedef GUIList<const Group*> GUIGroupList;
void ShowTemplateReplaceWindow();
bool TemplateVehicleClicked(const TemplateVehicle *v);
#endif

@ -33,6 +33,7 @@
#include "core/random_func.hpp"
#include "tbtr_template_vehicle.h"
#include "tbtr_template_vehicle_func.h"
#include "scope.h"
#include <sstream>
#include <iomanip>
#include <cctype>
@ -1537,6 +1538,47 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
return total_cost;
}
/**
* Clone a vehicle from a template.
* @param tile tile of the depot where the cloned vehicle is build
* @param flags type of operation
* @param p1 the original template vehicle's index
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdCloneVehicleFromTemplate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
TemplateVehicle* tv = TemplateVehicle::GetIfValid(p1);
if (tv == nullptr) {
return CMD_ERROR;
}
CommandCost ret = CheckOwnership(tv->owner);
if (ret.Failed()) return ret;
/* Vehicle construction needs random bits, so we have to save the random
* seeds to prevent desyncs. */
SavedRandomSeeds saved_seeds;
SaveRandomSeeds(&saved_seeds);
auto guard = scope_guard([&]() {
if (!(flags & DC_EXEC)) RestoreRandomSeeds(saved_seeds);
});
ret = DoCommand(0, tv->index, 0, DC_EXEC, CMD_VIRTUAL_TRAIN_FROM_TEMPLATE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN));
if (ret.Failed()) return ret;
Train* virt = Train::From(Vehicle::Get(_new_vehicle_id));
ret = DoCommand(tile, _new_vehicle_id, 0, flags, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN));
delete virt;
return ret;
}
/**
* Send all vehicles of type to depots
* @param flags the flags used for DoCommand()

@ -823,6 +823,13 @@ public:
*/
virtual bool OnVehicleSelect(const struct Vehicle *v) { return false; }
/**
* The user clicked on a template vehicle while HT_VEHICLE has been set.
* @param v clicked vehicle. It is guaranteed to be v->IsPrimaryVehicle() == true
* @return True if the click is handled, false if it is ignored.
*/
virtual bool OnTemplateVehicleSelect(const struct TemplateVehicle *v) { return false; }
/**
* The user cancelled a tile highlight mode that has been set.
*/

Loading…
Cancel
Save