1
0
Fork 0

(svn r10811) -Fix (r10097): Refit all the parts of an articulated road vehicle, not just the first part.

release/0.6
maedhros 2007-08-06 13:05:45 +00:00
parent a43370bf1c
commit 8c4a4baac1
1 changed files with 64 additions and 46 deletions

View File

@ -2009,7 +2009,7 @@ void RoadVehiclesYearlyLoop()
* @param p2 Bitstuffed elements * @param p2 Bitstuffed elements
* - p2 = (bit 0-7) - the new cargo type to refit to * - p2 = (bit 0-7) - the new cargo type to refit to
* - p2 = (bit 8-15) - the new cargo subtype to refit to * - p2 = (bit 8-15) - the new cargo subtype to refit to
* - p2 = (bit 16) - refit only this vehicle (ignored) * - p2 = (bit 16) - refit only this vehicle
* @return cost of refit or error * @return cost of refit or error
*/ */
CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
@ -2018,7 +2018,9 @@ CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
CommandCost cost; CommandCost cost;
CargoID new_cid = GB(p2, 0, 8); CargoID new_cid = GB(p2, 0, 8);
byte new_subtype = GB(p2, 8, 8); byte new_subtype = GB(p2, 8, 8);
bool only_this = HASBIT(p2, 16);
uint16 capacity = CALLBACK_FAILED; uint16 capacity = CALLBACK_FAILED;
uint total_capacity = 0;
if (!IsValidVehicleID(p1)) return CMD_ERROR; if (!IsValidVehicleID(p1)) return CMD_ERROR;
@ -2027,63 +2029,79 @@ CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR; if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
if (!CheckRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE); if (!CheckRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR; if (new_cid >= NUM_CARGO) return CMD_ERROR;
SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN); SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) { for (; v != NULL; v = v->next) {
/* Back up the cargo type */ /* XXX: We refit all the attached wagons en-masse if they can be
CargoID temp_cid = v->cargo_type; * refitted. This is how TTDPatch does it. TODO: Have some nice
byte temp_subtype = v->cargo_subtype; * [Refit] button near each wagon. */
v->cargo_type = new_cid; if (!CanRefitTo(v->engine_type, new_cid)) continue;
v->cargo_subtype = new_subtype;
/* Check the refit capacity callback */ if (v->cargo_cap == 0) continue;
capacity = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
/* Restore the original cargo type */ if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
v->cargo_type = temp_cid; /* Back up the cargo type */
v->cargo_subtype = temp_subtype; CargoID temp_cid = v->cargo_type;
} byte temp_subtype = v->cargo_subtype;
v->cargo_type = new_cid;
v->cargo_subtype = new_subtype;
if (capacity == CALLBACK_FAILED) { /* Check the refit capacity callback */
/* callback failed or not used, use default capacity */ capacity = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
const RoadVehicleInfo *rvi = RoadVehInfo(v->engine_type);
CargoID old_cid = rvi->cargo_type; /* Restore the original cargo type */
/* normally, the capacity depends on the cargo type, a vehicle can v->cargo_type = temp_cid;
* carry twice as much mail/goods as normal cargo, and four times as v->cargo_subtype = temp_subtype;
* many passengers
*/
capacity = GetVehicleProperty(v, 0x0F, rvi->capacity);
switch (old_cid) {
case CT_PASSENGERS: break;
case CT_MAIL:
case CT_GOODS: capacity *= 2; break;
default: capacity *= 4; break;
} }
switch (new_cid) {
case CT_PASSENGERS: break; if (capacity == CALLBACK_FAILED) {
case CT_MAIL: /* callback failed or not used, use default capacity */
case CT_GOODS: capacity /= 2; break; const RoadVehicleInfo *rvi = RoadVehInfo(v->engine_type);
default: capacity /= 4; break;
CargoID old_cid = rvi->cargo_type;
/* normally, the capacity depends on the cargo type, a vehicle can
* carry twice as much mail/goods as normal cargo, and four times as
* many passengers
*/
capacity = GetVehicleProperty(v, 0x0F, rvi->capacity);
switch (old_cid) {
case CT_PASSENGERS: break;
case CT_MAIL:
case CT_GOODS: capacity *= 2; break;
default: capacity *= 4; break;
}
switch (new_cid) {
case CT_PASSENGERS: break;
case CT_MAIL:
case CT_GOODS: capacity /= 2; break;
default: capacity /= 4; break;
}
} }
}
_returned_refit_capacity = capacity;
if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) { if (capacity == 0) continue;
cost = GetRefitCost(v->engine_type);
total_capacity += capacity;
if (IsHumanPlayer(v->owner) && 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;
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
RebuildVehicleLists();
}
if (only_this) break;
} }
if (flags & DC_EXEC) { _returned_refit_capacity = total_capacity;
v->cargo_cap = capacity;
v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
v->cargo_type = new_cid;
v->cargo_subtype = new_subtype;
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
RebuildVehicleLists();
}
return cost; return cost;
} }