| | 1 | /**
|
---|
| | 2 | * Build a ship depot.
|
---|
| | 3 | * @param tile tile where ship depot is built
|
---|
| | 4 | * @param flags type of operation
|
---|
| | 5 | * @param p1 bit 0 depot orientation (Axis)
|
---|
| | 6 | * @param p2 unused
|
---|
| | 7 | * @param text unused
|
---|
| | 8 | * @return the cost of this operation or an error
|
---|
| | 9 | */
|
---|
| | 10 | CommandCost CmdBuildShipDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
---|
| | 11 | {
|
---|
| | 12 | Axis axis = Extract<Axis, 0, 1>(p1);
|
---|
| | 13 |
|
---|
| | 14 | TileIndex tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
|
---|
| | 15 |
|
---|
| | 16 | if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
|
---|
| | 17 |
|
---|
| | 18 | if (!Depot::CanAllocateItem()) return CMD_ERROR;
|
---|
| | 19 |
|
---|
| | 20 | CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_DEPOT_SHIP]);
|
---|
| | 21 | CommandCost ret;
|
---|
| | 22 |
|
---|
| | 23 | WaterClass wc1 = IsWaterTile(tile) ? GetWaterClass(tile) : WATER_CLASS_CANAL;
|
---|
| | 24 | Owner oc1 = HasTileWaterGround(tile) && GetWaterClass(tile) == WATER_CLASS_CANAL ? GetCanalOwner(tile) : _current_company;
|
---|
| | 25 | bool add_cost1 = !IsWaterTile(tile);
|
---|
| | 26 |
|
---|
| | 27 | /* At this point we got a flat tile with no bridge over it. Check for ownership */
|
---|
| | 28 | if (IsWaterTile(tile) && IsCanal(tile)) {
|
---|
| | 29 | ret = EnsureNoVehicleOnGround(tile);
|
---|
| | 30 | if (ret.Failed()) return ret;
|
---|
| | 31 | if (oc1 != OWNER_NONE) {
|
---|
| | 32 | ret = CheckTileOwnership(tile);
|
---|
| | 33 | if (ret.Failed() && !_settings_game.construction.build_on_competitor_canal) return ret;
|
---|
| | 34 | }
|
---|
| | 35 | } else {
|
---|
| | 36 | ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
---|
| | 37 | if (ret.Failed()) return ret;
|
---|
| | 38 | if (add_cost1) {
|
---|
| | 39 | cost.AddCost(ret);
|
---|
| | 40 | if (wc1 == WATER_CLASS_CANAL) cost.AddCost(_price[PR_BUILD_CANAL]);
|
---|
| | 41 | }
|
---|
| | 42 | }
|
---|
| | 43 |
|
---|
| | 44 | WaterClass wc2 = IsWaterTile(tile2) ? GetWaterClass(tile2) : WATER_CLASS_CANAL;
|
---|
| | 45 | Owner oc2 = HasTileWaterGround(tile2) && GetWaterClass(tile2) == WATER_CLASS_CANAL ? GetCanalOwner(tile2) : _current_company;
|
---|
| | 46 | bool add_cost2 = !IsWaterTile(tile2);
|
---|
| | 47 |
|
---|
| | 48 | /* At this point we got a flat tile2 with no bridge over it. Check for ownership */
|
---|
| | 49 | if (IsWaterTile(tile2) && IsCanal(tile2)) {
|
---|
| | 50 | ret = EnsureNoVehicleOnGround(tile2);
|
---|
| | 51 | if (ret.Failed()) return ret;
|
---|
| | 52 | if (oc2 != OWNER_NONE) {
|
---|
| | 53 | ret = CheckTileOwnership(tile2);
|
---|
| | 54 | if (ret.Failed() && !_settings_game.construction.build_on_competitor_canal) return ret;
|
---|
| | 55 | }
|
---|
| | 56 | } else {
|
---|
| | 57 | ret = DoCommand(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
---|
| | 58 | if (ret.Failed()) return ret;
|
---|
| | 59 | if (add_cost2) {
|
---|
| | 60 | cost.AddCost(ret);
|
---|
| | 61 | if (wc2 == WATER_CLASS_CANAL) cost.AddCost(_price[PR_BUILD_CANAL]);
|
---|
| | 62 | }
|
---|
| | 63 | }
|
---|
| | 64 |
|
---|
12 |
| 72 |
|
---|
13 | /* Forbid these combinations. */
| 73 | /* Forbid these combinations. */
|
---|
14 | if (IsSteepSlope(slope1) || IsSteepSlope(slope2)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
| 74 | if (IsSteepSlope(slope1) || IsSteepSlope(slope2)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
|
---|
15 | if (slope1 == SLOPE_NS && slope2 == SLOPE_EW || slope1 == SLOPE_EW && slope2 == SLOPE_NS) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
| 75 | if (slope1 == SLOPE_NS && slope2 == SLOPE_EW || slope1 == SLOPE_EW && slope2 == SLOPE_NS) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
|
---|
16 | if (z_middle_corner_n != z_middle_corner_s && (IsSlopeWithThreeCornersRaised(slope1) && IsSlopeWithOneCornerRaised(slope2) || IsSlopeWithOneCornerRaised(slope1) && IsSlopeWithThreeCornersRaised(slope2))) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
| 76 | if (z_middle_corner_n != z_middle_corner_s && (IsSlopeWithThreeCornersRaised(slope1) && IsSlopeWithOneCornerRaised(slope2) || IsSlopeWithOneCornerRaised(slope1) && IsSlopeWithThreeCornersRaised(slope2))) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
|
---|
28 | /* Mark the tile as already cleared for the terraform command.
| 28 | /* Mark the tile as already cleared for the terraform command. */
|
---|
29 | * Do this for all tiles (like trees), not only objects. */
| 29 | ClearedObjectArea *coa = MakeClearedObjectArea(slope1 == SLOPE_FLAT ? tile2 : tile, tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
|
---|
30 | ClearedObjectArea *coa = FindClearedObject(slope1 == SLOPE_FLAT ? tile2 : tile);
| 30 | /* Hide the tile from the terraforming command. */
|
---|
31 | if (coa == NULL) {
| | |
---|
32 | coa = _cleared_object_areas.Append();
| | |
---|
33 | coa->first_tile = slope1 == SLOPE_FLAT ? tile2 : tile;
| | |
---|
34 | coa->area = TileArea(tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
| | |
---|
35 | }
| | |
---|
36 | /* Hide the tile from the terraforming command */
| | |
---|
37 | TileIndex tile_flat_before = coa->first_tile;
| 85 | TileIndex tile_flat_before = coa->first_tile;
|
---|
38 | coa->first_tile = INVALID_TILE;
| 86 | coa->first_tile = INVALID_TILE;
|
---|
39 | ret = DoCommand(slope1 == SLOPE_FLAT ? tile2 : tile, slope1 == SLOPE_FLAT ? z_slope1 == z_slope2 ? slope2: ComplementSlope(slope2) : z_slope1 == z_slope2 ? slope1 : ComplementSlope(slope1), z_slope1 == z_slope2 ? 0 : 1, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
| 87 | ret = DoCommand(slope1 == SLOPE_FLAT ? tile2 : tile, slope1 == SLOPE_FLAT ? z_slope1 == z_slope2 ? slope2: ComplementSlope(slope2) : z_slope1 == z_slope2 ? slope1 : ComplementSlope(slope1), z_slope1 == z_slope2 ? 0 : 1, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
|
---|
45 | // int z_middle_corner1 = TileHeight(tile2);
| 45 | /* Mark the tile as already cleared for the terraform command. */
|
---|
46 | // int z_middle_corner2 = TileHeight(TileAddByDiagDir(tile2, AxisToDiagDir(axis == AXIS_X ? AXIS_Y : AXIS_X)));
| 46 | ClearedObjectArea *coa = MakeClearedObjectArea(tile, tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
|
---|
47 |
| 47 | /* Hide the tile from the terraforming command. */
|
---|
48 | /* Mark the tile as already cleared for the terraform command.
| | |
---|
49 | * Do this for all tiles (like trees), not only objects. */
| | |
---|
50 | ClearedObjectArea *coa = FindClearedObject(tile);
| | |
---|
51 | if (coa == NULL) {
| | |
---|
52 | coa = _cleared_object_areas.Append();
| | |
---|
53 | coa->first_tile = tile;
| | |
---|
54 | coa->area = TileArea(tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
| | |
---|
55 | }
| | |
---|
56 | /* Hide the tile from the terraforming command */
| | |
---|
57 | TileIndex tile_3corner1_before = coa->first_tile;
| 96 | TileIndex tile_3corner1_before = coa->first_tile;
|
---|
58 | coa->first_tile = INVALID_TILE;
| 97 | coa->first_tile = INVALID_TILE;
|
---|
59 | ret = DoCommand(tile, IsSlopeWithThreeCornersRaised(slope1) ? ComplementSlope(slope1) : slope1, IsSlopeWithThreeCornersRaised(slope1) ? 1 : 0, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
| 98 | ret = DoCommand(tile, IsSlopeWithThreeCornersRaised(slope1) ? ComplementSlope(slope1) : slope1, IsSlopeWithThreeCornersRaised(slope1) ? 1 : 0, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
|
---|
60 | coa->first_tile = tile_3corner1_before;
| 99 | coa->first_tile = tile_3corner1_before;
|
---|
61 | if (ret.Failed()) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
| 100 | if (ret.Failed()) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
|
---|
62 | cost.AddCost(ret);
| 101 | cost.AddCost(ret);
|
---|
65 | /* Mark the tile as already cleared for the terraform command.
| 65 | /* Mark the tile as already cleared for the terraform command. */
|
---|
66 | * Do this for all tiles (like trees), not only objects. */
| 66 | ClearedObjectArea *coa = MakeClearedObjectArea(tile2, tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
|
---|
67 | ClearedObjectArea *coa = FindClearedObject(tile2);
| 67 | /* Hide the tile from the terraforming command. */
|
---|
68 | if (coa == NULL) {
| | |
---|
69 | coa = _cleared_object_areas.Append();
| | |
---|
70 | coa->first_tile = tile2;
| | |
---|
71 | coa->area = TileArea(tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
| | |
---|
72 | }
| | |
---|
73 | /* Hide the tile from the terraforming command */
| | |
---|
74 | TileIndex tile_3corner2_before = coa->first_tile;
| 106 | TileIndex tile_3corner2_before = coa->first_tile;
|
---|
75 | coa->first_tile = INVALID_TILE;
| 107 | coa->first_tile = INVALID_TILE;
|
---|
76 | ret = DoCommand(tile2, IsSlopeWithThreeCornersRaised(slope2) ? ComplementSlope(slope2) : slope2, IsSlopeWithThreeCornersRaised(slope2) ? 1 : 0, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
| 108 | ret = DoCommand(tile2, IsSlopeWithThreeCornersRaised(slope2) ? ComplementSlope(slope2) : slope2, IsSlopeWithThreeCornersRaised(slope2) ? 1 : 0, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
|
---|
82 | if (IsInclinedSlope(slope1) && (IsSlopeWithOneCornerRaised(slope2) || IsSlopeWithThreeCornersRaised(slope2)) || IsInclinedSlope(slope2) && (IsSlopeWithOneCornerRaised(slope1) || IsSlopeWithThreeCornersRaised(slope1))) {
| 82 | if ((IsInclinedSlope(slope1) && DiagDirToAxis(GetInclinedSlopeDirection(slope1)) == OtherAxis(axis) && (IsSlopeWithOneCornerRaised(slope2) || IsSlopeWithThreeCornersRaised(slope2))) || (IsInclinedSlope(slope2) && DiagDirToAxis(GetInclinedSlopeDirection(slope2)) == OtherAxis(axis) && (IsSlopeWithOneCornerRaised(slope1) || IsSlopeWithThreeCornersRaised(slope1)))) {
|
---|
83 | if ((IsInclinedSlope(slope1) && DiagDirToAxis(GetInclinedSlopeDirection(slope1)) == OtherAxis(axis)) || (IsInclinedSlope(slope2) && DiagDirToAxis(GetInclinedSlopeDirection(slope2)) == OtherAxis(axis))) {
| 83 | /* Mark the tile as already cleared for the terraform command. */
|
---|
84 | if (IsInclinedSlope(slope1)) {
| 84 | ClearedObjectArea *coa = MakeClearedObjectArea(IsInclinedSlope(slope1) ? tile : tile2, tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
|
---|
85 | /* Mark the tile as already cleared for the terraform command.
| 85 | /* Hide the tile from the terraforming command. */
|
---|
86 | * Do this for all tiles (like trees), not only objects. */
| 86 | TileIndex tile_inclined1_before = coa->first_tile;
|
---|
87 | ClearedObjectArea *coa = FindClearedObject(tile);
| 87 | coa->first_tile = INVALID_TILE;
|
---|
88 | if (coa == NULL) {
| 88 | ret = DoCommand(IsInclinedSlope(slope1) ? tile : tile2, IsInclinedSlope(slope1) ? IsSlopeWithThreeCornersRaised(slope2) ? ComplementSlope(slope1) : slope1 : IsSlopeWithThreeCornersRaised(slope1) ? ComplementSlope(slope2) : slope2, IsInclinedSlope(slope1) ? IsSlopeWithThreeCornersRaised(slope2) ? 1 : 0 : IsSlopeWithThreeCornersRaised(slope1) ? 1 : 0, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
|
---|
89 | coa = _cleared_object_areas.Append();
| 89 | coa->first_tile = tile_inclined1_before;
|
---|
90 | coa->first_tile = tile;
| 90 | if (ret.Failed()) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
|
---|
91 | coa->area = TileArea(tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
| 91 | cost.AddCost(ret);
|
---|
92 | }
| | |
---|
93 | /* Hide the tile from the terraforming command */
| | |
---|
94 | TileIndex tile_inclined1_before = coa->first_tile;
| | |
---|
95 | coa->first_tile = INVALID_TILE;
| | |
---|
96 | ret = DoCommand(tile, IsSlopeWithThreeCornersRaised(slope2) ? ComplementSlope(slope1) : slope1, IsSlopeWithThreeCornersRaised(slope2) ? 1 : 0, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
| | |
---|
97 | coa->first_tile = tile_inclined1_before;
| | |
---|
98 | if (ret.Failed()) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
| | |
---|
99 | cost.AddCost(ret);
| | |
---|
100 | } else {
| | |
---|
101 | /* Mark the tile as already cleared for the terraform command.
| | |
---|
102 | * Do this for all tiles (like trees), not only objects. */
| | |
---|
103 | ClearedObjectArea *coa = FindClearedObject(tile2);
| | |
---|
104 | if (coa == NULL) {
| | |
---|
105 | coa = _cleared_object_areas.Append();
| | |
---|
106 | coa->first_tile = tile2;
| | |
---|
107 | coa->area = TileArea(tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
| | |
---|
108 | }
| | |
---|
109 | /* Hide the tile from the terraforming command */
| | |
---|
110 | TileIndex tile_inclined2_before = coa->first_tile;
| | |
---|
111 | coa->first_tile = INVALID_TILE;
| | |
---|
112 | ret = DoCommand(tile2, IsSlopeWithThreeCornersRaised(slope1) ? ComplementSlope(slope2) : slope2, IsSlopeWithThreeCornersRaised(slope1) ? 1 : 0, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
| | |
---|
113 | coa->first_tile = tile_inclined2_before;
| | |
---|
114 | if (ret.Failed()) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
| | |
---|
115 | cost.AddCost(ret);
| | |
---|
116 | }
| | |
---|
117 | }
| | |
---|
120 | /* Mark the tile as already cleared for the terraform command.
| 120 | /* Mark the tile as already cleared for the terraform command. */
|
---|
121 | * Do this for all tiles (like trees), not only objects. */
| 121 | ClearedObjectArea *coa = MakeClearedObjectArea((slope1 == SLOPE_EW || slope1 == SLOPE_NS), tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
|
---|
122 | ClearedObjectArea *coa = FindClearedObject((slope1 == SLOPE_EW || slope1 == SLOPE_NS) ? tile : tile2);
| 122 | /* Hide the tile from the terraforming command. */
|
---|
123 | if (coa == NULL) {
| | |
---|
124 | coa = _cleared_object_areas.Append();
| | |
---|
125 | coa->first_tile = (slope1 == SLOPE_EW || slope1 == SLOPE_NS) ? tile : tile2;
| | |
---|
126 | coa->area = TileArea(tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
| | |
---|
127 | }
| | |
---|
128 | /* Hide the tile from the terraforming command */
| | |
---|
129 | TileIndex tile_oppositecorners_before = coa->first_tile;
| 129 | TileIndex tile_oppositecorners_before = coa->first_tile;
|
---|
130 | coa->first_tile = INVALID_TILE;
| 130 | coa->first_tile = INVALID_TILE;
|
---|
131 | ret = DoCommand((slope1 == SLOPE_EW || slope1 == SLOPE_NS) ? tile : tile2, (slope1 == SLOPE_EW || slope1 == SLOPE_NS) ? IsSlopeWithOneCornerRaised(slope2) ? slope1 : ComplementSlope(slope1) : IsSlopeWithOneCornerRaised(slope1) ? slope2 : ComplementSlope(slope2), (slope1 == SLOPE_EW || slope1 == SLOPE_NS) ? IsSlopeWithOneCornerRaised(slope2) ? 0 : 1 : IsSlopeWithOneCornerRaised(slope1) ? 0 : 1, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
| 131 | ret = DoCommand((slope1 == SLOPE_EW || slope1 == SLOPE_NS) ? tile : tile2, (slope1 == SLOPE_EW || slope1 == SLOPE_NS) ? IsSlopeWithOneCornerRaised(slope2) ? slope1 : ComplementSlope(slope1) : IsSlopeWithOneCornerRaised(slope1) ? slope2 : ComplementSlope(slope2), (slope1 == SLOPE_EW || slope1 == SLOPE_NS) ? IsSlopeWithOneCornerRaised(slope2) ? 0 : 1 : IsSlopeWithOneCornerRaised(slope1) ? 0 : 1, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
|
---|
136 | /* Shouldn't reach here. */
| 136 | if (slope1 == ComplementSlope(slope2) && IsInclinedSlope(slope1)) {
|
---|
137 | assert(false);
| 137 | /* Mark the tile as already cleared for the terraform command. */
|
---|
| | 138 | ClearedObjectArea *coa = MakeClearedObjectArea(tile, tile, axis == AXIS_X ? 2 : 1, axis == AXIS_Y ? 2 : 1);
|
---|
| | 139 | /* Hide the tile from the terraforming command. */
|
---|
| | 140 | TileIndex tile_complement_before = coa->first_tile;
|
---|
| | 141 | coa->first_tile = INVALID_TILE;
|
---|
| | 142 | ret = DoCommand(tile, z_slope1 > z_slope2 ? slope2 : slope1, z_slope1 > z_slope2 ? 1 : 0, flags | DC_NO_WATER, CMD_TERRAFORM_LAND);
|
---|
| | 143 | coa->first_tile = tile_complement_before;
|
---|
| | 144 | if (ret.Failed()) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
|
---|
| | 145 | cost.AddCost(ret);
|
---|
| | 146 | } else {
|
---|
| | 147 | /* Shouldn't reach here. */
|
---|
| | 148 | assert(false);
|
---|
| | 149 | }
|
---|
142 | } | 154 | }
|
---|
| | 155 |
|
---|
| | 156 | if (flags & DC_EXEC) {
|
---|
| | 157 | Depot *depot = new Depot(tile);
|
---|
| | 158 | depot->build_date = _date;
|
---|
| | 159 |
|
---|
| | 160 | if (add_cost1 && wc1 == WATER_CLASS_CANAL) Company::Get(_current_company)->infrastructure.water++;
|
---|
| | 161 | if (add_cost2 && wc2 == WATER_CLASS_CANAL) Company::Get(_current_company)->infrastructure.water++;
|
---|
| | 162 | Company::Get(_current_company)->infrastructure.water += 2 * LOCK_DEPOT_TILE_FACTOR;
|
---|
| | 163 | DirtyCompanyInfrastructureWindows(_current_company);
|
---|
| | 164 |
|
---|
| | 165 | MakeShipDepot(tile, _current_company, oc1, depot->index, DEPOT_PART_NORTH, axis, wc1);
|
---|
| | 166 | MakeShipDepot(tile2, _current_company, oc2, depot->index, DEPOT_PART_SOUTH, axis, wc2);
|
---|
| | 167 | MarkTileDirtyByTile(tile);
|
---|
| | 168 | MarkTileDirtyByTile(tile2);
|
---|
| | 169 | MakeDefaultName(depot);
|
---|
| | 170 | }
|
---|
| | 171 |
|
---|
| | 172 | return cost;
|
---|
| | 173 | } |
---|