Loading

Paste #pispecj9e

  1. /**
  2.  * Build a piece of canal.
  3.  * @param tile end tile of stretch-dragging
  4.  * @param flags type of operation
  5.  * @param p1 start tile of stretch-dragging
  6.  * @param p2 waterclass to build. sea and river can only be built in scenario editor
  7.  * @param text unused
  8.  * @return the cost of this operation or an error
  9.  */
  10. CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
  11. {
  12.     WaterClass wc = Extract<WaterClass, 0, 2>(p2);
  13.     if (p1 >= MapSize() || wc == WATER_CLASS_INVALID) return CMD_ERROR;
  14.  
  15.     /* Outside of the editor you can only build canals, not oceans */
  16.     if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR;
  17.  
  18.     TileArea ta(tile, p1);
  19.  
  20.     /* Outside the editor you can only drag canals, and not areas */
  21.     if (_game_mode != GM_EDITOR && ta.w != 1 && ta.h != 1) return CMD_ERROR;
  22.  
  23.     Axis axis = INVALID_AXIS;
  24.     int delta = 0;
  25.     TileIndex tile_next = min(tile, p1);
  26.     int rem = 1;
  27.     if (ta.w == 1 && ta.h > 1) {
  28.         rem = ta.h;
  29.         axis = AXIS_Y;
  30.     }
  31.     if (ta.w > 1 && ta.h == 1) {
  32.         rem = ta.w;
  33.         axis = AXIS_X;
  34.     }
  35.     if (ta.w > 1 && ta.h > 1) rem = -1;
  36.     if (axis != INVALID_AXIS) delta = TileOffsByDiagDir(AxisToDiagDir(axis));
  37.  
  38.     bool built_lock = false;
  39.     CommandCost cost(EXPENSES_CONSTRUCTION);
  40.     TILE_AREA_LOOP(tile, ta) {
  41.         if (rem > 0) rem--;
  42.         tile_next += delta;
  43.         if (built_lock) {
  44.             built_lock = false;
  45.             continue;
  46.         }
  47.         CommandCost ret;
  48.  
  49.         Slope slope = GetTileSlope(tile);
  50.         Slope slope_next = GetTileSlope(tile_next);
  51. //      if (slope != SLOPE_FLAT && (wc != WATER_CLASS_RIVER || !IsInclinedSlope(slope))) {
  52. //          return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
  53. //      }
  54.  
  55.         if (slope != SLOPE_FLAT && !IsInclinedSlope(slope)) {
  56.             return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
  57.         }
  58.  
  59.         /* can't make water of water! */
  60.         if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || wc == WATER_CLASS_SEA)) continue;
  61.  
  62.        
  63.         bool river = HasTileWaterClass(tile) && GetWaterClass(tile) == WATER_CLASS_RIVER;
  64.         if (rem > 0 && wc == WATER_CLASS_CANAL && slope == SLOPE_FLAT && IsInclinedSlope(slope_next) && DiagDirToAxis(GetInclinedSlopeDirection(slope_next)) == axis) {
  65.             continue;
  66.         } else {
  67.             bool water = IsWaterTile(tile);
  68.             ret = DoCommand(tile, 0, 0, flags | DC_FORCE_CLEAR_TILE, CMD_LANDSCAPE_CLEAR);
  69.             if (ret.Failed()) return ret;
  70.  
  71.             if (!water) cost.AddCost(ret);
  72.         }
  73.  
  74.         /* Try to build a lock on inclined tile. */
  75.         if (rem >= 0) {
  76.             if (wc == WATER_CLASS_CANAL && IsInclinedSlope(slope) && (axis == INVALID_AXIS || DiagDirToAxis(GetInclinedSlopeDirection(slope)) == axis)) {
  77.                 if (rem == 0 && axis == INVALID_AXIS || IsTileFlat(tile + TileOffsByDiagDir(GetInclinedSlopeDirection(slope))) && IsTileFlat(tile - TileOffsByDiagDir(GetInclinedSlopeDirection(slope)))) {
  78.                     /* Mark the tile as already cleared for the lock command.
  79.                      * Do this for all tiles (like trees), not only objects. */
  80.                     ClearedObjectArea *coa = FindClearedObject(tile);
  81.                     if (coa == NULL) {
  82.                         coa = _cleared_object_areas.Append();
  83.                         coa->first_tile = tile;
  84.                         coa->area = TileArea(tile, 1, 1);
  85.                     }
  86.                     /* Hide the tile from the lock command */
  87.                     TileIndex tile_lock_before = coa->first_tile;
  88.                     coa->first_tile = INVALID_TILE;
  89.                     ret = DoCommand(tile, river ? 1 : 0, 0, flags, CMD_BUILD_LOCK);
  90.                     coa->first_tile = tile_lock_before;
  91.                     if (ret.Failed()) return ret;
  92.                     cost.AddCost(ret);
  93.                     built_lock = true;
  94.                 } else {
  95.                     return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
  96.                 }
  97.             } else {
  98.                 if (wc == WATER_CLASS_CANAL && IsInclinedSlope(slope) && axis != INVALID_AXIS && DiagDirToAxis(GetInclinedSlopeDirection(slope)) != axis) {
  99.                     return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
  100.                 } //else {
  101. //                  if (wc == WATER_CLASS_CANAL && rem == 0 && axis == INVALID_AXIS && _game_mode == GM_EDITOR && slope != SLOPE_FLAT) {
  102. //                      return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
  103. //                  }
  104. //              }
  105.             }
  106.         } else {
  107.             if (slope != SLOPE_FLAT && wc != WATER_CLASS_RIVER) {
  108.                 return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
  109.             }
  110.         }
  111.  
  112.         if (flags & DC_EXEC) {
  113.             switch (wc) {
  114.                 case WATER_CLASS_RIVER:
  115.                     MakeRiver(tile, Random());
  116.                     if (_game_mode == GM_EDITOR) {
  117.                         TileIndex tile2 = tile;
  118.                         CircularTileSearch(&tile2, 5, RiverModifyDesertZone, NULL);
  119.                     }
  120.                     break;
  121.  
  122.                 case WATER_CLASS_SEA:
  123.                     if (TileHeight(tile) == 0) {
  124.                         MakeSea(tile);
  125.                         break;
  126.                     }
  127.                     /* FALL THROUGH */
  128.  
  129.                 default:
  130.                     if (!IsInclinedSlope(slope)) {
  131.                         MakeCanal(tile, _current_company, Random());
  132.                         if (river) SetCanalOnRiver(tile);
  133.                         if (Company::IsValidID(_current_company)) {
  134.                             Company::Get(_current_company)->infrastructure.water++;
  135.                             DirtyCompanyInfrastructureWindows(_current_company);
  136.                         }
  137.                     }
  138.                     break;
  139.             }
  140.             MarkTileDirtyByTile(tile);
  141.             MarkCanalsAndRiversAroundDirty(tile);
  142.         }
  143.  
  144.         if (!built_lock) cost.AddCost(_price[PR_BUILD_CANAL]);
  145.     }
  146.  
  147.     if (cost.GetCost() == 0) {
  148.         return_cmd_error(STR_ERROR_ALREADY_BUILT);
  149.     } else {
  150.         return cost;
  151.     }
  152. }

Comments