1
0
Fork 0

(svn r10205) -Codechange: refactor returning of cost, so it can be more easily modified.

release/0.6
rubidium 2007-06-18 19:53:50 +00:00
parent 3771d666c0
commit 49220cc6f1
37 changed files with 502 additions and 406 deletions

View File

@ -84,7 +84,7 @@ static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uin
CommandCost AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback) CommandCost AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback)
{ {
PlayerID old_lp; PlayerID old_lp;
CommandCost res = 0; CommandCost res;
const char* tmp_cmdtext; const char* tmp_cmdtext;
/* If you enable DC_EXEC with DC_QUERY_COST you are a really strange /* If you enable DC_EXEC with DC_QUERY_COST you are a really strange

View File

@ -152,7 +152,7 @@ static EngineID AiChooseTrainToBuild(RailType railtype, int32 money, byte flag,
} }
ret = DoCommand(tile, i, 0, 0, CMD_BUILD_RAIL_VEHICLE); ret = DoCommand(tile, i, 0, 0, CMD_BUILD_RAIL_VEHICLE);
if (CmdSucceeded(ret) && ret <= money && rvi->ai_rank >= best_veh_score) { if (CmdSucceeded(ret) && ret.GetCost() <= money && rvi->ai_rank >= best_veh_score) {
best_veh_score = rvi->ai_rank; best_veh_score = rvi->ai_rank;
best_veh_index = i; best_veh_index = i;
} }
@ -189,8 +189,8 @@ static EngineID AiChooseRoadVehToBuild(CargoID cargo, int32 money, TileIndex til
if (CmdFailed(ret)) continue; if (CmdFailed(ret)) continue;
/* Add the cost of refitting */ /* Add the cost of refitting */
if (rvi->cargo_type != cargo) ret += GetRefitCost(i); if (rvi->cargo_type != cargo) ret.AddCost(GetRefitCost(i));
if (ret > money) continue; if (ret.GetCost() > money) continue;
best_veh_rating = rating; best_veh_rating = rating;
best_veh_index = i; best_veh_index = i;
@ -216,8 +216,8 @@ static EngineID AiChooseAircraftToBuild(int32 money, byte flag)
if ((AircraftVehInfo(i)->subtype & AIR_CTOL) != flag) continue; if ((AircraftVehInfo(i)->subtype & AIR_CTOL) != flag) continue;
ret = DoCommand(0, i, 0, DC_QUERY_COST, CMD_BUILD_AIRCRAFT); ret = DoCommand(0, i, 0, DC_QUERY_COST, CMD_BUILD_AIRCRAFT);
if (CmdSucceeded(ret) && ret <= money && ret >= best_veh_cost) { if (CmdSucceeded(ret) && ret.GetCost() <= money && ret.GetCost() >= best_veh_cost) {
best_veh_cost = ret; best_veh_cost = ret.GetCost();
best_veh_index = i; best_veh_index = i;
} }
} }
@ -1641,7 +1641,7 @@ static bool AiCheckTrackResources(TileIndex tile, const AiDefaultBlockData *p, b
static CommandCost AiDoBuildDefaultRailTrack(TileIndex tile, const AiDefaultBlockData* p, RailType railtype, byte flag) static CommandCost AiDoBuildDefaultRailTrack(TileIndex tile, const AiDefaultBlockData* p, RailType railtype, byte flag)
{ {
CommandCost ret; CommandCost ret;
CommandCost total_cost = 0; CommandCost total_cost;
Town *t = NULL; Town *t = NULL;
int rating = 0; int rating = 0;
int i, j, k; int i, j, k;
@ -1662,7 +1662,7 @@ static CommandCost AiDoBuildDefaultRailTrack(TileIndex tile, const AiDefaultBloc
} }
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
total_cost += ret; total_cost.AddCost(ret);
clear_town_stuff:; clear_town_stuff:;
if (_cleared_town != NULL) { if (_cleared_town != NULL) {
@ -1684,7 +1684,7 @@ clear_town_stuff:;
k = i; k = i;
ret = DoCommand(c, railtype, i, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL); ret = DoCommand(c, railtype, i, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
total_cost += ret; total_cost.AddCost(ret);
} }
} }
@ -1699,17 +1699,18 @@ clear_town_stuff:;
ret = DoCommand(c, k, 0, flag, CMD_BUILD_SIGNALS); ret = DoCommand(c, k, 0, flag, CMD_BUILD_SIGNALS);
} while (--j); } while (--j);
} else { } else {
ret = _price.build_signals; ret.AddCost(_price.build_signals);
} }
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
total_cost += ret; total_cost.AddCost(ret);
} }
} else if (p->mode == 3) { } else if (p->mode == 3) {
//Clear stuff and then build single rail. //Clear stuff and then build single rail.
if (GetTileSlope(c, NULL) != SLOPE_FLAT) return CMD_ERROR; if (GetTileSlope(c, NULL) != SLOPE_FLAT) return CMD_ERROR;
ret = DoCommand(c, 0, 0, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_LANDSCAPE_CLEAR); ret = DoCommand(c, 0, 0, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
total_cost += ret + _price.build_rail; total_cost.AddCost(ret);
total_cost.AddCost(_price.build_rail);
if (flag & DC_EXEC) { if (flag & DC_EXEC) {
DoCommand(c, railtype, p->attr & 1, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_SINGLE_RAIL); DoCommand(c, railtype, p->attr & 1, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_SINGLE_RAIL);
@ -2069,7 +2070,7 @@ static inline void AiCheckBuildRailTunnelHere(AiRailFinder *arf, TileIndex tile,
if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) { if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
CommandCost cost = DoCommand(tile, arf->player->ai.railtype_to_use, 0, DC_AUTO, CMD_BUILD_TUNNEL); CommandCost cost = DoCommand(tile, arf->player->ai.railtype_to_use, 0, DC_AUTO, CMD_BUILD_TUNNEL);
if (CmdSucceeded(cost) && cost <= (arf->player->player_money >> 4)) { if (CmdSucceeded(cost) && cost.GetCost() <= (arf->player->player_money >> 4)) {
AiBuildRailRecursive(arf, _build_tunnel_endtile, p[0] & 3); AiBuildRailRecursive(arf, _build_tunnel_endtile, p[0] & 3);
if (arf->depth == 1) AiCheckRailPathBetter(arf, p); if (arf->depth == 1) AiCheckRailPathBetter(arf, p);
} }
@ -2210,8 +2211,8 @@ static void AiBuildRailConstruct(Player *p)
*/ */
for (i = MAX_BRIDGES - 1; i != 0; i--) { for (i = MAX_BRIDGES - 1; i != 0; i--) {
if (CheckBridge_Stuff(i, bridge_len)) { if (CheckBridge_Stuff(i, bridge_len)) {
int32 cost = DoCommand(arf.bridge_end_tile, p->ai.cur_tile_a, i | (p->ai.railtype_to_use << 8), DC_AUTO, CMD_BUILD_BRIDGE); CommandCost cost = DoCommand(arf.bridge_end_tile, p->ai.cur_tile_a, i | (p->ai.railtype_to_use << 8), DC_AUTO, CMD_BUILD_BRIDGE);
if (CmdSucceeded(cost) && cost < (p->player_money >> 5)) break; if (CmdSucceeded(cost) && cost.GetCost() < (p->player_money >> 5)) break;
} }
} }
@ -2629,7 +2630,7 @@ static int AiFindBestDefaultRoadBlock(TileIndex tile, byte direction, byte cargo
static CommandCost AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag) static CommandCost AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag)
{ {
CommandCost ret; CommandCost ret;
CommandCost total_cost = 0; CommandCost total_cost;
Town *t = NULL; Town *t = NULL;
int rating = 0; int rating = 0;
int roadflag = 0; int roadflag = 0;
@ -2651,7 +2652,7 @@ static CommandCost AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBloc
ret = DoCommand(c, p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD); ret = DoCommand(c, p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
total_cost += ret; total_cost.AddCost(ret);
continue; continue;
} }
@ -2671,7 +2672,7 @@ static CommandCost AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBloc
clear_town_stuff:; clear_town_stuff:;
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
total_cost += ret; total_cost.AddCost(ret);
if (_cleared_town != NULL) { if (_cleared_town != NULL) {
if (t != NULL && t != _cleared_town) return CMD_ERROR; if (t != NULL && t != _cleared_town) return CMD_ERROR;
@ -2969,7 +2970,7 @@ static inline void AiCheckBuildRoadTunnelHere(AiRoadFinder *arf, TileIndex tile,
if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) { if (GetTileSlope(tile, &z) == _dir_table_2[p[0] & 3] && z != 0) {
CommandCost cost = DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL); CommandCost cost = DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL);
if (CmdSucceeded(cost) && cost <= (arf->player->player_money >> 4)) { if (CmdSucceeded(cost) && cost.GetCost() <= (arf->player->player_money >> 4)) {
AiBuildRoadRecursive(arf, _build_tunnel_endtile, p[0] & 3); AiBuildRoadRecursive(arf, _build_tunnel_endtile, p[0] & 3);
if (arf->depth == 1) AiCheckRoadPathBetter(arf, p); if (arf->depth == 1) AiCheckRoadPathBetter(arf, p);
} }
@ -3102,7 +3103,7 @@ do_some_terraform:
for (i = 10; i != 0; i--) { for (i = 10; i != 0; i--) {
if (CheckBridge_Stuff(i, bridge_len)) { if (CheckBridge_Stuff(i, bridge_len)) {
CommandCost cost = DoCommand(tile, p->ai.cur_tile_a, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE); CommandCost cost = DoCommand(tile, p->ai.cur_tile_a, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE);
if (CmdSucceeded(cost) && cost < (p->player_money >> 5)) break; if (CmdSucceeded(cost) && cost.GetCost() < (p->player_money >> 5)) break;
} }
} }
@ -3390,13 +3391,13 @@ static void AiStateAirportStuff(Player *p)
static CommandCost AiDoBuildDefaultAirportBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag) static CommandCost AiDoBuildDefaultAirportBlock(TileIndex tile, const AiDefaultBlockData *p, byte flag)
{ {
uint32 avail_airports = GetValidAirports(); uint32 avail_airports = GetValidAirports();
CommandCost total_cost = 0, ret; CommandCost total_cost, ret;
for (; p->mode == 0; p++) { for (; p->mode == 0; p++) {
if (!HASBIT(avail_airports, p->attr)) return CMD_ERROR; if (!HASBIT(avail_airports, p->attr)) return CMD_ERROR;
ret = DoCommand(TILE_MASK(tile + ToTileIndexDiff(p->tileoffs)), p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_AIRPORT); ret = DoCommand(TILE_MASK(tile + ToTileIndexDiff(p->tileoffs)), p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_AIRPORT);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
total_cost += ret; total_cost.AddCost(ret);
} }
return total_cost; return total_cost;

View File

@ -97,7 +97,7 @@ CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo,
TileIndex *route = PathFinderInfo->route; TileIndex *route = PathFinderInfo->route;
int dir; int dir;
int old_dir = -1; int old_dir = -1;
CommandCost cost = 0; CommandCost cost;
CommandCost res; CommandCost res;
// We need to calculate the direction with the parent of the parent.. so we skip // We need to calculate the direction with the parent of the parent.. so we skip
// the first pieces and the last piece // the first pieces and the last piece
@ -105,30 +105,30 @@ CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo,
// When we are done, stop it // When we are done, stop it
if (part >= PathFinderInfo->route_length - 1) { if (part >= PathFinderInfo->route_length - 1) {
PathFinderInfo->position = -2; PathFinderInfo->position = -2;
return 0; return CommandCost();
} }
if (PathFinderInfo->rail_or_road) { if (PathFinderInfo->rail_or_road) {
// Tunnel code // Tunnel code
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) { if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
cost += AI_DoCommand(route[part], 0, 0, flag, CMD_BUILD_TUNNEL); cost.AddCost(AI_DoCommand(route[part], 0, 0, flag, CMD_BUILD_TUNNEL));
PathFinderInfo->position++; PathFinderInfo->position++;
// TODO: problems! // TODO: problems!
if (CmdFailed(cost)) { if (CmdFailed(cost)) {
DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]); DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]);
return 0; return CommandCost();
} }
return cost; return cost;
} }
// Bridge code // Bridge code
if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) { if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
cost += AiNew_Build_Bridge(p, route[part], route[part - 1], flag); cost.AddCost(AiNew_Build_Bridge(p, route[part], route[part - 1], flag));
PathFinderInfo->position++; PathFinderInfo->position++;
// TODO: problems! // TODO: problems!
if (CmdFailed(cost)) { if (CmdFailed(cost)) {
DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part - 1]); DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part - 1]);
return 0; return CommandCost();
} }
return cost; return cost;
} }
@ -147,9 +147,9 @@ CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo,
if (CmdFailed(res)) { if (CmdFailed(res)) {
// Problem.. let's just abort it all! // Problem.. let's just abort it all!
p->ainew.state = AI_STATE_NOTHING; p->ainew.state = AI_STATE_NOTHING;
return 0; return CommandCost();
} }
cost += res; cost.AddCost(res);
// Go to the next tile // Go to the next tile
part++; part++;
// Check if it is still in range.. // Check if it is still in range..
@ -162,23 +162,23 @@ CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo,
} else { } else {
// Tunnel code // Tunnel code
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) { if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
cost += AI_DoCommand(route[part], 0x200 | ROADTYPES_ROAD, 0, flag, CMD_BUILD_TUNNEL); cost.AddCost(AI_DoCommand(route[part], 0x200 | ROADTYPES_ROAD, 0, flag, CMD_BUILD_TUNNEL));
PathFinderInfo->position++; PathFinderInfo->position++;
// TODO: problems! // TODO: problems!
if (CmdFailed(cost)) { if (CmdFailed(cost)) {
DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]); DEBUG(ai, 0, "[BuildPath] tunnel could not be built (0x%X)", route[part]);
return 0; return CommandCost();
} }
return cost; return cost;
} }
// Bridge code // Bridge code
if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) { if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
cost += AiNew_Build_Bridge(p, route[part], route[part + 1], flag); cost.AddCost(AiNew_Build_Bridge(p, route[part], route[part + 1], flag));
PathFinderInfo->position++; PathFinderInfo->position++;
// TODO: problems! // TODO: problems!
if (CmdFailed(cost)) { if (CmdFailed(cost)) {
DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part + 1]); DEBUG(ai, 0, "[BuildPath] bridge could not be built (0x%X, 0x%X)", route[part], route[part + 1]);
return 0; return CommandCost();
} }
return cost; return cost;
} }
@ -203,10 +203,10 @@ CommandCost AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo,
// Problem.. let's just abort it all! // Problem.. let's just abort it all!
DEBUG(ai, 0, "[BuidPath] route building failed at tile 0x%X, aborting", route[part]); DEBUG(ai, 0, "[BuidPath] route building failed at tile 0x%X, aborting", route[part]);
p->ainew.state = AI_STATE_NOTHING; p->ainew.state = AI_STATE_NOTHING;
return 0; return CommandCost();
} }
if (CmdSucceeded(res)) cost += res; if (CmdSucceeded(res)) cost.AddCost(res);
} }
// Go to the next tile // Go to the next tile
part++; part++;
@ -314,11 +314,12 @@ CommandCost AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction
return AI_DoCommand(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT); return AI_DoCommand(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
} else { } else {
ret = AI_DoCommand(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT); ret = AI_DoCommand(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret2)) return ret;
// Try to build the road from the depot // Try to build the road from the depot
ret2 = AI_DoCommand(tile + TileOffsByDiagDir(direction), DiagDirToRoadBits(ReverseDiagDir(direction)), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD); ret2 = AI_DoCommand(tile + TileOffsByDiagDir(direction), DiagDirToRoadBits(ReverseDiagDir(direction)), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
// If it fails, ignore it.. // If it fails, ignore it..
if (CmdFailed(ret2)) return ret; if (CmdFailed(ret2)) return ret;
return ret + ret2; ret.AddCost(ret2);
return ret;
} }
} }

View File

@ -691,7 +691,7 @@ static void AiNew_State_FindStation(Player *p)
// See how much it is going to cost us... // See how much it is going to cost us...
r = AiNew_Build_Station(p, p->ainew.tbt, new_tile, 0, 0, 0, DC_QUERY_COST); r = AiNew_Build_Station(p, p->ainew.tbt, new_tile, 0, 0, 0, DC_QUERY_COST);
p->ainew.new_cost += r; p->ainew.new_cost += r.GetCost();
direction = AI_PATHFINDER_NO_DIRECTION; direction = AI_PATHFINDER_NO_DIRECTION;
} else if (new_tile == 0 && p->ainew.tbt == AI_TRUCK) { } else if (new_tile == 0 && p->ainew.tbt == AI_TRUCK) {
@ -850,7 +850,7 @@ static void AiNew_State_FindDepot(Player *p)
r = AiNew_Build_Depot(p, t, ReverseDiagDir(j), 0); r = AiNew_Build_Depot(p, t, ReverseDiagDir(j), 0);
if (CmdFailed(r)) continue; if (CmdFailed(r)) continue;
// Found a spot! // Found a spot!
p->ainew.new_cost += r; p->ainew.new_cost += r.GetCost();
p->ainew.depot_tile = t; p->ainew.depot_tile = t;
p->ainew.depot_direction = ReverseDiagDir(j); // Reverse direction p->ainew.depot_direction = ReverseDiagDir(j); // Reverse direction
p->ainew.state = AI_STATE_VERIFY_ROUTE; p->ainew.state = AI_STATE_VERIFY_ROUTE;
@ -935,7 +935,7 @@ static void AiNew_State_VerifyRoute(Player *p)
do { do {
p->ainew.path_info.position++; p->ainew.path_info.position++;
p->ainew.new_cost += AiNew_Build_RoutePart(p, &p->ainew.path_info, DC_QUERY_COST); p->ainew.new_cost += AiNew_Build_RoutePart(p, &p->ainew.path_info, DC_QUERY_COST).GetCost();
} while (p->ainew.path_info.position != -2); } while (p->ainew.path_info.position != -2);
// Now we know the price of build station + path. Now check how many vehicles // Now we know the price of build station + path. Now check how many vehicles
@ -951,7 +951,7 @@ static void AiNew_State_VerifyRoute(Player *p)
// Check how much it it going to cost us.. // Check how much it it going to cost us..
for (i=0;i<res;i++) { for (i=0;i<res;i++) {
p->ainew.new_cost += AiNew_Build_Vehicle(p, 0, DC_QUERY_COST); p->ainew.new_cost += AiNew_Build_Vehicle(p, 0, DC_QUERY_COST).GetCost();
} }
// Now we know how much the route is going to cost us // Now we know how much the route is going to cost us
@ -985,7 +985,7 @@ static void AiNew_State_VerifyRoute(Player *p)
// Build the stations // Build the stations
static void AiNew_State_BuildStation(Player *p) static void AiNew_State_BuildStation(Player *p)
{ {
CommandCost res = 0; CommandCost res;
assert(p->ainew.state == AI_STATE_BUILD_STATION); assert(p->ainew.state == AI_STATE_BUILD_STATION);
if (p->ainew.temp == 0) { if (p->ainew.temp == 0) {
if (!IsTileType(p->ainew.from_tile, MP_STATION)) if (!IsTileType(p->ainew.from_tile, MP_STATION))
@ -1103,7 +1103,7 @@ static void AiNew_State_BuildPath(Player *p)
// Builds the depot // Builds the depot
static void AiNew_State_BuildDepot(Player *p) static void AiNew_State_BuildDepot(Player *p)
{ {
CommandCost res = 0; CommandCost res;
assert(p->ainew.state == AI_STATE_BUILD_DEPOT); assert(p->ainew.state == AI_STATE_BUILD_DEPOT);
if (IsTileType(p->ainew.depot_tile, MP_STREET) && GetRoadTileType(p->ainew.depot_tile) == ROAD_TILE_DEPOT) { if (IsTileType(p->ainew.depot_tile, MP_STREET) && GetRoadTileType(p->ainew.depot_tile) == ROAD_TILE_DEPOT) {
@ -1278,7 +1278,7 @@ static void AiNew_CheckVehicle(Player *p, Vehicle *v)
if (!AiNew_SetSpecialVehicleFlag(p, v, AI_VEHICLEFLAG_SELL)) return; if (!AiNew_SetSpecialVehicleFlag(p, v, AI_VEHICLEFLAG_SELL)) return;
{ {
CommandCost ret = 0; CommandCost ret;
if (v->type == VEH_ROAD) if (v->type == VEH_ROAD)
ret = AI_DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT); ret = AI_DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
// This means we can not find a depot :s // This means we can not find a depot :s

View File

@ -229,7 +229,7 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height)
static CommandCost EstimateAircraftCost(EngineID engine, const AircraftVehicleInfo *avi) static CommandCost EstimateAircraftCost(EngineID engine, const AircraftVehicleInfo *avi)
{ {
return GetEngineProperty(engine, 0x0B, avi->base_cost) * (_price.aircraft_base >> 3) >> 5; return CommandCost(GetEngineProperty(engine, 0x0B, avi->base_cost) * (_price.aircraft_base >> 3) >> 5);
} }
@ -346,7 +346,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
v->subtype = (avi->subtype & AIR_CTOL ? AIR_AIRCRAFT : AIR_HELICOPTER); v->subtype = (avi->subtype & AIR_CTOL ? AIR_AIRCRAFT : AIR_HELICOPTER);
v->UpdateDeltaXY(INVALID_DIR); v->UpdateDeltaXY(INVALID_DIR);
v->value = value; v->value = (uint32)value.GetCost();
u->subtype = AIR_SHADOW; u->subtype = AIR_SHADOW;
u->UpdateDeltaXY(INVALID_DIR); u->UpdateDeltaXY(INVALID_DIR);
@ -493,7 +493,7 @@ CommandCost CmdSellAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
DoDeleteAircraft(v); DoDeleteAircraft(v);
} }
return -(int32)v->value; return CommandCost(-(int32)v->value);
} }
/** Start/Stop an aircraft. /** Start/Stop an aircraft.
@ -534,7 +534,7 @@ CommandCost CmdStartStopAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32
InvalidateWindowClasses(WC_AIRCRAFT_LIST); InvalidateWindowClasses(WC_AIRCRAFT_LIST);
} }
return 0; return CommandCost();
} }
/** Send an aircraft to the hangar. /** Send an aircraft to the hangar.
@ -569,7 +569,7 @@ CommandCost CmdSendAircraftToHangar(TileIndex tile, uint32 flags, uint32 p1, uin
TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
@ -609,7 +609,7 @@ CommandCost CmdSendAircraftToHangar(TileIndex tile, uint32 flags, uint32 p1, uin
} }
} }
return 0; return CommandCost();
} }
@ -668,7 +668,7 @@ CommandCost CmdRefitAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
_returned_refit_capacity = pass; _returned_refit_capacity = pass;
CommandCost cost = 0; CommandCost cost;
if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) { if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
cost = GetRefitCost(v->engine_type); cost = GetRefitCost(v->engine_type);
} }
@ -744,9 +744,9 @@ void OnNewDay_Aircraft(Vehicle *v)
if (v->vehstatus & VS_STOPPED) return; if (v->vehstatus & VS_STOPPED) return;
CommandCost cost = GetVehicleProperty(v, 0x0E, AircraftVehInfo(v->engine_type)->running_cost) * _price.aircraft_running / 364; CommandCost cost = CommandCost(GetVehicleProperty(v, 0x0E, AircraftVehInfo(v->engine_type)->running_cost) * _price.aircraft_running / 364);
v->profit_this_year -= cost >> 8; v->profit_this_year -= cost.GetCost() >> 8;
SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN); SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN);
SubtractMoneyFromPlayerFract(v->owner, cost); SubtractMoneyFromPlayerFract(v->owner, cost);

View File

@ -154,7 +154,7 @@ static CommandCost ReplaceVehicle(Vehicle **w, byte flags, int32 total_cost)
replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type); replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type);
/* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */ /* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */
if (replacement_cargo_type == CT_INVALID) return 0; if (replacement_cargo_type == CT_INVALID) return CommandCost();
sell_value = DoCommand(0, old_v->index, 0, DC_QUERY_COST, GetCmdSellVeh(old_v)); sell_value = DoCommand(0, old_v->index, 0, DC_QUERY_COST, GetCmdSellVeh(old_v));
@ -167,15 +167,17 @@ static CommandCost ReplaceVehicle(Vehicle **w, byte flags, int32 total_cost)
cost = DoCommand(old_v->tile, new_engine_type, 3, flags, GetCmdBuildVeh(old_v)); cost = DoCommand(old_v->tile, new_engine_type, 3, flags, GetCmdBuildVeh(old_v));
if (CmdFailed(cost)) { if (CmdFailed(cost)) {
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
SubtractMoneyFromPlayer(-sell_value); // Take back the money we just gave the player /* Take back the money we just gave the player */
sell_value.MultiplyCost(-1);
SubtractMoneyFromPlayer(sell_value);
return cost; return cost;
} }
if (replacement_cargo_type != CT_NO_REFIT) { if (replacement_cargo_type != CT_NO_REFIT) {
/* add refit cost */ /* add refit cost */
CommandCost refit_cost = GetRefitCost(new_engine_type); CommandCost refit_cost = GetRefitCost(new_engine_type);
if (old_v->type == VEH_TRAIN && IsMultiheaded(old_v)) refit_cost += refit_cost; // pay for both ends if (old_v->type == VEH_TRAIN && IsMultiheaded(old_v)) refit_cost.AddCost(refit_cost); // pay for both ends
cost += refit_cost; cost.AddCost(refit_cost);
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
@ -246,7 +248,7 @@ static CommandCost ReplaceVehicle(Vehicle **w, byte flags, int32 total_cost)
GetName(vehicle_name, old_v->string_id & 0x7FF, lastof(vehicle_name)); GetName(vehicle_name, old_v->string_id & 0x7FF, lastof(vehicle_name));
} }
} else { // flags & DC_EXEC not set } else { // flags & DC_EXEC not set
CommandCost tmp_move = 0; CommandCost tmp_move;
if (old_v->type == VEH_TRAIN && IsFrontEngine(old_v) && old_v->next != NULL) { if (old_v->type == VEH_TRAIN && IsFrontEngine(old_v) && old_v->next != NULL) {
/* Verify that the wagons can be placed on the engine in question. /* Verify that the wagons can be placed on the engine in question.
* This is done by building an engine, test if the wagons can be added and then sell the test engine. */ * This is done by building an engine, test if the wagons can be added and then sell the test engine. */
@ -258,9 +260,11 @@ static CommandCost ReplaceVehicle(Vehicle **w, byte flags, int32 total_cost)
/* Ensure that the player will not end up having negative money while autoreplacing /* Ensure that the player will not end up having negative money while autoreplacing
* This is needed because the only other check is done after the income from selling the old vehicle is substracted from the cost */ * This is needed because the only other check is done after the income from selling the old vehicle is substracted from the cost */
if (CmdFailed(tmp_move) || p->money64 < (cost + total_cost)) { if (CmdFailed(tmp_move) || p->money64 < (cost.GetCost() + total_cost)) {
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
SubtractMoneyFromPlayer(-sell_value); // Pay back the loan /* Pay back the loan */
sell_value.MultiplyCost(-1);
SubtractMoneyFromPlayer(sell_value);
return CMD_ERROR; return CMD_ERROR;
} }
} }
@ -268,10 +272,11 @@ static CommandCost ReplaceVehicle(Vehicle **w, byte flags, int32 total_cost)
/* Take back the money we just gave the player just before building the vehicle /* Take back the money we just gave the player just before building the vehicle
* The player will get the same amount now that the sale actually takes place */ * The player will get the same amount now that the sale actually takes place */
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
SubtractMoneyFromPlayer(-sell_value); sell_value.MultiplyCost(-1);
SubtractMoneyFromPlayer(sell_value);
/* sell the engine/ find out how much you get for the old engine (income is returned as negative cost) */ /* sell the engine/ find out how much you get for the old engine (income is returned as negative cost) */
cost += DoCommand(0, old_v->index, 0, flags, GetCmdSellVeh(old_v)); cost.AddCost(DoCommand(0, old_v->index, 0, flags, GetCmdSellVeh(old_v)));
if (new_front) { if (new_front) {
/* now we assign the old unitnumber to the new vehicle */ /* now we assign the old unitnumber to the new vehicle */
@ -300,7 +305,7 @@ CommandCost MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs)
Vehicle *w; Vehicle *w;
const Player *p = GetPlayer(v->owner); const Player *p = GetPlayer(v->owner);
byte flags = 0; byte flags = 0;
CommandCost cost, temp_cost = 0; CommandCost cost, temp_cost;
bool stopped; bool stopped;
/* Remember the length in case we need to trim train later on /* Remember the length in case we need to trim train later on
@ -326,7 +331,7 @@ CommandCost MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs)
v->leave_depot_instantly = false; v->leave_depot_instantly = false;
for (;;) { for (;;) {
cost = 0; cost = CommandCost();
w = v; w = v;
do { do {
if (w->type == VEH_TRAIN && IsMultiheaded(w) && !IsTrainEngine(w)) { if (w->type == VEH_TRAIN && IsMultiheaded(w) && !IsTrainEngine(w)) {
@ -352,7 +357,7 @@ CommandCost MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs)
} }
/* Now replace the vehicle */ /* Now replace the vehicle */
temp_cost = ReplaceVehicle(&w, flags, cost); temp_cost = ReplaceVehicle(&w, flags, cost.GetCost());
if (CmdFailed(temp_cost)) break; // replace failed for some reason. Leave the vehicle alone if (CmdFailed(temp_cost)) break; // replace failed for some reason. Leave the vehicle alone
@ -364,11 +369,11 @@ CommandCost MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs)
*/ */
v = w; v = w;
} }
cost += temp_cost; cost.AddCost(temp_cost);
} while (w->type == VEH_TRAIN && (w = GetNextVehicle(w)) != NULL); } while (w->type == VEH_TRAIN && (w = GetNextVehicle(w)) != NULL);
if (!(flags & DC_EXEC) && (p->money64 < (int32)(cost + p->engine_renew_money) || cost == 0)) { if (!(flags & DC_EXEC) && (p->money64 < (int32)(cost.GetCost() + p->engine_renew_money) || cost.GetCost() == 0)) {
if (!check && p->money64 < (int32)(cost + p->engine_renew_money) && ( _local_player == v->owner ) && cost != 0) { if (!check && p->money64 < (int32)(cost.GetCost() + p->engine_renew_money) && ( _local_player == v->owner ) && cost.GetCost() != 0) {
StringID message; StringID message;
SetDParam(0, v->unitnumber); SetDParam(0, v->unitnumber);
switch (v->type) { switch (v->type) {
@ -418,13 +423,13 @@ CommandCost MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs)
w = GetNextVehicle(w); w = GetNextVehicle(w);
DoCommand(0, (INVALID_VEHICLE << 16) | temp->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE); DoCommand(0, (INVALID_VEHICLE << 16) | temp->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
MoveVehicleCargo(v, temp); MoveVehicleCargo(v, temp);
cost += DoCommand(0, temp->index, 0, DC_EXEC, CMD_SELL_RAIL_WAGON); cost.AddCost(DoCommand(0, temp->index, 0, DC_EXEC, CMD_SELL_RAIL_WAGON));
} }
} }
if (stopped) v->vehstatus &= ~VS_STOPPED; if (stopped) v->vehstatus &= ~VS_STOPPED;
if (display_costs) { if (display_costs) {
if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost); if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
_current_player = OWNER_NONE; _current_player = OWNER_NONE;
} }
return cost; return cost;

View File

@ -145,7 +145,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, byte bridge_type)
const Bridge *b = &_bridge[bridge_type]; const Bridge *b = &_bridge[bridge_type];
// bridge is accepted, add to list // bridge is accepted, add to list
// add to terraforming & bulldozing costs the cost of the bridge itself (not computed with DC_QUERY_COST) // add to terraforming & bulldozing costs the cost of the bridge itself (not computed with DC_QUERY_COST)
_bridgedata.costs[j] = ret + (((int64)tot_bridgedata_len * _price.build_bridge * b->price) >> 8); _bridgedata.costs[j] = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * b->price) >> 8);
_bridgedata.indexes[j] = bridge_type; _bridgedata.indexes[j] = bridge_type;
j++; j++;
} }

View File

@ -148,7 +148,7 @@ static int TerraformProc(TerraformerState *ts, TileIndex tile, int mode)
return -1; return -1;
} }
ts->cost += ret; ts->cost.AddCost(ret.GetCost());
if (ts->tile_table_count >= 625) return -1; if (ts->tile_table_count >= 625) return -1;
ts->tile_table[ts->tile_table_count++] = tile; ts->tile_table[ts->tile_table_count++] = tile;
@ -198,7 +198,7 @@ static bool TerraformTileHeight(TerraformerState *ts, TileIndex tile, int height
mod->tile = tile; mod->tile = tile;
mod->height = (byte)height; mod->height = (byte)height;
ts->cost += _price.terraform; ts->cost.AddCost(_price.terraform);
{ {
int direction = ts->direction, r; int direction = ts->direction, r;
@ -248,7 +248,7 @@ CommandCost CmdTerraformLand(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
ts.direction = direction = p2 ? 1 : -1; ts.direction = direction = p2 ? 1 : -1;
ts.flags = flags; ts.flags = flags;
ts.modheight_count = ts.tile_table_count = 0; ts.modheight_count = ts.tile_table_count = 0;
ts.cost = 0; ts.cost = CommandCost();
ts.modheight = modheight_data; ts.modheight = modheight_data;
ts.tile_table = tile_table_data; ts.tile_table = tile_table_data;
@ -364,7 +364,7 @@ CommandCost CmdLevelLand(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
int ey; int ey;
int sx, sy; int sx, sy;
uint h, curh; uint h, curh;
int32 money; CommandCost money;
CommandCost ret; CommandCost ret;
CommandCost cost; CommandCost cost;
@ -387,29 +387,29 @@ CommandCost CmdLevelLand(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
size_x = ex - sx + 1; size_x = ex - sx + 1;
size_y = ey - sy + 1; size_y = ey - sy + 1;
money = GetAvailableMoneyForCommand(); money.AddCost(GetAvailableMoneyForCommand());
cost = 0;
BEGIN_TILE_LOOP(tile2, size_x, size_y, tile) { BEGIN_TILE_LOOP(tile2, size_x, size_y, tile) {
curh = TileHeight(tile2); curh = TileHeight(tile2);
while (curh != h) { while (curh != h) {
ret = DoCommand(tile2, 8, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND); ret = DoCommand(tile2, 8, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND);
if (CmdFailed(ret)) break; if (CmdFailed(ret)) break;
cost += ret;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
if ((money -= ret) < 0) { money.AddCost(-ret.GetCost());
_additional_cash_required = ret; if (money.GetCost() < 0) {
return cost - ret; _additional_cash_required = ret.GetCost();
return cost;
} }
DoCommand(tile2, 8, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND); DoCommand(tile2, 8, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
} }
cost.AddCost(ret);
curh += (curh > h) ? -1 : 1; curh += (curh > h) ? -1 : 1;
} }
} END_TILE_LOOP(tile2, size_x, size_y, tile) } END_TILE_LOOP(tile2, size_x, size_y, tile)
return (cost == 0) ? CMD_ERROR : cost; return (cost.GetCost() == 0) ? CMD_ERROR : cost;
} }
/** Purchase a land area. Actually you only purchase one tile, so /** Purchase a land area. Actually you only purchase one tile, so
@ -440,7 +440,7 @@ CommandCost CmdPurchaseLandArea(TileIndex tile, uint32 flags, uint32 p1, uint32
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
return cost + _price.purchase_land * 10; return cost.AddCost(_price.purchase_land * 10);
} }
@ -457,10 +457,8 @@ static CommandCost ClearTile_Clear(TileIndex tile, byte flags)
}; };
CommandCost price; CommandCost price;
if (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) == 0) { if (!IsClearGround(tile, CLEAR_GRASS) || GetClearDensity(tile) != 0) {
price = 0; price.AddCost(*clear_price_table[GetClearGround(tile)]);
} else {
price = *clear_price_table[GetClearGround(tile)];
} }
if (flags & DC_EXEC) DoClearSquare(tile); if (flags & DC_EXEC) DoClearSquare(tile);
@ -488,7 +486,7 @@ CommandCost CmdSellLandArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (flags & DC_EXEC) DoClearSquare(tile); if (flags & DC_EXEC) DoClearSquare(tile);
return - _price.purchase_land * 2; return CommandCost(- _price.purchase_land * 2);
} }

View File

@ -372,13 +372,13 @@ CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint p
if (_docommand_recursive == 1 || !(flags & DC_EXEC) || (flags & DC_FORCETEST) ) { if (_docommand_recursive == 1 || !(flags & DC_EXEC) || (flags & DC_FORCETEST) ) {
res = proc(tile, flags & ~DC_EXEC, p1, p2); res = proc(tile, flags & ~DC_EXEC, p1, p2);
if (CmdFailed(res)) { if (CmdFailed(res)) {
if (res & 0xFFFF) _error_message = res & 0xFFFF; res.SetGlobalErrorMessage();
goto error; goto error;
} }
if (_docommand_recursive == 1 && if (_docommand_recursive == 1 &&
!(flags & DC_QUERY_COST) && !(flags & DC_QUERY_COST) &&
res != 0 && res.GetCost() != 0 &&
!CheckPlayerHasMoney(res)) { !CheckPlayerHasMoney(res)) {
goto error; goto error;
} }
@ -394,7 +394,7 @@ CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint p
* themselves with "SET_EXPENSES_TYPE(...);" at the beginning of the function */ * themselves with "SET_EXPENSES_TYPE(...);" at the beginning of the function */
res = proc(tile, flags, p1, p2); res = proc(tile, flags, p1, p2);
if (CmdFailed(res)) { if (CmdFailed(res)) {
if (res & 0xFFFF) _error_message = res & 0xFFFF; res.SetGlobalErrorMessage();
error: error:
_docommand_recursive--; _docommand_recursive--;
_cmd_text = NULL; _cmd_text = NULL;
@ -425,7 +425,7 @@ int32 GetAvailableMoneyForCommand()
* the callback is called when the command succeeded or failed. */ * the callback is called when the command succeeded or failed. */
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd) bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback, uint32 cmd)
{ {
CommandCost res = 0, res2; CommandCost res, res2;
CommandProc *proc; CommandProc *proc;
uint32 flags; uint32 flags;
bool notest; bool notest;
@ -497,10 +497,10 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
/* estimate the cost. */ /* estimate the cost. */
res = proc(tile, flags, p1, p2); res = proc(tile, flags, p1, p2);
if (CmdFailed(res)) { if (CmdFailed(res)) {
if (res & 0xFFFF) _error_message = res & 0xFFFF; res.SetGlobalErrorMessage();
ShowErrorMessage(_error_message, error_part1, x, y); ShowErrorMessage(_error_message, error_part1, x, y);
} else { } else {
ShowEstimatedCostOrIncome(res, x, y); ShowEstimatedCostOrIncome(res.GetCost(), x, y);
} }
_docommand_recursive = 0; _docommand_recursive = 0;
@ -513,11 +513,11 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
/* first test if the command can be executed. */ /* first test if the command can be executed. */
res = proc(tile, flags, p1, p2); res = proc(tile, flags, p1, p2);
if (CmdFailed(res)) { if (CmdFailed(res)) {
if (res & 0xFFFF) _error_message = res & 0xFFFF; res.SetGlobalErrorMessage();
goto show_error; goto show_error;
} }
/* no money? Only check if notest is off */ /* no money? Only check if notest is off */
if (!notest && res != 0 && !CheckPlayerHasMoney(res)) goto show_error; if (!notest && res.GetCost() != 0 && !CheckPlayerHasMoney(res)) goto show_error;
} }
#ifdef ENABLE_NETWORK #ifdef ENABLE_NETWORK
@ -552,10 +552,10 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
/* If notest is on, it means the result of the test can be different than /* If notest is on, it means the result of the test can be different than
* the real command.. so ignore the test */ * the real command.. so ignore the test */
if (!notest && !((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) { if (!notest && !((cmd & CMD_NO_TEST_IF_IN_NETWORK) && _networking)) {
assert(res == res2); // sanity check assert(res.GetCost() == res2.GetCost() && CmdFailed(res) == CmdFailed(res2)); // sanity check
} else { } else {
if (CmdFailed(res2)) { if (CmdFailed(res2)) {
if (res2 & 0xFFFF) _error_message = res2 & 0xFFFF; res.SetGlobalErrorMessage();
goto show_error; goto show_error;
} }
} }
@ -563,11 +563,11 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
SubtractMoneyFromPlayer(res2); SubtractMoneyFromPlayer(res2);
if (IsLocalPlayer() && _game_mode != GM_EDITOR) { if (IsLocalPlayer() && _game_mode != GM_EDITOR) {
if (res2 != 0) ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2); if (res2.GetCost() != 0) ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2.GetCost());
if (_additional_cash_required) { if (_additional_cash_required) {
SetDParam(0, _additional_cash_required); SetDParam(0, _additional_cash_required);
ShowErrorMessage(STR_0003_NOT_ENOUGH_CASH_REQUIRES, error_part1, x, y); ShowErrorMessage(STR_0003_NOT_ENOUGH_CASH_REQUIRES, error_part1, x, y);
if (res2 == 0) goto callb_err; if (res2.GetCost() == 0) goto callb_err;
} }
} }
@ -590,3 +590,47 @@ callb_err:
_cmd_text = NULL; _cmd_text = NULL;
return false; return false;
} }
CommandCost CommandCost::AddCost(CommandCost ret)
{
this->cost += ret.cost;
if (this->success && !ret.success) {
this->message = ret.message;
this->success = false;
}
return *this;
}
CommandCost CommandCost::AddCost(int32 cost)
{
this->cost += cost;
return *this;
}
CommandCost CommandCost::MultiplyCost(int factor)
{
this->cost *= factor;
return *this;
}
int32 CommandCost::GetCost() const
{
return this->cost;
}
void CommandCost::SetGlobalErrorMessage() const
{
extern StringID _error_message;
if (this->message != INVALID_STRING_ID) _error_message = this->message;
}
bool CommandCost::Succeeded() const
{
return this->success;
}
bool CommandCost::Failed() const
{
return !this->success;
}

View File

@ -164,8 +164,6 @@ enum {
DC_AI_BUILDING = 0x20, ///< special building rules for AI DC_AI_BUILDING = 0x20, ///< special building rules for AI
DC_NO_TOWN_RATING = 0x40, ///< town rating does not disallow you from building DC_NO_TOWN_RATING = 0x40, ///< town rating does not disallow you from building
DC_FORCETEST = 0x80, ///< force test too. DC_FORCETEST = 0x80, ///< force test too.
CMD_ERROR = ((int32)0x80000000),
}; };
#define CMD_MSG(x) ((x) << 16) #define CMD_MSG(x) ((x) << 16)
@ -191,21 +189,12 @@ struct Command {
byte flags; byte flags;
}; };
//#define return_cmd_error(errcode) do { _error_message=(errcode); return CMD_ERROR; } while(0) static inline bool CmdFailed(CommandCost cost) { return cost.Failed(); }
#define return_cmd_error(errcode) do { return CMD_ERROR | (errcode); } while (0) static inline bool CmdSucceeded(CommandCost cost) { return cost.Succeeded(); }
/** static const CommandCost CMD_ERROR = CommandCost((StringID)INVALID_STRING_ID);
* Check the return value of a DoCommand*() function
* @param res the resulting value from the command to be checked
* @return Return true if the command failed, false otherwise
*/
static inline bool CmdFailed(CommandCost res)
{
/* lower 16bits are the StringID of the possible error */
return res <= (CMD_ERROR | INVALID_STRING_ID);
}
static inline bool CmdSucceeded(CommandCost res) { return !CmdFailed(res); } #define return_cmd_error(errcode) do { return CommandCost((StringID)(errcode)); } while (0)
/* command.cpp */ /* command.cpp */
typedef void CommandCallback(bool success, TileIndex tile, uint32 p1, uint32 p2); typedef void CommandCallback(bool success, TileIndex tile, uint32 p1, uint32 p2);

View File

@ -710,7 +710,7 @@ static void PlayersPayInterest()
_current_player = p->index; _current_player = p->index;
SET_EXPENSES_TYPE(EXPENSES_LOAN_INT); SET_EXPENSES_TYPE(EXPENSES_LOAN_INT);
SubtractMoneyFromPlayer(BIGMULUS(p->current_loan, interest, 16)); SubtractMoneyFromPlayer(CommandCost(BIGMULUS(p->current_loan, interest, 16)));
SET_EXPENSES_TYPE(EXPENSES_OTHER); SET_EXPENSES_TYPE(EXPENSES_OTHER);
SubtractMoneyFromPlayer(_price.station_value >> 2); SubtractMoneyFromPlayer(_price.station_value >> 2);
@ -1823,12 +1823,12 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32
if (_cur_year - p->inaugurated_year < 6) return_cmd_error(STR_7080_PROTECTED); if (_cur_year - p->inaugurated_year < 6) return_cmd_error(STR_7080_PROTECTED);
/* Those lines are here for network-protection (clients can be slow) */ /* Those lines are here for network-protection (clients can be slow) */
if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 0) return 0; if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 0) return cost;
/* We can not buy out a real player (temporarily). TODO: well, enable it obviously */ /* We can not buy out a real player (temporarily). TODO: well, enable it obviously */
if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 1 && !p->is_ai) return 0; if (GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 1 && !p->is_ai) return cost;
cost = CalculateCompanyValue(p) >> 2; cost.AddCost(CalculateCompanyValue(p) >> 2);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
PlayerByte* b = p->share_owners; PlayerByte* b = p->share_owners;
int i; int i;
@ -1866,7 +1866,7 @@ CommandCost CmdSellShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint3
p = GetPlayer((PlayerID)p1); p = GetPlayer((PlayerID)p1);
/* Those lines are here for network-protection (clients can be slow) */ /* Those lines are here for network-protection (clients can be slow) */
if (GetAmountOwnedBy(p, _current_player) == 0) return 0; if (GetAmountOwnedBy(p, _current_player) == 0) return CommandCost();
/* adjust it a little to make it less profitable to sell and buy */ /* adjust it a little to make it less profitable to sell and buy */
cost = CalculateCompanyValue(p) >> 2; cost = CalculateCompanyValue(p) >> 2;
@ -1878,7 +1878,7 @@ CommandCost CmdSellShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint3
*b = PLAYER_SPECTATOR; *b = PLAYER_SPECTATOR;
InvalidateWindow(WC_COMPANY, p1); InvalidateWindow(WC_COMPANY, p1);
} }
return cost; return CommandCost((int32)cost);
} }
/** Buy up another company. /** Buy up another company.
@ -1909,7 +1909,7 @@ CommandCost CmdBuyCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
DoAcquireCompany(p); DoAcquireCompany(p);
} }
return p->bankrupt_value; return CommandCost(p->bankrupt_value);
} }
/** Prices */ /** Prices */

View File

@ -276,7 +276,7 @@ CommandCost CmdWantEnginePreview(TileIndex tile, uint32 flags, uint32 p1, uint32
if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_player); if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_player);
return 0; return CommandCost();
} }
/* Determine if an engine type is a wagon (and not a loco) */ /* Determine if an engine type is a wagon (and not a loco) */
@ -393,7 +393,7 @@ CommandCost CmdRenameEngine(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
DeleteName(str); DeleteName(str);
} }
return 0; return CommandCost();
} }
@ -541,7 +541,7 @@ CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, Engi
er = GetEngineReplacement(*erl, old_engine, group); er = GetEngineReplacement(*erl, old_engine, group);
if (er != NULL) { if (er != NULL) {
if (flags & DC_EXEC) er->to = new_engine; if (flags & DC_EXEC) er->to = new_engine;
return 0; return CommandCost();
} }
er = AllocateEngineRenew(); er = AllocateEngineRenew();
@ -557,7 +557,7 @@ CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, Engi
*erl = (EngineRenewList)er; *erl = (EngineRenewList)er;
} }
return 0; return CommandCost();
} }
CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, uint32 flags) CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, uint32 flags)
@ -578,7 +578,7 @@ CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, Group
} }
DeleteEngineRenew(er); DeleteEngineRenew(er);
} }
return 0; return CommandCost();
} }
prev = er; prev = er;
er = er->next; er = er->next;

View File

@ -110,7 +110,7 @@ CommandCost CmdCreateGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player); InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player);
} }
return 0; return CommandCost();
} }
@ -156,7 +156,7 @@ CommandCost CmdDeleteGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player); InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player);
} }
return 0; return CommandCost();
} }
@ -187,7 +187,7 @@ CommandCost CmdRenameGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
InvalidateWindowData(GetWCForVT(g->vehicle_type), (g->vehicle_type << 11) | VLW_GROUP_LIST | _current_player); InvalidateWindowData(GetWCForVT(g->vehicle_type), (g->vehicle_type << 11) | VLW_GROUP_LIST | _current_player);
} }
return 0; return CommandCost();
} }
@ -235,7 +235,7 @@ CommandCost CmdAddVehicleGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p
InvalidateWindowData(GetWCForVT(v->type), (v->type << 11) | VLW_GROUP_LIST | _current_player); InvalidateWindowData(GetWCForVT(v->type), (v->type << 11) | VLW_GROUP_LIST | _current_player);
} }
return 0; return CommandCost();
} }
/** /**
@ -271,7 +271,7 @@ CommandCost CmdAddSharedVehicleGroup(TileIndex tile, uint32 flags, uint32 p1, ui
InvalidateWindowData(GetWCForVT(type), (type << 11) | VLW_GROUP_LIST | _current_player); InvalidateWindowData(GetWCForVT(type), (type << 11) | VLW_GROUP_LIST | _current_player);
} }
return 0; return CommandCost();
} }
@ -307,7 +307,7 @@ CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, uint32 flags, uint32 p1, u
InvalidateWindowData(GetWCForVT(type), (type << 11) | VLW_GROUP_LIST | _current_player); InvalidateWindowData(GetWCForVT(type), (type << 11) | VLW_GROUP_LIST | _current_player);
} }
return 0; return CommandCost();
} }
@ -332,7 +332,7 @@ CommandCost CmdSetGroupReplaceProtection(TileIndex tile, uint32 flags, uint32 p1
InvalidateWindowData(GetWCForVT(g->vehicle_type), (g->vehicle_type << 11) | VLW_GROUP_LIST | _current_player); InvalidateWindowData(GetWCForVT(g->vehicle_type), (g->vehicle_type << 11) | VLW_GROUP_LIST | _current_player);
} }
return 0; return CommandCost();
} }
/** /**

View File

@ -354,7 +354,7 @@ static CommandCost ClearTile_Industry(TileIndex tile, byte flags)
} }
if (flags & DC_EXEC) DeleteIndustry(i); if (flags & DC_EXEC) DeleteIndustry(i);
return 0; return CommandCost();
} }
static void TransportIndustryGoods(TileIndex tile) static void TransportIndustryGoods(TileIndex tile)
@ -1505,7 +1505,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (CreateNewIndustryHelper(tile, p1, flags, indspec, it) == NULL) return CMD_ERROR; if (CreateNewIndustryHelper(tile, p1, flags, indspec, it) == NULL) return CMD_ERROR;
return (_price.build_industry >> 8) * indspec->cost_multiplier; return CommandCost((_price.build_industry >> 8) * indspec->cost_multiplier);
} }

View File

@ -401,20 +401,19 @@ CommandCost CmdClearArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (ex < sx) Swap(ex, sx); if (ex < sx) Swap(ex, sx);
if (ey < sy) Swap(ey, sy); if (ey < sy) Swap(ey, sy);
money = GetAvailableMoneyForCommand(); money.AddCost(GetAvailableMoneyForCommand());
cost = 0;
for (x = sx; x <= ex; ++x) { for (x = sx; x <= ex; ++x) {
for (y = sy; y <= ey; ++y) { for (y = sy; y <= ey; ++y) {
ret = DoCommand(TileXY(x, y), 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR); ret = DoCommand(TileXY(x, y), 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) continue; if (CmdFailed(ret)) continue;
cost += ret;
success = true; success = true;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
if (ret > 0 && (money -= ret) < 0) { money.AddCost(-ret.GetCost());
_additional_cash_required = ret; if (ret.GetCost() > 0 && money.GetCost() < 0) {
return cost - ret; _additional_cash_required = ret.GetCost();
return cost;
} }
DoCommand(TileXY(x, y), 0, 0, flags, CMD_LANDSCAPE_CLEAR); DoCommand(TileXY(x, y), 0, 0, flags, CMD_LANDSCAPE_CLEAR);
@ -426,6 +425,7 @@ CommandCost CmdClearArea(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
); );
} }
} }
cost.AddCost(ret);
} }
} }

View File

@ -34,7 +34,7 @@ CommandCost CmdSetPlayerFace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
GetPlayer(_current_player)->face = pf; GetPlayer(_current_player)->face = pf;
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} }
return 0; return CommandCost();
} }
/** Change the player's company-colour /** Change the player's company-colour
@ -114,7 +114,7 @@ CommandCost CmdSetPlayerColor(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
} }
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} }
return 0; return CommandCost();
} }
/** Increase the loan of your company. /** Increase the loan of your company.
@ -151,7 +151,7 @@ CommandCost CmdIncreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
InvalidatePlayerWindows(p); InvalidatePlayerWindows(p);
} }
return 0; return CommandCost();
} }
/** Decrease the loan of your company. /** Decrease the loan of your company.
@ -190,7 +190,7 @@ CommandCost CmdDecreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
UpdatePlayerMoney32(p); UpdatePlayerMoney32(p);
InvalidatePlayerWindows(p); InvalidatePlayerWindows(p);
} }
return 0; return CommandCost();
} }
/** Change the name of the company. /** Change the name of the company.
@ -218,7 +218,7 @@ CommandCost CmdChangeCompanyName(TileIndex tile, uint32 flags, uint32 p1, uint32
DeleteName(str); DeleteName(str);
} }
return 0; return CommandCost();
} }
/** Change the name of the president. /** Change the name of the president.
@ -254,7 +254,7 @@ CommandCost CmdChangePresidentName(TileIndex tile, uint32 flags, uint32 p1, uint
DeleteName(str); DeleteName(str);
} }
return 0; return CommandCost();
} }
/** Pause/Unpause the game (server-only). /** Pause/Unpause the game (server-only).
@ -274,7 +274,7 @@ CommandCost CmdPause(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
InvalidateWindow(WC_STATUS_BAR, 0); InvalidateWindow(WC_STATUS_BAR, 0);
InvalidateWindow(WC_MAIN_TOOLBAR, 0); InvalidateWindow(WC_MAIN_TOOLBAR, 0);
} }
return 0; return CommandCost();
} }
/** Change the financial flow of your company. /** Change the financial flow of your company.
@ -291,7 +291,7 @@ CommandCost CmdMoneyCheat(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (_networking) return CMD_ERROR; if (_networking) return CMD_ERROR;
#endif #endif
SET_EXPENSES_TYPE(EXPENSES_OTHER); SET_EXPENSES_TYPE(EXPENSES_OTHER);
return -(int32)p1; return CommandCost(-(int32)p1);
} }
/** Transfer funds (money) from one player to another. /** Transfer funds (money) from one player to another.
@ -306,19 +306,19 @@ CommandCost CmdMoneyCheat(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{ {
const Player *p = GetPlayer(_current_player); const Player *p = GetPlayer(_current_player);
CommandCost amount = min((int32)p1, 20000000); CommandCost amount(min((int32)p1, 20000000));
SET_EXPENSES_TYPE(EXPENSES_OTHER); SET_EXPENSES_TYPE(EXPENSES_OTHER);
/* You can only transfer funds that is in excess of your loan */ /* You can only transfer funds that is in excess of your loan */
if (p->money64 - p->current_loan < amount || amount <= 0) return CMD_ERROR; if (p->money64 - p->current_loan < amount.GetCost() || amount.GetCost() <= 0) return CMD_ERROR;
if (!_networking || !IsValidPlayer((PlayerID)p2)) return CMD_ERROR; if (!_networking || !IsValidPlayer((PlayerID)p2)) return CMD_ERROR;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
/* Add money to player */ /* Add money to player */
PlayerID old_cp = _current_player; PlayerID old_cp = _current_player;
_current_player = (PlayerID)p2; _current_player = (PlayerID)p2;
SubtractMoneyFromPlayer(-amount); SubtractMoneyFromPlayer(CommandCost(-amount.GetCost()));
_current_player = old_cp; _current_player = old_cp;
} }
@ -354,5 +354,5 @@ CommandCost CmdChangeDifficultyLevel(TileIndex tile, uint32 flags, uint32 p1, ui
if (_networking && !_network_server && FindWindowById(WC_GAME_OPTIONS, 0) != NULL) if (_networking && !_network_server && FindWindowById(WC_GAME_OPTIONS, 0) != NULL)
ShowGameDifficulty(); ShowGameDifficulty();
} }
return 0; return CommandCost();
} }

View File

@ -90,7 +90,7 @@ static void Place_LandInfo(TileIndex tile)
Window *w; Window *w;
Town *t; Town *t;
int64 old_money; int64 old_money;
int64 costclear; CommandCost costclear;
AcceptedCargo ac; AcceptedCargo ac;
TileDesc td; TileDesc td;
StringID str; StringID str;
@ -123,7 +123,7 @@ static void Place_LandInfo(TileIndex tile)
str = STR_01A4_COST_TO_CLEAR_N_A; str = STR_01A4_COST_TO_CLEAR_N_A;
if (CmdSucceeded(costclear)) { if (CmdSucceeded(costclear)) {
SetDParam(0, costclear); SetDParam(0, costclear.GetCost());
str = STR_01A5_COST_TO_CLEAR; str = STR_01A5_COST_TO_CLEAR;
} }
GetString(_landinfo_data[2], str, lastof(_landinfo_data[2])); GetString(_landinfo_data[2], str, lastof(_landinfo_data[2]));

View File

@ -52,6 +52,8 @@ struct PalSpriteID {
typedef uint16 EngineID; typedef uint16 EngineID;
typedef uint16 UnitID; typedef uint16 UnitID;
typedef uint16 StringID; typedef uint16 StringID;
#define INVALID_STRING_ID 0xFFFF
typedef EngineID *EngineList; ///< engine list type placeholder acceptable for C code (see helpers.cpp) typedef EngineID *EngineList; ///< engine list type placeholder acceptable for C code (see helpers.cpp)
/* IDs used in Pools */ /* IDs used in Pools */
@ -67,7 +69,6 @@ typedef uint16 SignID;
typedef uint16 GroupID; typedef uint16 GroupID;
typedef uint16 EngineRenewID; typedef uint16 EngineRenewID;
typedef uint16 DestinationID; typedef uint16 DestinationID;
typedef int32 CommandCost;
/* DestinationID must be at least as large as every these below, because it can /* DestinationID must be at least as large as every these below, because it can
* be any of them * be any of them
@ -359,10 +360,84 @@ struct ViewportSign {
byte width_1, width_2; byte width_1, width_2;
}; };
/**
* Common return value for all commands. Wraps the cost and
* a possible error message/state together.
*/
class CommandCost {
int32 cost; ///< The cost of this action
StringID message; ///< Warning message for when success is unset
bool success; ///< Whether the comment went fine up to this moment
public:
/**
* Creates a command cost return with no cost and no error
*/
CommandCost() : cost(0), message(INVALID_STRING_ID), success(true) {}
/**
* Creates a command return value the is failed with the given message
*/
CommandCost(StringID msg) : cost(0), message(msg), success(false) {}
/**
* Creates a command return value with the given start cost
* @param cst the initial cost of this command
*/
CommandCost(int32 cst) : cost(cst), message(INVALID_STRING_ID), success(true) {}
/** "Hack" to make everything compile nicely, not needed when cost is int64 */
CommandCost(uint cst) : cost(cst), message(INVALID_STRING_ID), success(true) {}
/**
* Adds the cost of the given command return value to this cost.
* Also takes a possible error message when it is set.
* @param ret the command to add the cost of.
* @return this class.
*/
CommandCost AddCost(CommandCost ret);
/**
* Adds the given cost to the cost of the command.
* @param cost the cost to add
* @return this class.
*/
CommandCost AddCost(int32 cost);
/**
* Multiplies the cost of the command by the given factor.
* @param cost factor to multiply the costs with
* @return this class
*/
CommandCost MultiplyCost(int factor);
/**
* The costs as made up to this moment
* @return the costs
*/
int32 GetCost() const;
/**
* Sets the global error message *if* this class has one.
*/
void SetGlobalErrorMessage() const;
/**
* Did this command succeed?
* @return true if and only if it succeeded
*/
bool Succeeded() const;
/**
* Did this command fail?
* @return true if and only if it failed
*/
bool Failed() const;
};
typedef void DrawTileProc(TileInfo *ti); typedef void DrawTileProc(TileInfo *ti);
typedef uint GetSlopeZProc(TileIndex tile, uint x, uint y); typedef uint GetSlopeZProc(TileIndex tile, uint x, uint y);
typedef int32 ClearTileProc(TileIndex tile, byte flags); typedef CommandCost ClearTileProc(TileIndex tile, byte flags);
typedef void GetAcceptedCargoProc(TileIndex tile, AcceptedCargo res); typedef void GetAcceptedCargoProc(TileIndex tile, AcceptedCargo res);
typedef void GetTileDescProc(TileIndex tile, TileDesc *td); typedef void GetTileDescProc(TileIndex tile, TileDesc *td);
/** /**
@ -589,8 +664,6 @@ enum {
VARDEF byte _savegame_sort_order; VARDEF byte _savegame_sort_order;
#define INVALID_STRING_ID 0xFFFF
enum { enum {
MAX_SCREEN_WIDTH = 2048, MAX_SCREEN_WIDTH = 2048,
MAX_SCREEN_HEIGHT = 1200, MAX_SCREEN_HEIGHT = 1200,

View File

@ -441,7 +441,7 @@ CommandCost CmdInsertOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
RebuildVehicleLists(); RebuildVehicleLists();
} }
return 0; return CommandCost();
} }
/** Declone an order-list /** Declone an order-list
@ -455,7 +455,7 @@ static CommandCost DecloneOrder(Vehicle *dst, uint32 flags)
InvalidateVehicleOrder(dst); InvalidateVehicleOrder(dst);
RebuildVehicleLists(); RebuildVehicleLists();
} }
return 0; return CommandCost();
} }
/** /**
@ -554,7 +554,7 @@ CommandCost CmdDeleteOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
RebuildVehicleLists(); RebuildVehicleLists();
} }
return 0; return CommandCost();
} }
/** Goto order of order-list. /** Goto order of order-list.
@ -595,7 +595,7 @@ CommandCost CmdSkipToOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (v->type == VEH_AIRCRAFT) InvalidateWindowClasses(WC_AIRCRAFT_LIST); if (v->type == VEH_AIRCRAFT) InvalidateWindowClasses(WC_AIRCRAFT_LIST);
if (v->type == VEH_SHIP) InvalidateWindowClasses(WC_SHIPS_LIST); if (v->type == VEH_SHIP) InvalidateWindowClasses(WC_SHIPS_LIST);
return 0; return CommandCost();
} }
/** /**
@ -681,7 +681,7 @@ CommandCost CmdMoveOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
RebuildVehicleLists(); RebuildVehicleLists();
} }
return 0; return CommandCost();
} }
/** Modify an order in the orderlist of a vehicle. /** Modify an order in the orderlist of a vehicle.
@ -763,7 +763,7 @@ CommandCost CmdModifyOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
} }
return 0; return CommandCost();
} }
/** Clone/share/copy an order-list of an other vehicle. /** Clone/share/copy an order-list of an other vehicle.
@ -896,7 +896,7 @@ CommandCost CmdCloneOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
default: return CMD_ERROR; default: return CMD_ERROR;
} }
return 0; return CommandCost();
} }
/** Add/remove refit orders from an order /** Add/remove refit orders from an order
@ -945,7 +945,7 @@ CommandCost CmdOrderRefit(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
} }
return 0; return CommandCost();
} }
/** /**
@ -1058,7 +1058,7 @@ CommandCost CmdRestoreOrderIndex(TileIndex tile, uint32 flags, uint32 p1, uint32
v->service_interval = serv_int; v->service_interval = serv_int;
} }
return 0; return CommandCost();
} }

View File

@ -175,10 +175,10 @@ void InvalidatePlayerWindows(const Player *p)
bool CheckPlayerHasMoney(CommandCost cost) bool CheckPlayerHasMoney(CommandCost cost)
{ {
if (cost > 0) { if (cost.GetCost() > 0) {
PlayerID pid = _current_player; PlayerID pid = _current_player;
if (IsValidPlayer(pid) && cost > GetPlayer(pid)->player_money) { if (IsValidPlayer(pid) && cost.GetCost() > GetPlayer(pid)->player_money) {
SetDParam(0, cost); SetDParam(0, cost.GetCost());
_error_message = STR_0003_NOT_ENOUGH_CASH_REQUIRES; _error_message = STR_0003_NOT_ENOUGH_CASH_REQUIRES;
return false; return false;
} }
@ -188,23 +188,23 @@ bool CheckPlayerHasMoney(CommandCost cost)
static void SubtractMoneyFromAnyPlayer(Player *p, CommandCost cost) static void SubtractMoneyFromAnyPlayer(Player *p, CommandCost cost)
{ {
p->money64 -= cost; p->money64 -= cost.GetCost();
UpdatePlayerMoney32(p); UpdatePlayerMoney32(p);
p->yearly_expenses[0][_yearly_expenses_type] += cost; p->yearly_expenses[0][_yearly_expenses_type] += cost.GetCost();
if (HASBIT(1 << EXPENSES_TRAIN_INC | if (HASBIT(1 << EXPENSES_TRAIN_INC |
1 << EXPENSES_ROADVEH_INC | 1 << EXPENSES_ROADVEH_INC |
1 << EXPENSES_AIRCRAFT_INC | 1 << EXPENSES_AIRCRAFT_INC |
1 << EXPENSES_SHIP_INC, _yearly_expenses_type)) { 1 << EXPENSES_SHIP_INC, _yearly_expenses_type)) {
p->cur_economy.income -= cost; p->cur_economy.income -= cost.GetCost();
} else if (HASBIT(1 << EXPENSES_TRAIN_RUN | } else if (HASBIT(1 << EXPENSES_TRAIN_RUN |
1 << EXPENSES_ROADVEH_RUN | 1 << EXPENSES_ROADVEH_RUN |
1 << EXPENSES_AIRCRAFT_RUN | 1 << EXPENSES_AIRCRAFT_RUN |
1 << EXPENSES_SHIP_RUN | 1 << EXPENSES_SHIP_RUN |
1 << EXPENSES_PROPERTY | 1 << EXPENSES_PROPERTY |
1 << EXPENSES_LOAN_INT, _yearly_expenses_type)) { 1 << EXPENSES_LOAN_INT, _yearly_expenses_type)) {
p->cur_economy.expenses -= cost; p->cur_economy.expenses -= cost.GetCost();
} }
InvalidatePlayerWindows(p); InvalidatePlayerWindows(p);
@ -217,15 +217,16 @@ void SubtractMoneyFromPlayer(CommandCost cost)
if (IsValidPlayer(pid)) SubtractMoneyFromAnyPlayer(GetPlayer(pid), cost); if (IsValidPlayer(pid)) SubtractMoneyFromAnyPlayer(GetPlayer(pid), cost);
} }
void SubtractMoneyFromPlayerFract(PlayerID player, CommandCost cost) void SubtractMoneyFromPlayerFract(PlayerID player, CommandCost cst)
{ {
Player *p = GetPlayer(player); Player *p = GetPlayer(player);
byte m = p->player_money_fraction; byte m = p->player_money_fraction;
int32 cost = cst.GetCost();
p->player_money_fraction = m - (byte)cost; p->player_money_fraction = m - (byte)cost;
cost >>= 8; cost >>= 8;
if (p->player_money_fraction > m) cost++; if (p->player_money_fraction > m) cost++;
if (cost != 0) SubtractMoneyFromAnyPlayer(p, cost); if (cost != 0) SubtractMoneyFromAnyPlayer(p, CommandCost(cost));
} }
/** the player_money field is kept as it is, but money64 contains the actual amount of money. */ /** the player_money field is kept as it is, but money64 contains the actual amount of money. */
@ -782,7 +783,7 @@ CommandCost CmdSetAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
break; break;
} }
return 0; return CommandCost();
} }
/** Control the players: add, delete, etc. /** Control the players: add, delete, etc.
@ -827,9 +828,9 @@ CommandCost CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (!_networking) return CMD_ERROR; if (!_networking) return CMD_ERROR;
/* Has the network client a correct ClientID? */ /* Has the network client a correct ClientID? */
if (!(flags & DC_EXEC)) return 0; if (!(flags & DC_EXEC)) return CommandCost();
#ifdef ENABLE_NETWORK #ifdef ENABLE_NETWORK
if (cid >= MAX_CLIENT_INFO) return 0; if (cid >= MAX_CLIENT_INFO) return CommandCost();
#endif /* ENABLE_NETWORK */ #endif /* ENABLE_NETWORK */
/* Delete multiplayer progress bar */ /* Delete multiplayer progress bar */
@ -903,7 +904,7 @@ CommandCost CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} break; } break;
case 1: /* Make a new AI player */ case 1: /* Make a new AI player */
if (!(flags & DC_EXEC)) return 0; if (!(flags & DC_EXEC)) return CommandCost();
DoStartupNewPlayer(true); DoStartupNewPlayer(true);
break; break;
@ -913,7 +914,7 @@ CommandCost CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (!IsValidPlayer((PlayerID)p2)) return CMD_ERROR; if (!IsValidPlayer((PlayerID)p2)) return CMD_ERROR;
if (!(flags & DC_EXEC)) return 0; if (!(flags & DC_EXEC)) return CommandCost();
p = GetPlayer((PlayerID)p2); p = GetPlayer((PlayerID)p2);
@ -951,7 +952,7 @@ CommandCost CmdPlayerCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
default: return CMD_ERROR; default: return CMD_ERROR;
} }
return 0; return CommandCost();
} }
static const StringID _endgame_perf_titles[] = { static const StringID _endgame_perf_titles[] = {

View File

@ -207,7 +207,7 @@ static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits ex
/* no special foundation */ /* no special foundation */
if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) { if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) {
return 0; return CommandCost();
} else if (!_patches.build_on_slopes || _is_old_ai_player) { } else if (!_patches.build_on_slopes || _is_old_ai_player) {
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
} }
@ -216,7 +216,7 @@ static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits ex
(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) && (rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
(tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N) (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)
)) { // partly up )) { // partly up
return (existing != 0) ? 0 : _price.terraform; return CommandCost((existing != 0) ? 0 : _price.terraform);
} }
} }
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
@ -237,7 +237,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p
RailType railtype; RailType railtype;
Track track; Track track;
TrackBits trackbit; TrackBits trackbit;
CommandCost cost = 0; CommandCost cost;
CommandCost ret; CommandCost ret;
if (!ValParamRailtype(p1) || !ValParamTrackOrientation((Track)p2)) return CMD_ERROR; if (!ValParamRailtype(p1) || !ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
@ -263,14 +263,14 @@ CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p
ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile); ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
/* If the rail types don't match, try to convert only if engines of /* If the rail types don't match, try to convert only if engines of
* the present rail type are powered on the new rail type. */ * the present rail type are powered on the new rail type. */
if (GetRailType(tile) != railtype && HasPowerOnRail(GetRailType(tile), railtype)) { if (GetRailType(tile) != railtype && HasPowerOnRail(GetRailType(tile), railtype)) {
ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL); ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
@ -330,11 +330,11 @@ CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p
default: default:
ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile); ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
if (flags & DC_EXEC) MakeRailNormal(tile, _current_player, trackbit, railtype); if (flags & DC_EXEC) MakeRailNormal(tile, _current_player, trackbit, railtype);
break; break;
@ -346,7 +346,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p
YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(tile, track);
} }
return cost + _price.build_rail; return cost.AddCost(_price.build_rail);
} }
/** Remove a single piece of track /** Remove a single piece of track
@ -359,7 +359,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32
{ {
Track track = (Track)p2; Track track = (Track)p2;
TrackBits trackbit; TrackBits trackbit;
CommandCost cost = _price.remove_rail; CommandCost cost(_price.remove_rail);
bool crossing = false; bool crossing = false;
if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR; if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
@ -397,7 +397,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32
/* Charge extra to remove signals on the track, if they are there */ /* Charge extra to remove signals on the track, if they are there */
if (HasSignalOnTrack(tile, track)) if (HasSignalOnTrack(tile, track))
cost += DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS); cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS));
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
present ^= trackbit; present ^= trackbit;
@ -492,7 +492,7 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd
return CMD_ERROR; return CMD_ERROR;
} }
return 0; return CommandCost();
} }
/** Build a stretch of railroad tracks. /** Build a stretch of railroad tracks.
@ -506,7 +506,7 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd
*/ */
static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{ {
CommandCost ret, total_cost = 0; CommandCost ret, total_cost;
Track track = (Track)GB(p2, 4, 3); Track track = (Track)GB(p2, 4, 3);
Trackdir trackdir; Trackdir trackdir;
byte mode = HASBIT(p2, 7); byte mode = HASBIT(p2, 7);
@ -531,7 +531,7 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, u
if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0)) break; if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0)) break;
_error_message = INVALID_STRING_ID; _error_message = INVALID_STRING_ID;
} else { } else {
total_cost += ret; total_cost.AddCost(ret);
} }
if (tile == end_tile) break; if (tile == end_tile) break;
@ -542,7 +542,7 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, u
if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0); if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
} }
return (total_cost == 0) ? CMD_ERROR : total_cost; return (total_cost.GetCost() == 0) ? CMD_ERROR : total_cost;
} }
/** Build rail on a stretch of track. /** Build rail on a stretch of track.
@ -589,7 +589,7 @@ CommandCost CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint
CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{ {
Depot *d; Depot *d;
CommandCost cost, ret; CommandCost cost;
Slope tileh; Slope tileh;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@ -618,9 +618,8 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p
return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
} }
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(cost)) return CMD_ERROR;
cost = ret;
if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
@ -638,7 +637,7 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p
YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir))); YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
} }
return cost + _price.build_train_depot; return cost.AddCost(_price.build_train_depot);
} }
/** Build signals, alternate between double/single, signal/semaphore, /** Build signals, alternate between double/single, signal/semaphore,
@ -687,14 +686,14 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32
if (!HasSignalOnTrack(tile, track)) { if (!HasSignalOnTrack(tile, track)) {
/* build new signals */ /* build new signals */
cost = _price.build_signals; cost = CommandCost(_price.build_signals);
} else { } else {
if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) { if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
/* convert signals <-> semaphores */ /* convert signals <-> semaphores */
cost = _price.build_signals + _price.remove_signals; cost = CommandCost(_price.build_signals + _price.remove_signals);
} else { } else {
/* it is free to change orientation/pre-exit-combo signals */ /* it is free to change orientation/pre-exit-combo signals */
cost = 0; cost = CommandCost();
} }
} }
@ -800,7 +799,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
* signals - is there a signal/semaphore on the first tile, copy its style (two-way/single-way) * signals - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
* and convert all others to semaphore/signal * and convert all others to semaphore/signal
* remove - 1 remove signals, 0 build signals */ * remove - 1 remove signals, 0 build signals */
signal_ctr = total_cost = 0; signal_ctr = 0;
for (;;) { for (;;) {
/* only build/remove signals with the specified density */ /* only build/remove signals with the specified density */
if (signal_ctr % signal_density == 0) { if (signal_ctr % signal_density == 0) {
@ -812,7 +811,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
/* Be user-friendly and try placing signals as much as possible */ /* Be user-friendly and try placing signals as much as possible */
if (CmdSucceeded(ret)) { if (CmdSucceeded(ret)) {
error = false; error = false;
total_cost += ret; total_cost.AddCost(ret);
} }
} }
@ -888,7 +887,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint3
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
return _price.remove_signals; return CommandCost(_price.remove_signals);
} }
/** Remove signals on a stretch of track. /** Remove signals on a stretch of track.
@ -958,7 +957,7 @@ static CommandCost DoConvertRail(TileIndex tile, RailType totype, bool exec)
} }
} }
return _price.build_rail / 2; return CommandCost(_price.build_rail / 2);
} }
extern CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec); extern CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
@ -994,8 +993,6 @@ CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (ey < sy) Swap(ey, sy); if (ey < sy) Swap(ey, sy);
money = GetAvailableMoneyForCommand(); money = GetAvailableMoneyForCommand();
cost = 0;
ret = 0;
for (x = sx; x <= ex; ++x) { for (x = sx; x <= ex; ++x) {
for (y = sy; y <= ey; ++y) { for (y = sy; y <= ey; ++y) {
@ -1012,20 +1009,20 @@ CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
ret = proc(tile, (RailType)p2, false); ret = proc(tile, (RailType)p2, false);
if (CmdFailed(ret)) continue; if (CmdFailed(ret)) continue;
cost += ret;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
money -= ret; money -= ret.GetCost();
if (money < 0) { if (money < 0) {
_additional_cash_required = ret; _additional_cash_required = ret.GetCost();
return cost - ret; return cost;
} }
proc(tile, (RailType)p2, true); proc(tile, (RailType)p2, true);
} }
cost.AddCost(ret);
} }
} }
return (cost == 0) ? ret : cost; return (cost.GetCost() == 0) ? ret : cost;
} }
static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags) static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags)
@ -1044,7 +1041,7 @@ static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags)
YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir))); YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
} }
return _price.remove_train_depot; return CommandCost(_price.remove_train_depot);
} }
static CommandCost ClearTile_Track(TileIndex tile, byte flags) static CommandCost ClearTile_Track(TileIndex tile, byte flags)
@ -1063,8 +1060,6 @@ static CommandCost ClearTile_Track(TileIndex tile, byte flags)
} }
} }
cost = 0;
switch (GetRailTileType(tile)) { switch (GetRailTileType(tile)) {
case RAIL_TILE_SIGNALS: case RAIL_TILE_SIGNALS:
case RAIL_TILE_NORMAL: { case RAIL_TILE_NORMAL: {
@ -1073,7 +1068,7 @@ static CommandCost ClearTile_Track(TileIndex tile, byte flags)
Track track = RemoveFirstTrack(&tracks); Track track = RemoveFirstTrack(&tracks);
ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL); ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
cost += ret; cost.AddCost(ret);
} }
return cost; return cost;
} }

View File

@ -170,7 +170,7 @@ CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (IsTileType(tile, MP_TUNNELBRIDGE)) { if (IsTileType(tile, MP_TUNNELBRIDGE)) {
TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile); TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
/* Pay for *every* tile of the bridge or tunnel */ /* Pay for *every* tile of the bridge or tunnel */
cost = (DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _price.remove_road; cost.AddCost((DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _price.remove_road);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt)); SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt));
SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt)); SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
@ -185,13 +185,13 @@ CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
} }
} else { } else {
cost = _price.remove_road; cost.AddCost(_price.remove_road);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt)); SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
} }
return cost; return CommandCost(cost);
} }
switch (GetRoadTileType(tile)) { switch (GetRoadTileType(tile)) {
@ -232,7 +232,7 @@ CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
} }
return CountRoadBits(c) * _price.remove_road; return CommandCost(CountRoadBits(c) * _price.remove_road);
} }
case ROAD_TILE_CROSSING: { case ROAD_TILE_CROSSING: {
@ -258,7 +258,7 @@ CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile))); YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
} }
return _price.remove_road * 2; return CommandCost(_price.remove_road * 2);
} }
default: default:
@ -320,12 +320,12 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existi
if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) { if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
/* force that all bits are set when we have slopes */ /* force that all bits are set when we have slopes */
if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh]; if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
return 0; // no extra cost return CommandCost(); // no extra cost
} }
/* foundation is used. Whole tile is leveled up */ /* foundation is used. Whole tile is leveled up */
if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) { if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) {
return existing != 0 ? 0 : _price.terraform; return CommandCost(existing != 0 ? 0 : _price.terraform);
} }
/* partly leveled up tile, only if there's no road on that tile */ /* partly leveled up tile, only if there's no road on that tile */
@ -348,7 +348,7 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existi
*/ */
CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{ {
CommandCost cost = 0; CommandCost cost;
CommandCost ret; CommandCost ret;
RoadBits existing = ROAD_NONE; RoadBits existing = ROAD_NONE;
RoadBits all_bits = ROAD_NONE; RoadBits all_bits = ROAD_NONE;
@ -396,7 +396,7 @@ CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
SetDisallowedRoadDirections(tile, GetDisallowedRoadDirections(tile) ^ toggle_drd); SetDisallowedRoadDirections(tile, GetDisallowedRoadDirections(tile) ^ toggle_drd);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
return 0; return CommandCost();
} }
return_cmd_error(STR_1007_ALREADY_BUILT); return_cmd_error(STR_1007_ALREADY_BUILT);
} }
@ -451,7 +451,7 @@ CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2); MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
return _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4); return CommandCost(_price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
} }
case MP_STATION: case MP_STATION:
@ -473,7 +473,7 @@ CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
do_clear:; do_clear:;
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
} }
if (all_bits != pieces) { if (all_bits != pieces) {
@ -481,10 +481,10 @@ do_clear:;
ret = CheckRoadSlope(tileh, &pieces, all_bits | existing); ret = CheckRoadSlope(tileh, &pieces, all_bits | existing);
/* Return an error if we need to build a foundation (ret != 0) but the /* Return an error if we need to build a foundation (ret != 0) but the
* current patch-setting is turned off (or stupid AI@work) */ * current patch-setting is turned off (or stupid AI@work) */
if (CmdFailed(ret) || (ret != 0 && (!_patches.build_on_slopes || _is_old_ai_player))) { if (CmdFailed(ret) || (ret.GetCost() != 0 && (!_patches.build_on_slopes || _is_old_ai_player))) {
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
} }
cost += ret; cost.AddCost(ret);
} }
if (IsTileType(tile, MP_STREET)) { if (IsTileType(tile, MP_STREET)) {
@ -492,10 +492,10 @@ do_clear:;
pieces &= ComplementRoadBits(existing); pieces &= ComplementRoadBits(existing);
} }
cost += CountRoadBits(pieces) * _price.build_road; cost.AddCost(CountRoadBits(pieces) * _price.build_road);
if (IsTileType(tile, MP_TUNNELBRIDGE)) { if (IsTileType(tile, MP_TUNNELBRIDGE)) {
/* Pay for *every* tile of the bridge or tunnel */ /* Pay for *every* tile of the bridge or tunnel */
cost *= DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile); cost.MultiplyCost(DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile));
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
@ -572,7 +572,7 @@ CommandCost DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetCrossingRailBits(tile))); YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetCrossingRailBits(tile)));
} }
return _price.build_rail / 2; return CommandCost(_price.build_rail / 2);
} }
@ -623,7 +623,6 @@ CommandCost CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32
/* No disallowed direction bits have to be toggled */ /* No disallowed direction bits have to be toggled */
if (!HASBIT(p2, 5)) drd = DRD_NONE; if (!HASBIT(p2, 5)) drd = DRD_NONE;
cost = 0;
tile = start_tile; tile = start_tile;
/* Start tile is the small number. */ /* Start tile is the small number. */
for (;;) { for (;;) {
@ -641,11 +640,11 @@ CommandCost CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32
/* Only pay for the upgrade on one side of the bridge */ /* Only pay for the upgrade on one side of the bridge */
if (IsBridgeTile(tile)) { if (IsBridgeTile(tile)) {
if ((!had_bridge || GetBridgeRampDirection(tile) == DIAGDIR_SE || GetBridgeRampDirection(tile) == DIAGDIR_SW)) { if ((!had_bridge || GetBridgeRampDirection(tile) == DIAGDIR_SE || GetBridgeRampDirection(tile) == DIAGDIR_SW)) {
cost += ret; cost.AddCost(ret);
} }
had_bridge = true; had_bridge = true;
} else { } else {
cost += ret; cost.AddCost(ret);
} }
} }
@ -692,7 +691,6 @@ CommandCost CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint3
p2 ^= IS_INT_INSIDE(p2 & 3, 1, 3) ? 3 : 0; p2 ^= IS_INT_INSIDE(p2 & 3, 1, 3) ? 3 : 0;
} }
cost = 0;
tile = start_tile; tile = start_tile;
/* Start tile is the small number. */ /* Start tile is the small number. */
for (;;) { for (;;) {
@ -704,7 +702,7 @@ CommandCost CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint3
/* try to remove the halves. */ /* try to remove the halves. */
if (bits != 0) { if (bits != 0) {
ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD); ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD);
if (CmdSucceeded(ret)) cost += ret; if (CmdSucceeded(ret)) cost.AddCost(ret);
} }
if (tile == end_tile) break; if (tile == end_tile) break;
@ -712,7 +710,7 @@ CommandCost CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint3
tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0); tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
} }
return (cost == 0) ? CMD_ERROR : cost; return (cost.GetCost() == 0) ? CMD_ERROR : cost;
} }
/** Build a road depot. /** Build a road depot.
@ -762,7 +760,7 @@ CommandCost CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
MakeRoadDepot(tile, _current_player, dir, rt); MakeRoadDepot(tile, _current_player, dir, rt);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
return cost + _price.build_road_depot; return cost.AddCost(_price.build_road_depot);
} }
static CommandCost RemoveRoadDepot(TileIndex tile, uint32 flags) static CommandCost RemoveRoadDepot(TileIndex tile, uint32 flags)
@ -774,7 +772,7 @@ static CommandCost RemoveRoadDepot(TileIndex tile, uint32 flags)
if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile)); if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile));
return _price.remove_road_depot; return CommandCost(_price.remove_road_depot);
} }
static CommandCost ClearTile_Road(TileIndex tile, byte flags) static CommandCost ClearTile_Road(TileIndex tile, byte flags)
@ -791,12 +789,12 @@ static CommandCost ClearTile_Road(TileIndex tile, byte flags)
!(flags & DC_AUTO) !(flags & DC_AUTO)
) { ) {
RoadTypes rts = GetRoadTypes(tile); RoadTypes rts = GetRoadTypes(tile);
CommandCost ret = 0; CommandCost ret;
for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
if (HASBIT(rts, rt)) { if (HASBIT(rts, rt)) {
CommandCost tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD); CommandCost tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
if (CmdFailed(tmp_ret)) return tmp_ret; if (CmdFailed(tmp_ret)) return tmp_ret;
ret += tmp_ret; ret.AddCost(tmp_ret);
} }
} }
return ret; return ret;
@ -807,7 +805,7 @@ static CommandCost ClearTile_Road(TileIndex tile, byte flags)
case ROAD_TILE_CROSSING: { case ROAD_TILE_CROSSING: {
RoadTypes rts = GetRoadTypes(tile); RoadTypes rts = GetRoadTypes(tile);
CommandCost ret = 0; CommandCost ret;
if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST); if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
@ -817,7 +815,7 @@ static CommandCost ClearTile_Road(TileIndex tile, byte flags)
if (HASBIT(rts, rt)) { if (HASBIT(rts, rt)) {
CommandCost tmp_ret = DoCommand(tile, 1 << 6 | rt << 4 | GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD); CommandCost tmp_ret = DoCommand(tile, 1 << 6 | rt << 4 | GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
if (CmdFailed(tmp_ret)) return tmp_ret; if (CmdFailed(tmp_ret)) return tmp_ret;
ret += tmp_ret; ret.AddCost(tmp_ret);
} }
} }

View File

@ -118,7 +118,7 @@ void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal)
static CommandCost EstimateRoadVehCost(EngineID engine_type) static CommandCost EstimateRoadVehCost(EngineID engine_type)
{ {
return ((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5; return CommandCost(((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
} }
byte GetRoadVehLength(const Vehicle *v) byte GetRoadVehLength(const Vehicle *v)
@ -219,7 +219,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
v->cargo_subtype = 0; v->cargo_subtype = 0;
v->cargo_cap = rvi->capacity; v->cargo_cap = rvi->capacity;
// v->cargo_count = 0; // v->cargo_count = 0;
v->value = cost; v->value = cost.GetCost();
// v->day_counter = 0; // v->day_counter = 0;
// v->next_order_param = v->next_order = 0; // v->next_order_param = v->next_order = 0;
// v->load_unload_time_rem = 0; // v->load_unload_time_rem = 0;
@ -273,7 +273,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
GetPlayer(_current_player)->num_engines[p1]++; GetPlayer(_current_player)->num_engines[p1]++;
} }
return cost; return CommandCost(cost);
} }
/** Start/Stop a road vehicle. /** Start/Stop a road vehicle.
@ -312,7 +312,7 @@ CommandCost CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
} }
return 0; return CommandCost();
} }
void ClearSlot(Vehicle *v) void ClearSlot(Vehicle *v)
@ -373,7 +373,7 @@ CommandCost CmdSellRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
DeleteVehicle(v); DeleteVehicle(v);
} }
return -(int32)v->value; return CommandCost(-(int32)v->value);
} }
struct RoadFindDepotData { struct RoadFindDepotData {
@ -478,7 +478,7 @@ CommandCost CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint3
TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
@ -492,7 +492,7 @@ CommandCost CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint3
v->current_order.flags = 0; v->current_order.flags = 0;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
dep = FindClosestRoadDepot(v); dep = FindClosestRoadDepot(v);
@ -511,7 +511,7 @@ CommandCost CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint3
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
/** Turn a roadvehicle around. /** Turn a roadvehicle around.
@ -548,7 +548,7 @@ CommandCost CmdTurnRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (flags & DC_EXEC) v->u.road.reverse_ctr = 180; if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
return 0; return CommandCost();
} }
@ -1968,10 +1968,10 @@ void OnNewDay_RoadVeh(Vehicle *v)
cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364; cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
v->profit_this_year -= cost >> 8; v->profit_this_year -= cost.GetCost() >> 8;
SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN); SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
SubtractMoneyFromPlayerFract(v->owner, cost); SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost));
InvalidateWindow(WC_VEHICLE_DETAILS, v->index); InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
InvalidateWindowClasses(WC_ROADVEH_LIST); InvalidateWindowClasses(WC_ROADVEH_LIST);
@ -2060,7 +2060,6 @@ CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
_returned_refit_capacity = capacity; _returned_refit_capacity = capacity;
cost = 0;
if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) { if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
cost = GetRefitCost(v->engine_type); cost = GetRefitCost(v->engine_type);
} }

View File

@ -1782,7 +1782,7 @@ CommandCost CmdChangePatchSetting(TileIndex tile, uint32 flags, uint32 p1, uint3
InvalidateWindow(WC_GAME_OPTIONS, 0); InvalidateWindow(WC_GAME_OPTIONS, 0);
} }
return 0; return CommandCost();
} }
/** Top function to save the new value of an element of the Patches struct /** Top function to save the new value of an element of the Patches struct

View File

@ -261,7 +261,7 @@ CommandCost CmdSetRoadDriveSide(TileIndex tile, uint32 flags, uint32 p1, uint32
_opt_ptr->road_side = p1; _opt_ptr->road_side = p1;
InvalidateWindow(WC_GAME_OPTIONS,0); InvalidateWindow(WC_GAME_OPTIONS,0);
} }
return 0; return CommandCost();
} }
static const Widget _game_options_widgets[] = { static const Widget _game_options_widgets[] = {

View File

@ -188,11 +188,11 @@ void OnNewDay_Ship(Vehicle *v)
if (v->vehstatus & VS_STOPPED) return; if (v->vehstatus & VS_STOPPED) return;
cost = GetVehicleProperty(v, 0x0F, ShipVehInfo(v->engine_type)->running_cost) * _price.ship_running / 364; cost.AddCost(GetVehicleProperty(v, 0x0F, ShipVehInfo(v->engine_type)->running_cost) * _price.ship_running / 364);
v->profit_this_year -= cost >> 8; v->profit_this_year -= cost.GetCost() >> 8;
SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN); SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
SubtractMoneyFromPlayerFract(v->owner, cost); SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost));
InvalidateWindow(WC_VEHICLE_DETAILS, v->index); InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
/* we need this for the profit */ /* we need this for the profit */
@ -405,7 +405,7 @@ static bool ShipAccelerate(Vehicle *v)
static CommandCost EstimateShipCost(EngineID engine_type) static CommandCost EstimateShipCost(EngineID engine_type)
{ {
return GetEngineProperty(engine_type, 0x0A, ShipVehInfo(engine_type)->base_cost) * (_price.ship_base >> 3) >> 5; return CommandCost(GetEngineProperty(engine_type, 0x0A, ShipVehInfo(engine_type)->base_cost) * (_price.ship_base >> 3) >> 5);
} }
static void ShipArrivesAt(const Vehicle* v, Station* st) static void ShipArrivesAt(const Vehicle* v, Station* st)
@ -857,7 +857,7 @@ CommandCost CmdBuildShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
v->cargo_type = svi->cargo_type; v->cargo_type = svi->cargo_type;
v->cargo_subtype = 0; v->cargo_subtype = 0;
v->cargo_cap = svi->capacity; v->cargo_cap = svi->capacity;
v->value = value; v->value = value.GetCost();
v->last_station_visited = INVALID_STATION; v->last_station_visited = INVALID_STATION;
v->max_speed = svi->max_speed; v->max_speed = svi->max_speed;
@ -929,7 +929,7 @@ CommandCost CmdSellShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
DeleteVehicle(v); DeleteVehicle(v);
} }
return -(int32)v->value; return CommandCost(-(int32)v->value);
} }
/** Start/Stop a ship. /** Start/Stop a ship.
@ -968,7 +968,7 @@ CommandCost CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
InvalidateWindowClasses(WC_SHIPS_LIST); InvalidateWindowClasses(WC_SHIPS_LIST);
} }
return 0; return CommandCost();
} }
/** Send a ship to the depot. /** Send a ship to the depot.
@ -1010,7 +1010,7 @@ CommandCost CmdSendShipToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p
TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
@ -1024,7 +1024,7 @@ CommandCost CmdSendShipToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p
v->current_order.flags = 0; v->current_order.flags = 0;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
dep = FindClosestShipDepot(v); dep = FindClosestShipDepot(v);
@ -1042,7 +1042,7 @@ CommandCost CmdSendShipToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
@ -1100,7 +1100,6 @@ CommandCost CmdRefitShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
_returned_refit_capacity = capacity; _returned_refit_capacity = capacity;
cost = 0;
if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) { if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
cost = GetRefitCost(v->engine_type); cost = GetRefitCost(v->engine_type);
} }

View File

@ -147,7 +147,7 @@ CommandCost CmdPlaceSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
_new_sign = si; _new_sign = si;
} }
return 0; return CommandCost();
} }
/** Rename a sign. If the new name of the sign is empty, we assume /** Rename a sign. If the new name of the sign is empty, we assume
@ -201,7 +201,7 @@ CommandCost CmdRenameSign(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
} }
return 0; return CommandCost();
} }
/** /**

View File

@ -618,7 +618,7 @@ static CommandCost ClearTile_Station(TileIndex tile, byte flags);
// Or an error code if it failed. // Or an error code if it failed.
CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station, bool check_clear = true) CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station, bool check_clear = true)
{ {
CommandCost cost = 0; CommandCost cost;
int allowed_z = -1; int allowed_z = -1;
BEGIN_TILE_LOOP(tile_cur, w, h, tile) { BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
@ -653,7 +653,7 @@ CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint
(invalid_dirs & 8 && !(tileh & SLOPE_NW) && (uint)h_cur == h)) { (invalid_dirs & 8 && !(tileh & SLOPE_NW) && (uint)h_cur == h)) {
return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
} }
cost += _price.terraform; cost.AddCost(_price.terraform);
flat_z += TILE_HEIGHT; flat_z += TILE_HEIGHT;
} }
@ -682,7 +682,7 @@ CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint
} else if (check_clear) { } else if (check_clear) {
CommandCost ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR); CommandCost ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
} }
} END_TILE_LOOP(tile_cur, w, h, tile) } END_TILE_LOOP(tile_cur, w, h, tile)
@ -838,7 +838,7 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1,
// for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365 // for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365
ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _patches.nonuniform_stations ? &est : NULL); ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
CommandCost cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len; CommandCost cost(ret.GetCost() + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len);
Station *st = NULL; Station *st = NULL;
bool check_surrounding = true; bool check_surrounding = true;
@ -1121,7 +1121,7 @@ CommandCost CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1
/* If we've not removed any tiles, give an error */ /* If we've not removed any tiles, give an error */
if (quantity == 0) return CMD_ERROR; if (quantity == 0) return CMD_ERROR;
return _price.remove_rail_station * quantity; return CommandCost(_price.remove_rail_station * quantity);
} }
@ -1142,7 +1142,7 @@ static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 fla
assert(w != 0 && h != 0); assert(w != 0 && h != 0);
CommandCost cost = 0; CommandCost cost;
/* clear all areas of the station */ /* clear all areas of the station */
do { do {
int w_bak = w; int w_bak = w;
@ -1151,7 +1151,7 @@ static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 fla
if (st->TileBelongsToRailStation(tile)) { if (st->TileBelongsToRailStation(tile)) {
if (!EnsureNoVehicle(tile)) if (!EnsureNoVehicle(tile))
return CMD_ERROR; return CMD_ERROR;
cost += _price.remove_rail_station; cost.AddCost(_price.remove_rail_station);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
Track track = GetRailStationTrack(tile); Track track = GetRailStationTrack(tile);
DoClearSquare(tile); DoClearSquare(tile);
@ -1211,7 +1211,7 @@ CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec)
YapfNotifyTrackLayoutChange(tile, GetRailStationTrack(tile)); YapfNotifyTrackLayoutChange(tile, GetRailStationTrack(tile));
} }
return _price.build_rail / 2; return CommandCost(_price.build_rail / 2);
} }
/** /**
@ -1267,7 +1267,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR; if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
CommandCost cost = 0; CommandCost cost;
/* Not allowed to build over this road */ /* Not allowed to build over this road */
if (build_over_road) { if (build_over_road) {
@ -1340,7 +1340,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
st->sign.width_1 = 0; st->sign.width_1 = 0;
} }
cost += (type) ? _price.build_truck_station : _price.build_bus_station; cost.AddCost((type) ? _price.build_truck_station : _price.build_bus_station);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
// Insert into linked list of RoadStops // Insert into linked list of RoadStops
@ -1416,7 +1416,7 @@ static CommandCost RemoveRoadStop(Station *st, uint32 flags, TileIndex tile)
DeleteStationIfEmpty(st); DeleteStationIfEmpty(st);
} }
return (is_truck) ? _price.remove_truck_station : _price.remove_bus_station; return CommandCost((is_truck) ? _price.remove_truck_station : _price.remove_bus_station);
} }
/** Remove a bus or truck stop /** Remove a bus or truck stop
@ -1584,7 +1584,7 @@ CommandCost CmdBuildAirport(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
CommandCost ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL); CommandCost ret = CheckFlatLandBelow(tile, w, h, flags, 0, NULL);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
CommandCost cost = ret; CommandCost cost(ret.GetCost());
Station *st = NULL; Station *st = NULL;
@ -1638,7 +1638,7 @@ CommandCost CmdBuildAirport(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
} }
cost += _price.build_airport * w * h; cost.AddCost(_price.build_airport * w * h);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
st->airport_tile = tile; st->airport_tile = tile;
@ -1687,7 +1687,7 @@ static CommandCost RemoveAirport(Station *st, uint32 flags)
int w = afc->size_x; int w = afc->size_x;
int h = afc->size_y; int h = afc->size_y;
CommandCost cost = w * h * _price.remove_airport; CommandCost cost(w * h * _price.remove_airport);
Vehicle *v; Vehicle *v;
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
@ -1769,7 +1769,7 @@ CommandCost CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
st_auto_delete.Release(); st_auto_delete.Release();
} }
return _price.build_dock; return CommandCost(_price.build_dock);
} }
/* Checks if any ship is servicing the buoy specified. Returns yes or no */ /* Checks if any ship is servicing the buoy specified. Returns yes or no */
@ -1821,7 +1821,7 @@ static CommandCost RemoveBuoy(Station *st, uint32 flags)
DeleteStationIfEmpty(st); DeleteStationIfEmpty(st);
} }
return _price.remove_truck_station; return CommandCost(_price.remove_truck_station);
} }
static const TileIndexDiffC _dock_tileoffs_chkaround[] = { static const TileIndexDiffC _dock_tileoffs_chkaround[] = {
@ -1935,7 +1935,7 @@ CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
/* success, so don't delete the new station */ /* success, so don't delete the new station */
st_auto_delete.Release(); st_auto_delete.Release();
} }
return _price.build_dock; return CommandCost(_price.build_dock);
} }
static CommandCost RemoveDock(Station *st, uint32 flags) static CommandCost RemoveDock(Station *st, uint32 flags)
@ -1964,7 +1964,7 @@ static CommandCost RemoveDock(Station *st, uint32 flags)
DeleteStationIfEmpty(st); DeleteStationIfEmpty(st);
} }
return _price.remove_dock; return CommandCost(_price.remove_dock);
} }
#include "table/station_land.h" #include "table/station_land.h"
@ -2516,7 +2516,7 @@ CommandCost CmdRenameStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
DeleteName(str); DeleteName(str);
} }
return 0; return CommandCost();
} }

View File

@ -488,7 +488,7 @@ static CommandCost ClearTile_Town(TileIndex tile, byte flags)
if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED); if (flags&DC_AUTO && !(flags&DC_AI_BUILDING)) return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
if (!CanDeleteHouse(tile)) return CMD_ERROR; if (!CanDeleteHouse(tile)) return CMD_ERROR;
cost = _price.remove_house * hs->removal_cost >> 8; cost.AddCost(_price.remove_house * hs->removal_cost >> 8);
rating = hs->remove_rating_decrease; rating = hs->remove_rating_decrease;
_cleared_town_rating += rating; _cleared_town_rating += rating;
@ -735,7 +735,7 @@ static bool TerraformTownTile(TileIndex tile, int edges, int dir)
TILE_ASSERT(tile); TILE_ASSERT(tile);
r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND); r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND);
if (CmdFailed(r) || r >= 126 * 16) return false; if (CmdFailed(r) || r.GetCost() >= 126 * 16) return false;
DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND); DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND);
return true; return true;
} }
@ -1502,7 +1502,7 @@ CommandCost CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
DoCreateTown(t, tile, townnameparts, (TownSizeMode)p2, p1); DoCreateTown(t, tile, townnameparts, (TownSizeMode)p2, p1);
_generating_world = false; _generating_world = false;
} }
return 0; return CommandCost();
} }
Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size) Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size)
@ -1869,7 +1869,7 @@ CommandCost CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} else { } else {
DeleteName(str); DeleteName(str);
} }
return 0; return CommandCost();
} }
/** Called from GUI */ /** Called from GUI */
@ -2063,7 +2063,7 @@ CommandCost CmdDoTownAction(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
SET_EXPENSES_TYPE(EXPENSES_OTHER); SET_EXPENSES_TYPE(EXPENSES_OTHER);
cost = (_price.build_industry >> 8) * _town_action_costs[p2]; cost.AddCost((_price.build_industry >> 8) * _town_action_costs[p2]);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
_town_action_proc[p2](t); _town_action_proc[p2](t);

View File

@ -507,7 +507,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 fla
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
const RailVehicleInfo *rvi = RailVehInfo(engine); const RailVehicleInfo *rvi = RailVehInfo(engine);
CommandCost value = (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8; CommandCost value((GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8);
uint num_vehicles = 1 + CountArticulatedParts(engine); uint num_vehicles = 1 + CountArticulatedParts(engine);
@ -565,7 +565,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 fla
v->cargo_type = rvi->cargo_type; v->cargo_type = rvi->cargo_type;
v->cargo_subtype = 0; v->cargo_subtype = 0;
v->cargo_cap = rvi->capacity; v->cargo_cap = rvi->capacity;
v->value = value; v->value = value.GetCost();
// v->day_counter = 0; // v->day_counter = 0;
v->u.rail.railtype = rvi->railtype; v->u.rail.railtype = rvi->railtype;
@ -592,7 +592,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 fla
} }
} }
return value; return CommandCost(value);
} }
/** Move all free vehicles in the depot to the train */ /** Move all free vehicles in the depot to the train */
@ -613,7 +613,7 @@ static void NormalizeTrainVehInDepot(const Vehicle* u)
static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi) static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
{ {
return GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5; return CommandCost(GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
} }
static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building) static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
@ -712,7 +712,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32
v->cargo_subtype = 0; v->cargo_subtype = 0;
v->cargo_cap = rvi->capacity; v->cargo_cap = rvi->capacity;
v->max_speed = rvi->max_speed; v->max_speed = rvi->max_speed;
v->value = value; v->value = value.GetCost();
v->last_station_visited = INVALID_STATION; v->last_station_visited = INVALID_STATION;
v->dest_tile = 0; v->dest_tile = 0;
@ -937,7 +937,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
} }
/* don't move the same vehicle.. */ /* don't move the same vehicle.. */
if (src == dst) return 0; if (src == dst) return CommandCost();
/* locate the head of the two chains */ /* locate the head of the two chains */
Vehicle *src_head = GetFirstVehicleInChain(src); Vehicle *src_head = GetFirstVehicleInChain(src);
@ -954,7 +954,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
if (IsMultiheaded(src) && !IsTrainEngine(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR); if (IsMultiheaded(src) && !IsTrainEngine(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
/* when moving all wagons, we can't have the same src_head and dst_head */ /* when moving all wagons, we can't have the same src_head and dst_head */
if (HASBIT(p2, 0) && src_head == dst_head) return 0; if (HASBIT(p2, 0) && src_head == dst_head) return CommandCost();
{ {
int max_len = _patches.mammoth_trains ? 100 : 9; int max_len = _patches.mammoth_trains ? 100 : 9;
@ -1153,7 +1153,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
RebuildVehicleLists(); RebuildVehicleLists();
} }
return 0; return CommandCost();
} }
/** Start/Stop a train. /** Start/Stop a train.
@ -1189,7 +1189,7 @@ CommandCost CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
} }
return 0; return CommandCost();
} }
/** Sell a (single) train wagon/engine. /** Sell a (single) train wagon/engine.
@ -1235,7 +1235,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
RebuildVehicleLists(); RebuildVehicleLists();
} }
CommandCost cost = 0; CommandCost cost;
switch (p2) { switch (p2) {
case 0: case 2: { /* Delete given wagon */ case 0: case 2: { /* Delete given wagon */
bool switch_engine = false; // update second wagon to engine? bool switch_engine = false; // update second wagon to engine?
@ -1247,7 +1247,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL; IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL;
if (rear != NULL) { if (rear != NULL) {
cost -= rear->value; cost.AddCost(-(int64)rear->value);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
UnlinkWagon(rear, first); UnlinkWagon(rear, first);
DeleteDepotHighlightOfVehicle(rear); DeleteDepotHighlightOfVehicle(rear);
@ -1302,7 +1302,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
/* 3. Delete the requested wagon */ /* 3. Delete the requested wagon */
cost -= v->value; cost.AddCost(-v->value);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
first = UnlinkWagon(v, first); first = UnlinkWagon(v, first);
DeleteDepotHighlightOfVehicle(v); DeleteDepotHighlightOfVehicle(v);
@ -1352,7 +1352,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
Vehicle *rear = v->u.rail.other_multiheaded_part; Vehicle *rear = v->u.rail.other_multiheaded_part;
if (rear != NULL) { if (rear != NULL) {
cost -= rear->value; cost.AddCost(-rear->value);
/* If this is a multiheaded vehicle with nothing /* If this is a multiheaded vehicle with nothing
* between the parts, tmp will be pointing to the * between the parts, tmp will be pointing to the
@ -1374,7 +1374,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
} }
cost -= v->value; cost.AddCost(-v->value);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
first = UnlinkWagon(v, first); first = UnlinkWagon(v, first);
DeleteDepotHighlightOfVehicle(v); DeleteDepotHighlightOfVehicle(v);
@ -1656,7 +1656,7 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, uint32 flags, uint32 p1, ui
} }
} }
} }
return 0; return CommandCost();
} }
/** Force a train through a red signal /** Force a train through a red signal
@ -1675,7 +1675,7 @@ CommandCost CmdForceTrainProceed(TileIndex tile, uint32 flags, uint32 p1, uint32
if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50; if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50;
return 0; return CommandCost();
} }
/** Refits a train to the specified cargo type. /** Refits a train to the specified cargo type.
@ -1706,7 +1706,7 @@ CommandCost CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32
SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN); SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
CommandCost cost = 0; CommandCost cost;
uint num = 0; uint num = 0;
do { do {
@ -1755,7 +1755,7 @@ CommandCost CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32
if (amount != 0) { if (amount != 0) {
if (new_cid != v->cargo_type) { if (new_cid != v->cargo_type) {
cost += GetRefitCost(v->engine_type); cost.AddCost(GetRefitCost(v->engine_type));
} }
num += amount; num += amount;
@ -1897,7 +1897,7 @@ CommandCost CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32
TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
@ -1910,7 +1910,7 @@ CommandCost CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32
v->current_order.flags = 0; v->current_order.flags = 0;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
} }
return 0; return CommandCost();
} }
/* check if at a standstill (not stopped only) in a depot /* check if at a standstill (not stopped only) in a depot
@ -1934,7 +1934,7 @@ CommandCost CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32
if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
} }
return 0; return CommandCost();
} }
@ -3389,9 +3389,9 @@ void OnNewDay_Train(Vehicle *v)
if ((v->vehstatus & VS_STOPPED) == 0) { if ((v->vehstatus & VS_STOPPED) == 0) {
/* running costs */ /* running costs */
CommandCost cost = GetTrainRunningCost(v) / 364; CommandCost cost(GetTrainRunningCost(v) / 364);
v->profit_this_year -= cost >> 8; v->profit_this_year -= cost.GetCost() >> 8;
SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN); SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
SubtractMoneyFromPlayerFract(v->owner, cost); SubtractMoneyFromPlayerFract(v->owner, cost);

View File

@ -235,8 +235,6 @@ CommandCost CmdPlantTree(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (ex < sx) Swap(ex, sx); if (ex < sx) Swap(ex, sx);
if (ey < sy) Swap(ey, sy); if (ey < sy) Swap(ey, sy);
cost = 0; // total cost
for (x = sx; x <= ex; x++) { for (x = sx; x <= ex; x++) {
for (y = sy; y <= ey; y++) { for (y = sy; y <= ey; y++) {
TileIndex tile = TileXY(x, y); TileIndex tile = TileXY(x, y);
@ -254,7 +252,7 @@ CommandCost CmdPlantTree(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
/* 2x as expensive to add more trees to an existing tile */ /* 2x as expensive to add more trees to an existing tile */
cost += _price.build_trees * 2; cost.AddCost(_price.build_trees * 2);
break; break;
case MP_CLEAR: case MP_CLEAR:
@ -265,8 +263,8 @@ CommandCost CmdPlantTree(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
switch (GetClearGround(tile)) { switch (GetClearGround(tile)) {
case CLEAR_FIELDS: cost += _price.clear_3; break; case CLEAR_FIELDS: cost.AddCost(_price.clear_3); break;
case CLEAR_ROCKS: cost += _price.clear_2; break; case CLEAR_ROCKS: cost.AddCost(_price.clear_2); break;
default: break; default: break;
} }
@ -297,7 +295,7 @@ CommandCost CmdPlantTree(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (_game_mode == GM_EDITOR && IS_INT_INSIDE(treetype, TREE_RAINFOREST, TREE_CACTUS)) if (_game_mode == GM_EDITOR && IS_INT_INSIDE(treetype, TREE_RAINFOREST, TREE_CACTUS))
SetTropicZone(tile, TROPICZONE_RAINFOREST); SetTropicZone(tile, TROPICZONE_RAINFOREST);
} }
cost += _price.build_trees; cost.AddCost(_price.build_trees);
break; break;
default: default:
@ -307,7 +305,7 @@ CommandCost CmdPlantTree(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
} }
} }
if (cost == 0) { if (cost.GetCost() == 0) {
return_cmd_error(msg); return_cmd_error(msg);
} else { } else {
return cost; return cost;
@ -443,7 +441,7 @@ static CommandCost ClearTile_Trees(TileIndex tile, byte flags)
if (flags & DC_EXEC) DoClearSquare(tile); if (flags & DC_EXEC) DoClearSquare(tile);
return num * _price.remove_trees; return CommandCost(num * _price.remove_trees);
} }
static void GetAcceptedCargo_Trees(TileIndex tile, AcceptedCargo ac) static void GetAcceptedCargo_Trees(TileIndex tile, AcceptedCargo ac)

View File

@ -115,12 +115,12 @@ static CommandCost CheckBridgeSlopeNorth(Axis axis, Slope tileh)
uint32 valid; uint32 valid;
valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_NE) : M(SLOPE_NW)); valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_NE) : M(SLOPE_NW));
if (HASBIT(valid, tileh)) return 0; if (HASBIT(valid, tileh)) return CommandCost();
valid = valid =
BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_N) | M(SLOPE_STEEP_N) | BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_N) | M(SLOPE_STEEP_N) |
(axis == AXIS_X ? M(SLOPE_E) | M(SLOPE_STEEP_E) : M(SLOPE_W) | M(SLOPE_STEEP_W)); (axis == AXIS_X ? M(SLOPE_E) | M(SLOPE_STEEP_E) : M(SLOPE_W) | M(SLOPE_STEEP_W));
if (HASBIT(valid, tileh)) return _price.terraform; if (HASBIT(valid, tileh)) return CommandCost(_price.terraform);
return CMD_ERROR; return CMD_ERROR;
} }
@ -130,12 +130,12 @@ static CommandCost CheckBridgeSlopeSouth(Axis axis, Slope tileh)
uint32 valid; uint32 valid;
valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_SW) : M(SLOPE_SE)); valid = M(SLOPE_FLAT) | (axis == AXIS_X ? M(SLOPE_SW) : M(SLOPE_SE));
if (HASBIT(valid, tileh)) return 0; if (HASBIT(valid, tileh)) return CommandCost();
valid = valid =
BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_S) | M(SLOPE_STEEP_S) | BRIDGE_FULL_LEVELED_FOUNDATION | M(SLOPE_S) | M(SLOPE_STEEP_S) |
(axis == AXIS_X ? M(SLOPE_W) | M(SLOPE_STEEP_W) : M(SLOPE_E) | M(SLOPE_STEEP_E)); (axis == AXIS_X ? M(SLOPE_W) | M(SLOPE_STEEP_W) : M(SLOPE_E) | M(SLOPE_STEEP_E));
if (HASBIT(valid, tileh)) return _price.terraform; if (HASBIT(valid, tileh)) return CommandCost(_price.terraform);
return CMD_ERROR; return CMD_ERROR;
} }
@ -301,7 +301,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p
return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER); return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
} }
cost = (bridge_len + 1) * _price.clear_bridge; // The cost of clearing the current bridge. cost.AddCost((bridge_len + 1) * _price.clear_bridge); // The cost of clearing the current bridge.
replace_bridge = true; replace_bridge = true;
replaced_bridge_type = GetBridgeType(tile_start); replaced_bridge_type = GetBridgeType(tile_start);
@ -316,20 +316,20 @@ CommandCost CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p
cost = ret; cost = ret;
terraformcost = CheckBridgeSlopeNorth(direction, tileh_start); terraformcost = CheckBridgeSlopeNorth(direction, tileh_start);
if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes)) if (CmdFailed(terraformcost) || (terraformcost.GetCost() != 0 && !allow_on_slopes))
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
cost += terraformcost; cost.AddCost(terraformcost);
/* Try and clear the end landscape */ /* Try and clear the end landscape */
ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
/* false - end tile slope check */ /* false - end tile slope check */
terraformcost = CheckBridgeSlopeSouth(direction, tileh_end); terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes)) if (CmdFailed(terraformcost) || (terraformcost.GetCost() != 0 && !allow_on_slopes))
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
cost += terraformcost; cost.AddCost(terraformcost);
} }
if (!replace_bridge) { if (!replace_bridge) {
@ -412,7 +412,7 @@ not_valid_below:;
/* try and clear the middle landscape */ /* try and clear the middle landscape */
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
break; break;
} }
@ -440,7 +440,7 @@ not_valid_below:;
if (IsValidPlayer(_current_player) && !_is_old_ai_player) if (IsValidPlayer(_current_player) && !_is_old_ai_player)
bridge_len = CalcBridgeLenCostFactor(bridge_len); bridge_len = CalcBridgeLenCostFactor(bridge_len);
cost += (int64)bridge_len * _price.build_bridge * b->price >> 8; cost.AddCost((int64)bridge_len * _price.build_bridge * b->price >> 8);
} }
return cost; return cost;
@ -489,7 +489,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
* for the clearing of the entrance of the tunnel. Assigning it to * for the clearing of the entrance of the tunnel. Assigning it to
* cost before the loop will yield different costs depending on start- * cost before the loop will yield different costs depending on start-
* position, because of increased-cost-by-length: 'cost += cost >> 3' */ * position, because of increased-cost-by-length: 'cost += cost >> 3' */
cost = 0;
delta = TileOffsByDiagDir(direction); delta = TileOffsByDiagDir(direction);
end_tile = start_tile; end_tile = start_tile;
for (;;) { for (;;) {
@ -502,13 +502,14 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
return_cmd_error(STR_5003_ANOTHER_TUNNEL_IN_THE_WAY); return_cmd_error(STR_5003_ANOTHER_TUNNEL_IN_THE_WAY);
} }
cost += _price.build_tunnel; cost.AddCost(_price.build_tunnel);
cost += cost >> 3; // add a multiplier for longer tunnels cost.AddCost(cost.GetCost() >> 3); // add a multiplier for longer tunnels
if (cost >= 400000000) cost = 400000000; if (cost.GetCost() >= 400000000) cost.AddCost(400000000 - cost.GetCost());
} }
/* Add the cost of the entrance */ /* Add the cost of the entrance */
cost += _price.build_tunnel + ret; cost.AddCost(_price.build_tunnel);
cost.AddCost(ret);
/* if the command fails from here on we want the end tile to be highlighted */ /* if the command fails from here on we want the end tile to be highlighted */
_build_tunnel_endtile = end_tile; _build_tunnel_endtile = end_tile;
@ -521,7 +522,8 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
} }
cost += _price.build_tunnel + ret; cost.AddCost(_price.build_tunnel);
cost.AddCost(ret);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
if (GB(p1, 9, 1) == TRANSPORT_RAIL) { if (GB(p1, 9, 1) == TRANSPORT_RAIL) {
@ -622,7 +624,7 @@ static CommandCost DoClearTunnel(TileIndex tile, uint32 flags)
YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(tile, track);
YapfNotifyTrackLayoutChange(endtile, track); YapfNotifyTrackLayoutChange(endtile, track);
} }
return _price.clear_tunnel * (length + 1); return CommandCost(_price.clear_tunnel * (length + 1));
} }
@ -695,7 +697,7 @@ static CommandCost DoClearBridge(TileIndex tile, uint32 flags)
YapfNotifyTrackLayoutChange(endtile, track); YapfNotifyTrackLayoutChange(endtile, track);
} }
return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge; return CommandCost((DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge);
} }
static CommandCost ClearTile_TunnelBridge(TileIndex tile, byte flags) static CommandCost ClearTile_TunnelBridge(TileIndex tile, byte flags)
@ -749,7 +751,7 @@ CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec
YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(tile, track);
YapfNotifyTrackLayoutChange(endtile, track); YapfNotifyTrackLayoutChange(endtile, track);
} }
return (length + 1) * (_price.build_rail / 2); return CommandCost((length + 1) * (_price.build_rail / 2));
} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) { } else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
if (!CheckTileOwnership(tile)) return CMD_ERROR; if (!CheckTileOwnership(tile)) return CMD_ERROR;
@ -784,7 +786,7 @@ CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec
} }
} }
return (DistanceManhattan(tile, endtile) + 1) * (_price.build_rail / 2); return CommandCost((DistanceManhattan(tile, endtile) + 1) * (_price.build_rail / 2));
} else { } else {
return CMD_ERROR; return CMD_ERROR;
} }

View File

@ -49,7 +49,7 @@ static CommandCost DestroyCompanyHQ(PlayerID pid, uint32 flags)
} }
/* cost of relocating company is 1% of company value */ /* cost of relocating company is 1% of company value */
return CalculateCompanyValue(p) / 100; return CommandCost((int32)(CalculateCompanyValue(p) / 100));
} }
void UpdateCompanyHQ(Player *p, uint score) void UpdateCompanyHQ(Player *p, uint score)
@ -85,16 +85,14 @@ CommandCost CmdBuildCompanyHQ(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
{ {
Player *p = GetPlayer(_current_player); Player *p = GetPlayer(_current_player);
CommandCost cost; CommandCost cost;
CommandCost ret;
SET_EXPENSES_TYPE(EXPENSES_PROPERTY); SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
ret = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL); cost = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL);
if (CmdFailed(ret)) return ret; if (CmdFailed(cost)) return cost;
cost = ret;
if (p->location_of_house != 0) { // Moving HQ if (p->location_of_house != 0) { // Moving HQ
cost += DestroyCompanyHQ(_current_player, flags); cost.AddCost(DestroyCompanyHQ(_current_player, flags));
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
@ -244,7 +242,7 @@ static CommandCost ClearTile_Unmovable(TileIndex tile, byte flags)
DoClearSquare(tile); DoClearSquare(tile);
} }
return 0; return CommandCost();
} }
static void GetAcceptedCargo_Unmovable(TileIndex tile, AcceptedCargo ac) static void GetAcceptedCargo_Unmovable(TileIndex tile, AcceptedCargo ac)

View File

@ -847,19 +847,19 @@ CargoID FindFirstRefittableCargo(EngineID engine_type)
*/ */
CommandCost GetRefitCost(EngineID engine_type) CommandCost GetRefitCost(EngineID engine_type)
{ {
CommandCost base_cost = 0; CommandCost base_cost;
switch (GetEngine(engine_type)->type) { switch (GetEngine(engine_type)->type) {
case VEH_SHIP: base_cost = _price.ship_base; break; case VEH_SHIP: base_cost.AddCost(_price.ship_base); break;
case VEH_ROAD: base_cost = _price.roadveh_base; break; case VEH_ROAD: base_cost.AddCost(_price.roadveh_base); break;
case VEH_AIRCRAFT: base_cost = _price.aircraft_base; break; case VEH_AIRCRAFT: base_cost.AddCost(_price.aircraft_base); break;
case VEH_TRAIN: case VEH_TRAIN:
base_cost = 2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ? base_cost.AddCost(2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
_price.build_railwagon : _price.build_railvehicle); _price.build_railwagon : _price.build_railvehicle));
break; break;
default: NOT_REACHED(); break; default: NOT_REACHED(); break;
} }
return (EngInfo(engine_type)->refit_cost * base_cost) >> 10; return CommandCost((EngInfo(engine_type)->refit_cost * base_cost.GetCost()) >> 10);
} }
static void DoDrawVehicle(const Vehicle *v) static void DoDrawVehicle(const Vehicle *v)
@ -1726,7 +1726,7 @@ CommandCost CmdMassStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uin
ret = DoCommand(tile, v->index, 0, flags, stop_command); ret = DoCommand(tile, v->index, 0, flags, stop_command);
if (CmdSucceeded(ret)) { if (CmdSucceeded(ret)) {
return_value = 0; return_value = CommandCost();
/* We know that the command is valid for at least one vehicle. /* We know that the command is valid for at least one vehicle.
* If we haven't set DC_EXEC, then there is no point in continueing because it will be valid */ * If we haven't set DC_EXEC, then there is no point in continueing because it will be valid */
if (!(flags & DC_EXEC)) break; if (!(flags & DC_EXEC)) break;
@ -1752,7 +1752,7 @@ CommandCost CmdDepotSellAllVehicles(TileIndex tile, uint32 flags, uint32 p1, uin
uint16 wagon_list_length = 0; uint16 wagon_list_length = 0;
uint16 wagon_count = 0; uint16 wagon_count = 0;
CommandCost cost = 0; CommandCost cost;
uint i, sell_command, total_number_vehicles; uint i, sell_command, total_number_vehicles;
VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8); VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
@ -1781,12 +1781,12 @@ CommandCost CmdDepotSellAllVehicles(TileIndex tile, uint32 flags, uint32 p1, uin
ret = DoCommand(tile, v->index, 1, flags, sell_command); ret = DoCommand(tile, v->index, 1, flags, sell_command);
if (CmdSucceeded(ret)) cost += ret; if (CmdSucceeded(ret)) cost.AddCost(ret);
} }
free(engines); free(engines);
free(wagons); free(wagons);
if (cost == 0) return CMD_ERROR; // no vehicles to sell if (cost.GetCost() == 0) return CMD_ERROR; // no vehicles to sell
return cost; return cost;
} }
@ -1802,7 +1802,7 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uin
uint16 engine_list_length = 0; uint16 engine_list_length = 0;
uint16 engine_count = 0; uint16 engine_count = 0;
uint i, x = 0, y = 0, z = 0; uint i, x = 0, y = 0, z = 0;
CommandCost cost = 0; CommandCost cost;
VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8); VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
@ -1830,7 +1830,7 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uin
ret = MaybeReplaceVehicle(v, !(flags & DC_EXEC), false); ret = MaybeReplaceVehicle(v, !(flags & DC_EXEC), false);
if (CmdSucceeded(ret)) { if (CmdSucceeded(ret)) {
cost += ret; cost.AddCost(ret);
if (!(flags & DC_EXEC)) break; if (!(flags & DC_EXEC)) break;
/* There is a problem with autoreplace and newgrf /* There is a problem with autoreplace and newgrf
* It's impossible to tell the length of a train after it's being replaced before it's actually done * It's impossible to tell the length of a train after it's being replaced before it's actually done
@ -1842,14 +1842,14 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uin
} }
} }
if (cost == 0) { if (cost.GetCost() == 0) {
cost = CMD_ERROR; cost = CMD_ERROR;
} else { } else {
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
/* Display the cost animation now that DoCommandP() can't do it for us (see previous comments) */ /* Display the cost animation now that DoCommandP() can't do it for us (see previous comments) */
if (IsLocalPlayer()) ShowCostOrIncomeAnimation(x, y, z, cost); if (IsLocalPlayer()) ShowCostOrIncomeAnimation(x, y, z, cost.GetCost());
} }
cost = 0; cost = CommandCost();
} }
free(vl); free(vl);
@ -1866,7 +1866,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{ {
Vehicle *v_front, *v; Vehicle *v_front, *v;
Vehicle *w_front, *w, *w_rear; Vehicle *w_front, *w, *w_rear;
CommandCost cost, total_cost = 0; CommandCost cost, total_cost;
uint32 build_argument = 2; uint32 build_argument = 2;
if (!IsValidVehicleID(p1)) return CMD_ERROR; if (!IsValidVehicleID(p1)) return CMD_ERROR;
@ -1914,7 +1914,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (CmdFailed(cost)) return cost; if (CmdFailed(cost)) return cost;
total_cost += cost; total_cost.AddCost(cost);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
w = GetVehicle(_new_vehicle_id); w = GetVehicle(_new_vehicle_id);
@ -1972,7 +1972,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (w->cargo_type != v->cargo_type || w->cargo_subtype != v->cargo_type) { if (w->cargo_type != v->cargo_type || w->cargo_subtype != v->cargo_type) {
cost = DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8) | 1U << 16 , flags, GetCmdRefitVeh(v)); cost = DoCommand(0, w->index, v->cargo_type | (v->cargo_subtype << 8) | 1U << 16 , flags, GetCmdRefitVeh(v));
if (CmdSucceeded(cost)) total_cost += cost; if (CmdSucceeded(cost)) total_cost.AddCost(cost);
} }
if (w->type == VEH_TRAIN && EngineHasArticPart(w)) { if (w->type == VEH_TRAIN && EngineHasArticPart(w)) {
@ -1986,7 +1986,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
CargoID initial_cargo = GetEngineCargoType(v->engine_type); CargoID initial_cargo = GetEngineCargoType(v->engine_type);
if (v->cargo_type != initial_cargo && initial_cargo != CT_INVALID) { if (v->cargo_type != initial_cargo && initial_cargo != CT_INVALID) {
total_cost += GetRefitCost(v->engine_type); total_cost.AddCost(GetRefitCost(v->engine_type));
} }
} }
@ -2242,12 +2242,12 @@ CommandCost SendAllVehiclesToDepot(VehicleType type, uint32 flags, bool service,
* it will succeed at least once. With DC_EXEC we really need to send them to the depot */ * it will succeed at least once. With DC_EXEC we really need to send them to the depot */
if (CmdSucceeded(ret) && !(flags & DC_EXEC)) { if (CmdSucceeded(ret) && !(flags & DC_EXEC)) {
free((void*)sort_list); free((void*)sort_list);
return 0; return CommandCost();
} }
} }
free((void*)sort_list); free((void*)sort_list);
return (flags & DC_EXEC) ? 0 : CMD_ERROR; return (flags & DC_EXEC) ? CommandCost() : CMD_ERROR;
} }
bool IsVehicleInDepot(const Vehicle *v) bool IsVehicleInDepot(const Vehicle *v)
@ -2327,8 +2327,8 @@ void VehicleEnterDepot(Vehicle *v)
SetDParam(1, v->unitnumber); SetDParam(1, v->unitnumber);
AddNewsItem(STR_ORDER_REFIT_FAILED, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0); AddNewsItem(STR_ORDER_REFIT_FAILED, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
} }
} else if (v->owner == _local_player && cost != 0) { } else if (v->owner == _local_player && cost.GetCost() != 0) {
ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost); ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
} }
} }
@ -2386,7 +2386,7 @@ CommandCost CmdNameVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
DeleteName(str); DeleteName(str);
} }
return 0; return CommandCost();
} }
@ -2412,7 +2412,7 @@ CommandCost CmdChangeServiceInt(TileIndex tile, uint32 flags, uint32 p1, uint32
InvalidateWindow(WC_VEHICLE_DETAILS, v->index); InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
} }
return 0; return CommandCost();
} }

View File

@ -346,7 +346,7 @@ static void VehicleRefitWndProc(Window *w, WindowEvent *e)
if (CmdSucceeded(cost)) { if (CmdSucceeded(cost)) {
SetDParam(0, WP(w, refit_d).cargo->cargo); SetDParam(0, WP(w, refit_d).cargo->cargo);
SetDParam(1, _returned_refit_capacity); SetDParam(1, _returned_refit_capacity);
SetDParam(2, cost); SetDParam(2, cost.GetCost());
DrawString(2, w->widget[5].top + 1, STR_9840_NEW_CAPACITY_COST_OF_REFIT, 0); DrawString(2, w->widget[5].top + 1, STR_9840_NEW_CAPACITY_COST_OF_REFIT, 0);
} }
} }

View File

@ -82,9 +82,6 @@ CommandCost CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
ret = DoCommand(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
/* pretend that we're not making land from the water even though we actually are. */
cost = 0;
depot = AllocateDepot(); depot = AllocateDepot();
if (depot == NULL) return CMD_ERROR; if (depot == NULL) return CMD_ERROR;
@ -98,7 +95,7 @@ CommandCost CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
MarkTileDirtyByTile(tile2); MarkTileDirtyByTile(tile2);
} }
return cost + _price.build_ship_depot; return cost.AddCost(_price.build_ship_depot);
} }
static CommandCost RemoveShipDepot(TileIndex tile, uint32 flags) static CommandCost RemoveShipDepot(TileIndex tile, uint32 flags)
@ -123,7 +120,7 @@ static CommandCost RemoveShipDepot(TileIndex tile, uint32 flags)
MarkTileDirtyByTile(tile2); MarkTileDirtyByTile(tile2);
} }
return _price.remove_ship_depot; return CommandCost(_price.remove_ship_depot);
} }
/** build a shiplift */ /** build a shiplift */
@ -164,7 +161,7 @@ static CommandCost DoBuildShiplift(TileIndex tile, DiagDirection dir, uint32 fla
MarkTileDirtyByTile(tile + delta); MarkTileDirtyByTile(tile + delta);
} }
return _price.clear_water * 22 >> 3; return CommandCost(_price.clear_water * 22 >> 3);
} }
static CommandCost RemoveShiplift(TileIndex tile, uint32 flags) static CommandCost RemoveShiplift(TileIndex tile, uint32 flags)
@ -183,7 +180,7 @@ static CommandCost RemoveShiplift(TileIndex tile, uint32 flags)
DoClearSquare(tile - delta); DoClearSquare(tile - delta);
} }
return _price.clear_water * 2; return CommandCost(_price.clear_water * 2);
} }
static void MarkTilesAroundDirty(TileIndex tile) static void MarkTilesAroundDirty(TileIndex tile)
@ -249,7 +246,6 @@ CommandCost CmdBuildCanal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
/* Outside the editor you can only drag canals, and not areas */ /* Outside the editor you can only drag canals, and not areas */
if (_game_mode != GM_EDITOR && (sx != x && sy != y)) return CMD_ERROR; if (_game_mode != GM_EDITOR && (sx != x && sy != y)) return CMD_ERROR;
cost = 0;
BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) { BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
CommandCost ret; CommandCost ret;
@ -262,7 +258,7 @@ CommandCost CmdBuildCanal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
cost += ret; cost.AddCost(ret);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
if (TileHeight(tile) == 0 && HASBIT(p2, 0)) { if (TileHeight(tile) == 0 && HASBIT(p2, 0)) {
@ -274,10 +270,10 @@ CommandCost CmdBuildCanal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
MarkTilesAroundDirty(tile); MarkTilesAroundDirty(tile);
} }
cost += _price.clear_water; cost.AddCost(_price.clear_water);
} END_TILE_LOOP(tile, size_x, size_y, 0); } END_TILE_LOOP(tile, size_x, size_y, 0);
if (cost == 0) { if (cost.GetCost() == 0) {
return_cmd_error(STR_1007_ALREADY_BUILT); return_cmd_error(STR_1007_ALREADY_BUILT);
} else { } else {
return cost; return cost;
@ -302,7 +298,7 @@ static CommandCost ClearTile_Water(TileIndex tile, byte flags)
if (GetTileOwner(tile) != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR; if (GetTileOwner(tile) != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
if (flags & DC_EXEC) DoClearSquare(tile); if (flags & DC_EXEC) DoClearSquare(tile);
return _price.clear_water; return CommandCost(_price.clear_water);
case WATER_TILE_COAST: { case WATER_TILE_COAST: {
Slope slope = GetTileSlope(tile, NULL); Slope slope = GetTileSlope(tile, NULL);
@ -318,9 +314,9 @@ static CommandCost ClearTile_Water(TileIndex tile, byte flags)
if (flags & DC_EXEC) DoClearSquare(tile); if (flags & DC_EXEC) DoClearSquare(tile);
if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) { if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) {
return _price.clear_water; return CommandCost(_price.clear_water);
} else { } else {
return _price.purchase_land; return CommandCost(_price.purchase_land);
} }
} }
@ -343,7 +339,6 @@ static CommandCost ClearTile_Water(TileIndex tile, byte flags)
default: default:
NOT_REACHED(); NOT_REACHED();
return 0;
} }
} }

View File

@ -272,7 +272,7 @@ CommandCost CmdBuildTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint3
YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis)); YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));
} }
return _price.build_train_depot; return CommandCost(_price.build_train_depot);
} }
/** /**
@ -324,7 +324,7 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove)
YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(tile, track);
} }
return _price.remove_train_depot; return CommandCost(_price.remove_train_depot);
} }
/** /**
@ -382,7 +382,7 @@ CommandCost CmdRenameWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} }
} }
return 0; return CommandCost();
} }
/** /**