summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2009-10-28 21:09:37 +0000
committerfrosch <frosch@openttd.org>2009-10-28 21:09:37 +0000
commit00aca63b48e18e4bf3644964457c7d81c1a10573 (patch)
tree0588c61cbfcbb82e0a194ec742f629c2af9aef0b
parentd01f5e9e7e78ceb22e36d5378f74b6ef4a842756 (diff)
downloadopenttd-00aca63b48e18e4bf3644964457c7d81c1a10573.tar.xz
(svn r17899) -Codechange: Deduplicate code for refitting vehicles.
-rw-r--r--src/aircraft_cmd.cpp31
-rw-r--r--src/roadveh_cmd.cpp49
-rw-r--r--src/ship_cmd.cpp27
-rw-r--r--src/train_cmd.cpp49
-rw-r--r--src/vehicle.cpp46
-rw-r--r--src/vehicle_cmd.cpp87
-rw-r--r--src/vehicle_func.h3
7 files changed, 106 insertions, 186 deletions
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
index c5a422c8e..65c3f6ff1 100644
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -500,40 +500,17 @@ CommandCost CmdRefitAircraft(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* Check cargo */
CargoID new_cid = GB(p2, 0, 8);
- if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
+ if (new_cid >= NUM_CARGO) return CMD_ERROR;
- const Engine *e = Engine::Get(v->engine_type);
- v->InvalidateNewGRFCacheOfChain();
-
- /* Back up the existing cargo type */
- CargoID temp_cid = v->cargo_type;
- byte temp_subtype = v->cargo_subtype;
- v->cargo_type = new_cid;
- v->cargo_subtype = new_subtype;
-
- uint pass = GetVehicleCapacity(v);
-
- /* Restore the cargo type */
- v->cargo_type = temp_cid;
- v->cargo_subtype = temp_subtype;
-
- _returned_refit_capacity = pass;
-
- CommandCost cost;
- if (new_cid != v->cargo_type) {
- cost = GetRefitCost(v->engine_type);
- }
+ CommandCost cost = RefitVehicle(v, true, new_cid, new_subtype, flags);
if (flags & DC_EXEC) {
- v->cargo_cap = pass;
-
+ const Engine *e = Engine::Get(v->engine_type);
Vehicle *u = v->Next();
uint mail = IsCargoInClass(new_cid, CC_PASSENGERS) ? e->u.air.mail_capacity : 0;
u->cargo_cap = mail;
- v->cargo.Truncate(v->cargo_type == new_cid ? pass : 0);
u->cargo.Truncate(v->cargo_type == new_cid ? mail : 0);
- v->cargo_type = new_cid;
- v->cargo_subtype = new_subtype;
+
v->colourmap = PAL_NONE; // invalidate vehicle colour map
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp
index bbdbb874b..f482c0ebb 100644
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -2003,11 +2003,9 @@ Trackdir RoadVehicle::GetVehicleTrackdir() const
*/
CommandCost CmdRefitRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
- CommandCost cost(EXPENSES_ROADVEH_RUN);
CargoID new_cid = GB(p2, 0, 8);
byte new_subtype = GB(p2, 8, 8);
bool only_this = HasBit(p2, 16);
- uint total_capacity = 0;
RoadVehicle *v = RoadVehicle::GetIfValid(p1);
@@ -2017,52 +2015,17 @@ CommandCost CmdRefitRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
if (new_cid >= NUM_CARGO) return CMD_ERROR;
- v->InvalidateNewGRFCacheOfChain();
- for (; v != NULL; v = (only_this ? NULL : v->Next())) {
- /* XXX: We refit all the attached wagons en-masse if they can be
- * refitted. This is how TTDPatch does it. TODO: Have some nice
- * [Refit] button near each wagon. */
- if (!CanRefitTo(v->engine_type, new_cid)) continue;
-
- const Engine *e = Engine::Get(v->engine_type);
- if (!e->CanCarryCargo()) continue;
-
- /* Back up the cargo type */
- CargoID temp_cid = v->cargo_type;
- byte temp_subtype = v->cargo_subtype;
- v->cargo_type = new_cid;
- v->cargo_subtype = new_subtype;
-
- uint capacity = GetVehicleCapacity(v);
-
- /* Restore the original cargo type */
- v->cargo_type = temp_cid;
- v->cargo_subtype = temp_subtype;
-
- total_capacity += capacity;
-
- if (new_cid != v->cargo_type) {
- cost.AddCost(GetRefitCost(v->engine_type));
- }
-
- if (flags & DC_EXEC) {
- v->cargo_cap = capacity;
- v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
- v->cargo_type = new_cid;
- v->cargo_subtype = new_subtype;
- SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
- SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
- InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
- }
- }
+ CommandCost cost = RefitVehicle(v, only_this, new_cid, new_subtype, flags);
if (flags & DC_EXEC) {
- RoadVehUpdateCache(RoadVehicle::Get(p1)->First());
+ RoadVehicle *front = v->First();
+ RoadVehUpdateCache(front);
+ SetWindowDirty(WC_VEHICLE_DETAILS, front->index);
+ SetWindowDirty(WC_VEHICLE_DEPOT, front->tile);
+ InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
} else {
v->InvalidateNewGRFCacheOfChain(); // always invalidate; querycost might have filled it
}
- _returned_refit_capacity = total_capacity;
-
return cost;
}
diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp
index 7c64e4ee5..c56f2dcf3 100644
--- a/src/ship_cmd.cpp
+++ b/src/ship_cmd.cpp
@@ -909,7 +909,6 @@ CommandCost CmdSendShipToDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u
*/
CommandCost CmdRefitShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
- CommandCost cost(EXPENSES_SHIP_RUN);
CargoID new_cid = GB(p2, 0, 8); // gets the cargo number
byte new_subtype = GB(p2, 8, 8);
@@ -920,33 +919,11 @@ CommandCost CmdRefitShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_CAN_T_REFIT_DESTROYED_VEHICLE);
/* Check cargo */
- if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
+ if (new_cid >= NUM_CARGO) return CMD_ERROR;
- v->InvalidateNewGRFCacheOfChain();
-
- /* Back up the existing cargo type */
- CargoID temp_cid = v->cargo_type;
- byte temp_subtype = v->cargo_subtype;
- v->cargo_type = new_cid;
- v->cargo_subtype = new_subtype;
-
- uint capacity = GetVehicleCapacity(v);
-
- /* Restore the cargo type */
- v->cargo_type = temp_cid;
- v->cargo_subtype = temp_subtype;
-
- _returned_refit_capacity = capacity;
-
- if (new_cid != v->cargo_type) {
- cost = GetRefitCost(v->engine_type);
- }
+ CommandCost cost = RefitVehicle(v, true, new_cid, new_subtype, flags);
if (flags & DC_EXEC) {
- v->cargo_cap = capacity;
- v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
- v->cargo_type = new_cid;
- v->cargo_subtype = new_subtype;
v->colourmap = PAL_NONE; // invalidate vehicle colour map
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index be4c66f3e..2cb2541c0 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -2113,52 +2113,15 @@ CommandCost CmdRefitRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
/* Check cargo */
if (new_cid >= NUM_CARGO) return CMD_ERROR;
- CommandCost cost(EXPENSES_TRAIN_RUN);
- uint num = 0;
-
- v->InvalidateNewGRFCacheOfChain();
- do {
- /* XXX: We also refit all the attached wagons en-masse if they
- * can be refitted. This is how TTDPatch does it. TODO: Have
- * some nice [Refit] button near each wagon. --pasky */
- if (!CanRefitTo(v->engine_type, new_cid)) continue;
-
- const Engine *e = Engine::Get(v->engine_type);
- if (!e->CanCarryCargo()) continue;
-
- /* Back up the vehicle's cargo type */
- CargoID temp_cid = v->cargo_type;
- byte temp_subtype = v->cargo_subtype;
- v->cargo_type = new_cid;
- v->cargo_subtype = new_subtype;
-
- uint amount = GetVehicleCapacity(v);
-
- /* Restore the original cargo type */
- v->cargo_type = temp_cid;
- v->cargo_subtype = temp_subtype;
-
- if (new_cid != v->cargo_type) {
- cost.AddCost(GetRefitCost(v->engine_type));
- }
-
- num += amount;
- if (flags & DC_EXEC) {
- v->cargo.Truncate((v->cargo_type == new_cid) ? amount : 0);
- v->cargo_type = new_cid;
- v->cargo_cap = amount;
- v->cargo_subtype = new_subtype;
- SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
- SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
- InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
- }
- } while ((v = v->Next()) != NULL && !only_this);
-
- _returned_refit_capacity = num;
+ CommandCost cost = RefitVehicle(v, only_this, new_cid, new_subtype, flags);
/* Update the train's cached variables */
if (flags & DC_EXEC) {
- TrainConsistChanged(Train::Get(p1)->First(), false);
+ Train *front = v->First();
+ TrainConsistChanged(front, false);
+ SetWindowDirty(WC_VEHICLE_DETAILS, front->index);
+ SetWindowDirty(WC_VEHICLE_DEPOT, front->tile);
+ InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
} else {
v->InvalidateNewGRFCacheOfChain(); // always invalidate; querycost might have filled it
}
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 2fbc9a6ac..174cc6aa0 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -683,52 +683,6 @@ void CallVehicleTicks()
_current_company = OWNER_NONE;
}
-/** Check if a given engine type can be refitted to a given cargo
- * @param engine_type Engine type to check
- * @param cid_to check refit to this cargo-type
- * @return true if it is possible, false otherwise
- */
-bool CanRefitTo(EngineID engine_type, CargoID cid_to)
-{
- return HasBit(EngInfo(engine_type)->refit_mask, cid_to);
-}
-
-/** Learn the price of refitting a certain engine
- * @param engine_type Which engine to refit
- * @return Price for refitting
- */
-CommandCost GetRefitCost(EngineID engine_type)
-{
- Money base_cost;
- ExpensesType expense_type;
- const Engine *e = Engine::Get(engine_type);
- switch (e->type) {
- case VEH_SHIP:
- base_cost = _price.ship_base;
- expense_type = EXPENSES_SHIP_RUN;
- break;
-
- case VEH_ROAD:
- base_cost = _price.roadveh_base;
- expense_type = EXPENSES_ROADVEH_RUN;
- break;
-
- case VEH_AIRCRAFT:
- base_cost = _price.aircraft_base;
- expense_type = EXPENSES_AIRCRAFT_RUN;
- break;
-
- case VEH_TRAIN:
- base_cost = 2 * ((e->u.rail.railveh_type == RAILVEH_WAGON) ?
- _price.build_railwagon : _price.build_railvehicle);
- expense_type = EXPENSES_TRAIN_RUN;
- break;
-
- default: NOT_REACHED();
- }
- return CommandCost(expense_type, (e->info.refit_cost * base_cost) >> 10);
-}
-
static void DoDrawVehicle(const Vehicle *v)
{
SpriteID image = v->cur_image;
diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp
index e8567abc4..58d8dabc2 100644
--- a/src/vehicle_cmd.cpp
+++ b/src/vehicle_cmd.cpp
@@ -256,6 +256,93 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32
return cost;
}
+/** Learn the price of refitting a certain engine
+ * @param engine_type Which engine to refit
+ * @return Price for refitting
+ */
+static CommandCost GetRefitCost(EngineID engine_type)
+{
+ Money base_cost;
+ ExpensesType expense_type;
+ const Engine *e = Engine::Get(engine_type);
+ switch (e->type) {
+ case VEH_SHIP:
+ base_cost = _price.ship_base;
+ expense_type = EXPENSES_SHIP_RUN;
+ break;
+
+ case VEH_ROAD:
+ base_cost = _price.roadveh_base;
+ expense_type = EXPENSES_ROADVEH_RUN;
+ break;
+
+ case VEH_AIRCRAFT:
+ base_cost = _price.aircraft_base;
+ expense_type = EXPENSES_AIRCRAFT_RUN;
+ break;
+
+ case VEH_TRAIN:
+ base_cost = 2 * ((e->u.rail.railveh_type == RAILVEH_WAGON) ?
+ _price.build_railwagon : _price.build_railvehicle);
+ expense_type = EXPENSES_TRAIN_RUN;
+ break;
+
+ default: NOT_REACHED();
+ }
+ return CommandCost(expense_type, (e->info.refit_cost * base_cost) >> 10);
+}
+
+/**
+ * Refits a vehicle (chain).
+ * This is the vehicle-type independent part of the CmdRefitXXX functions.
+ * @param v The vehicle to refit.
+ * @param only_this Whether to only refit this vehicle, or the whole chain.
+ * @param new_cid Cargotype to refit to
+ * @param new_subtype Cargo subtype to refit to
+ * @param flags Command flags
+ * @return refit cost; or CMD_ERROR if no vehicle was actually refitable to the cargo
+ */
+CommandCost RefitVehicle(Vehicle *v, bool only_this, CargoID new_cid, byte new_subtype, DoCommandFlag flags)
+{
+ CommandCost cost(v->GetExpenseType(false));
+ uint total_capacity = 0;
+ bool success = false;
+
+ v->InvalidateNewGRFCacheOfChain();
+ for (; v != NULL; v = (only_this ? NULL : v->Next())) {
+ const Engine *e = Engine::Get(v->engine_type);
+ if (!e->CanCarryCargo() || !HasBit(e->info.refit_mask, new_cid)) continue;
+ success = true;
+
+ /* Back up the vehicle's cargo type */
+ CargoID temp_cid = v->cargo_type;
+ byte temp_subtype = v->cargo_subtype;
+ v->cargo_type = new_cid;
+ v->cargo_subtype = new_subtype;
+
+ uint amount = GetVehicleCapacity(v);
+ total_capacity += amount;
+
+ /* Restore the original cargo type */
+ v->cargo_type = temp_cid;
+ v->cargo_subtype = temp_subtype;
+
+ if (new_cid != v->cargo_type) {
+ cost.AddCost(GetRefitCost(v->engine_type));
+ }
+
+ if (flags & DC_EXEC) {
+ v->cargo.Truncate((v->cargo_type == new_cid) ? amount : 0);
+ v->cargo_type = new_cid;
+ v->cargo_cap = amount;
+ v->cargo_subtype = new_subtype;
+ }
+ }
+
+ _returned_refit_capacity = total_capacity;
+ return success ? cost : CMD_ERROR;
+}
+
/** Test if a name is unique among vehicle names.
* @param name Name to test.
* @return True ifffffff the name is unique.
diff --git a/src/vehicle_func.h b/src/vehicle_func.h
index 718feb426..1d46abd45 100644
--- a/src/vehicle_func.h
+++ b/src/vehicle_func.h
@@ -42,8 +42,7 @@ byte VehicleRandomBits();
void ResetVehiclePosHash();
void ResetVehicleColourMap();
-bool CanRefitTo(EngineID engine_type, CargoID cid_to);
-CommandCost GetRefitCost(EngineID engine_type);
+CommandCost RefitVehicle(Vehicle *v, bool only_this, CargoID new_cid, byte new_subtype, DoCommandFlag flags);
void ViewportAddVehicles(DrawPixelInfo *dpi);