Index: src/viewport_type.h =================================================================== --- src/viewport_type.h (revision 24122) +++ src/viewport_type.h (working copy) @@ -95,6 +95,7 @@ DDSP_RAISE_AND_LEVEL_AREA, ///< Raise / level area DDSP_LOWER_AND_LEVEL_AREA, ///< Lower / level area DDSP_LEVEL_AREA, ///< Level area + DDSP_BUY_LAND, ///< Buy land DDSP_CREATE_DESERT, ///< Fill area with desert DDSP_CREATE_ROCKS, ///< Fill area with rocks DDSP_CREATE_WATER, ///< Create a canal Index: src/lang/english.txt =================================================================== --- src/lang/english.txt (revision 24122) +++ src/lang/english.txt (working copy) @@ -1117,6 +1117,9 @@ STR_CONFIG_SETTING_BUILDONSLOPES :{LTBLUE}Allow building on slopes and coasts: {ORANGE}{STRING1} STR_CONFIG_SETTING_AUTOSLOPE :{LTBLUE}Allow landscaping under buildings, tracks, etc. (autoslope): {ORANGE}{STRING1} +STR_CONFIG_SETTING_ENABLE_LAND_BUYING :{LTBLUE}Allow buying land: {ORANGE}{STRING1} +STR_CONFIG_SETTING_ENABLE_RESTRICTIVE_LAND_BUYING :{LTBLUE}Enable restriction on drag and drop land buying: {ORANGE}{STRING1} +STR_CONFIG_SETTING_DRAG_DROP_LAND_BUYING_LIMIT :{LTBLUE}Max amount of spaces allowed to buy land at one time: {ORANGE}{STRING1} STR_CONFIG_SETTING_CATCHMENT :{LTBLUE}Allow more realistically sized catchment areas: {ORANGE}{STRING1} STR_CONFIG_SETTING_EXTRADYNAMITE :{LTBLUE}Allow removal of more town-owned roads, bridges and tunnels: {ORANGE}{STRING1} STR_CONFIG_SETTING_TRAIN_LENGTH :{LTBLUE}Maximum length of trains: {ORANGE}{STRING1} tile{P 0:1 "" s} Index: src/settings_gui.cpp =================================================================== --- src/settings_gui.cpp (revision 24122) +++ src/settings_gui.cpp (working copy) @@ -1462,6 +1462,9 @@ SettingEntry(&_settings_construction_signals_page, STR_CONFIG_SETTING_CONSTRUCTION_SIGNALS), SettingEntry("construction.build_on_slopes"), SettingEntry("construction.autoslope"), + SettingEntry("construction.enable_land_buying"), + SettingEntry("construction.enable_restrictive_land_buying"), + SettingEntry("construction.drag_drop_land_buying_limit"), SettingEntry("construction.extra_dynamite"), SettingEntry("construction.max_bridge_length"), SettingEntry("construction.max_tunnel_length"), Index: src/table/settings.ini =================================================================== --- src/table/settings.ini (revision 24122) +++ src/table/settings.ini (working copy) @@ -420,6 +420,31 @@ [SDT_BOOL] base = GameSettings +var = construction.enable_land_buying +from = 175 +def = true +str = STR_CONFIG_SETTING_ENABLE_LAND_BUYING + +[SDT_BOOL] +base = GameSettings +var = construction.enable_restrictive_land_buying +from = 175 +def = true +str = STR_CONFIG_SETTING_ENABLE_RESTRICTIVE_LAND_BUYING + +[SDT_VAR] +base = GameSettings +var = construction.drag_drop_land_buying_limit +type = SLE_UINT8 +from = 175 +min = 1 +max = 64 +interval = 1 +def = 1 +str = STR_CONFIG_SETTING_DRAG_DROP_LAND_BUYING_LIMIT + +[SDT_BOOL] +base = GameSettings var = construction.extra_dynamite def = true str = STR_CONFIG_SETTING_EXTRADYNAMITE Index: src/terraform_gui.cpp =================================================================== --- src/terraform_gui.cpp (revision 24122) +++ src/terraform_gui.cpp (working copy) @@ -121,6 +121,9 @@ case DDSP_LEVEL_AREA: DoCommandP(end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LEVEL_LAND_HERE), CcTerraform); break; + case DDSP_BUY_LAND: + DoCommandP(end_tile, start_tile, _ctrl_pressed ? 1 : 0, CMD_BUY_LAND | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound1E); + break; case DDSP_CREATE_ROCKS: GenerateRockyArea(end_tile, start_tile); break; @@ -142,6 +145,32 @@ { VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_AREA); } +/** + * Start a drag for buying an area. + * @param tile Position of the starting corner. + */ +void PlaceProc_BuyLand(TileIndex tile) +{ + if (_settings_game.construction.enable_land_buying) + { + if (_settings_game.construction.enable_restrictive_land_buying) + { + if (_settings_game.construction.drag_drop_land_buying_limit == 1) // 1x1, we don't need to bother with dragging and dropping, just execute the command like normal + { + DoCommandP(tile, OBJECT_OWNED_LAND, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound1E); + } + else + { + VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUY_LAND); + VpSetPlaceSizingLimit(_settings_game.construction.drag_drop_land_buying_limit); + } + } + else //no limit + { + VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_BUY_LAND); + } + } +} /** Terra form toolbar managing class. */ struct TerraformToolbarWindow : Window { @@ -164,6 +193,7 @@ /* Don't show the place object button when there are no objects to place. */ NWidgetStacked *show_object = this->GetWidget(WID_TT_SHOW_PLACE_OBJECT); show_object->SetDisplayedPlane(ObjectClass::GetCount() != 0 ? 0 : SZSP_NONE); + this->SetWidgetDisabledState(WID_TT_BUY_LAND, _settings_game.construction.enable_land_buying ? false : true); } virtual void OnClick(Point pt, int widget, int click_count) @@ -192,7 +222,7 @@ break; case WID_TT_BUY_LAND: // Buy land button - HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT); + HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT | HT_DIAGONAL); this->last_user_action = widget; break; @@ -254,7 +284,7 @@ break; case WID_TT_BUY_LAND: // Buy land button - DoCommandP(tile, OBJECT_OWNED_LAND, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound1E); + PlaceProc_BuyLand(tile); break; case WID_TT_PLACE_SIGN: // Place sign button @@ -290,6 +320,7 @@ case DDSP_RAISE_AND_LEVEL_AREA: case DDSP_LOWER_AND_LEVEL_AREA: case DDSP_LEVEL_AREA: + case DDSP_BUY_LAND: GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; } @@ -301,6 +332,11 @@ DeleteWindowById(WC_BUILD_OBJECT, 0); this->RaiseButtons(); } + + virtual void OnHundredthTick() + { + this->SetWidgetDisabledState(WID_TT_BUY_LAND, _settings_game.construction.enable_land_buying ? false : true); + } static Hotkey terraform_hotkeys[]; }; Index: src/command.cpp =================================================================== --- src/command.cpp (revision 24122) +++ src/command.cpp (working copy) @@ -48,6 +48,7 @@ CommandProc CmdTerraformLand; CommandProc CmdBuildObject; +CommandProc CmdBuyLand; CommandProc CmdSellLandArea; CommandProc CmdBuildTunnel; @@ -203,6 +204,7 @@ DEF_CMD(CmdRemoveSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SIGNALS DEF_CMD(CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_TERRAFORM_LAND DEF_CMD(CmdBuildObject, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT + DEF_CMD(CmdBuyLand, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUY_LAND DEF_CMD(CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TUNNEL DEF_CMD(CmdRemoveFromRailStation, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_FROM_RAIL_STATION DEF_CMD(CmdConvertRail, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CONVERT_RAILD Index: src/settings_type.h =================================================================== --- src/settings_type.h (revision 24122) +++ src/settings_type.h (working copy) @@ -237,6 +237,9 @@ struct ConstructionSettings { bool build_on_slopes; ///< allow building on slopes bool autoslope; ///< allow terraforming under things + bool enable_land_buying; ///< allow any land buying. + bool enable_restrictive_land_buying; ///< enable restriction on drag and drop land buying. + uint8 drag_drop_land_buying_limit; ///< allow the use of dragging and dropping to buy land. uint16 max_bridge_length; ///< maximum length of bridges uint16 max_tunnel_length; ///< maximum length of tunnels bool signal_side; ///< show signals on right side Index: src/command_type.h =================================================================== --- src/command_type.h (revision 24122) +++ src/command_type.h (working copy) @@ -175,6 +175,7 @@ CMD_REMOVE_SIGNALS, ///< remove a signal CMD_TERRAFORM_LAND, ///< terraform a tile CMD_BUILD_OBJECT, ///< build an object + CMD_BUY_LAND, ///< Buy some land CMD_BUILD_TUNNEL, ///< build a tunnel CMD_REMOVE_FROM_RAIL_STATION, ///< remove a (rectangle of) tiles from a rail station Index: src/saveload/saveload.cpp =================================================================== --- src/saveload/saveload.cpp (revision 24122) +++ src/saveload/saveload.cpp (working copy) @@ -239,7 +239,7 @@ * 173 23967 1.2.0-RC1 * 174 23973 1.2.x */ -extern const uint16 SAVEGAME_VERSION = 174; ///< Current savegame version of OpenTTD. +extern const uint16 SAVEGAME_VERSION = 175; ///< Current savegame version of OpenTTD. SavegameType _savegame_type; ///< type of savegame we are loading Index: src/object_cmd.cpp =================================================================== --- src/object_cmd.cpp (revision 24122) +++ src/object_cmd.cpp (working copy) @@ -336,6 +336,56 @@ return cost; } +/** + * Build an object object + * @param tile end tile of area dragging + * @param flags operations to do + * @param p1 start tile of area dragging + * @param p2 some bit data. + * 1: Orthogonal Iterator 0: Diagonal Iterator + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdBuyLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (p1 >= MapSize()) return CMD_ERROR; + + Money money = GetAvailableMoneyForCommand(); + CommandCost cost(EXPENSES_CONSTRUCTION); + CommandCost last_error = CMD_ERROR; + bool had_success = false; + const Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? NULL : Company::GetIfValid(_current_company); + int limit = (c == NULL) ? INT32_MAX : GB(c->clear_limit, 16, 16); + + TileArea ta(tile, p1); + TileIterator *iter = HasBit(p2, 0) ? (TileIterator*) new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(ta); + + for (; *iter != INVALID_TILE; ++(*iter)) { + TileIndex t = *iter; + CommandCost ret = DoCommand(t, OBJECT_OWNED_LAND, 0, flags & ~DC_EXEC, CMD_BUILD_OBJECT); + if (ret.Failed()) { + last_error = ret; + + if (c != NULL && GB(c->clear_limit, 16, 16) < 1) break; + continue; + } + had_success = true; + if (flags & DC_EXEC) { + money -= ret.GetCost(); + if (ret.GetCost() > 0 && money < 0) { + _additional_cash_required = ret.GetCost(); + delete iter; + return cost; + } + DoCommand(t, OBJECT_OWNED_LAND, 0, flags, CMD_BUILD_OBJECT); + } else { + if(ret.GetCost() != 0 && --limit <= 0) break; + } + cost.AddCost(ret); + } + delete iter; + return had_success ? cost : last_error; +} static Foundation GetFoundation_Object(TileIndex tile, Slope tileh);