Allow building objects by area (1x1 objects only)

Add setting (default on)
pull/192/head
Jonathan G Rennison 4 years ago
parent 2d350d26db
commit f44d75eaf5

@ -54,6 +54,7 @@ CommandProc CmdTerraformLand;
CommandProc CmdBuildObject;
CommandProc CmdPurchaseLandArea;
CommandProc CmdBuildObjectArea;
CommandProc CmdBuildHouse;
CommandProc CmdSellLandArea;
@ -294,6 +295,7 @@ static const Command _command_proc_table[] = {
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(CmdPurchaseLandArea, CMD_NO_WATER | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_PURCHASE_LAND_AREA
DEF_CMD(CmdBuildObjectArea, CMD_NO_WATER | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT_AREA
DEF_CMD(CmdBuildHouse, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_HOUSE
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

@ -243,6 +243,7 @@ enum Commands {
CMD_TERRAFORM_LAND, ///< terraform a tile
CMD_BUILD_OBJECT, ///< build an object
CMD_PURCHASE_LAND_AREA, ///< purchase an area of landscape
CMD_BUILD_OBJECT_AREA, ///< build an area of objects
CMD_BUILD_HOUSE, ///< build a house
CMD_BUILD_TUNNEL, ///< build a tunnel

@ -1985,6 +1985,9 @@ STR_CONFIG_SETTING_ALLOW_DOCKS_UNDER_BRIDGES_HELPTEXT :Allow docks und
STR_CONFIG_SETTING_PURCHASE_LAND_PERMITTED :Permit purchasing land: {STRING2}
STR_CONFIG_SETTING_PURCHASE_LAND_PERMITTED_HELPTEXT :Set whether companies are permitted to purchase tiles of land, and in what quantity
STR_CONFIG_SETTING_BUILD_OBJECT_PERMITTED :Permit bulk construction of objects: {STRING2}
STR_CONFIG_SETTING_BUILD_OBJECT_PERMITTED_HELPTEXT :Set whether companies are permitted to construct objects by area, instead of one at a time
STR_PURCHASE_LAND_PERMITTED_NO :No
STR_PURCHASE_LAND_PERMITTED_SINGLE :Yes, 1 tile at a time
STR_PURCHASE_LAND_PERMITTED_AREA :Yes, large areas at a time
@ -1992,6 +1995,8 @@ STR_PURCHASE_LAND_PERMITTED_AREA :Yes, large area
STR_PURCHASE_LAND_NOT_PERMITTED :Purchasing of land is not permitted
STR_PURCHASE_LAND_NOT_PERMITTED_BULK :Purchasing of large areas of land is not permitted
STR_BUILD_OBJECT_NOT_PERMITTED_BULK :Building large areas of objects is not permitted
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Change setting value
STR_CONFIG_SETTING_ADJACENT_CROSSINGS :Close adjacent level crossings: {STRING2}

@ -430,6 +430,71 @@ CommandCost CmdPurchaseLandArea(TileIndex tile, DoCommandFlag flags, uint32 p1,
return had_success ? cost : last_error;
}
/**
* Construct multiple objects in an area
* @param tile end tile of area dragging
* @param flags of operation to conduct
* @param p1 start tile of area dragging
* @param p2 various bitstuffed data.
* - p2 = (bit 0) - Whether to use the Orthogonal (0) or Diagonal (1) iterator.
* - p2 = (bit 1 - 2) - Object view
* - p2 = (bit 3 - 19) - Object type
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdBuildObjectArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (p1 >= MapSize()) return CMD_ERROR;
if (!_settings_game.construction.build_object_area_permitted) return_cmd_error(STR_BUILD_OBJECT_NOT_PERMITTED_BULK);
ObjectType type = (ObjectType)GB(p2, 3, 16);
if (type >= NUM_OBJECTS) return CMD_ERROR;
uint8 view = GB(p2, 1, 2);
const ObjectSpec *spec = ObjectSpec::Get(type);
if (view >= spec->views) return CMD_ERROR;
if (spec->size != 0x11) return CMD_ERROR;
Money money = GetAvailableMoneyForCommand();
CommandCost cost(EXPENSES_CONSTRUCTION);
CommandCost last_error = CMD_ERROR;
bool had_success = false;
const Company *c = Company::GetIfValid(_current_company);
int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16));
TileIterator *iter = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1);
for (; *iter != INVALID_TILE; ++(*iter)) {
TileIndex t = *iter;
CommandCost ret = DoCommand(t, type, view, flags & ~DC_EXEC, CMD_BUILD_OBJECT);
if (ret.Failed()) {
last_error = ret;
/* We may not clear more tiles. */
if (c != nullptr && GB(c->build_object_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, type, view, flags, CMD_BUILD_OBJECT);
} else {
/* When we're at the clearing limit we better bail (unneed) testing as well. */
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);

@ -339,7 +339,7 @@ public:
}
if (_selected_object_index != -1) {
SetObjectToPlaceWnd(SPR_CURSOR_TRANSMITTER, PAL_NONE, HT_RECT, this);
SetObjectToPlaceWnd(SPR_CURSOR_TRANSMITTER, PAL_NONE, HT_RECT | HT_DIAGONAL, this);
}
this->UpdateButtons(_selected_object_class, _selected_object_index, _selected_object_view);
@ -415,8 +415,13 @@ public:
void OnPlaceObject(Point pt, TileIndex tile) override
{
DoCommandP(tile, ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index)->Index(),
_selected_object_view, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform);
const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index);
if (_settings_game.construction.build_object_area_permitted && spec->size == 0x11) {
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_BUILD_OBJECT);
} else {
DoCommandP(tile, spec->Index(),
_selected_object_view, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform);
}
}
void OnPlaceObjectAbort() override
@ -424,6 +429,32 @@ public:
this->UpdateButtons(_selected_object_class, -1, _selected_object_view);
}
void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override
{
VpSelectTilesWithMethod(pt.x, pt.y, select_method);
}
void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override
{
if (pt.x != -1) {
switch (select_proc) {
default: NOT_REACHED();
case DDSP_BUILD_OBJECT:
if (!_settings_game.construction.freeform_edges) {
/* When end_tile is MP_VOID, the error tile will not be visible to the
* user. This happens when terraforming at the southern border. */
if (TileX(end_tile) == MapMaxX()) end_tile += TileDiffXY(-1, 0);
if (TileY(end_tile) == MapMaxY()) end_tile += TileDiffXY(0, -1);
}
DoCommandP(end_tile, start_tile,
(ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index)->Index() << 3) | (_selected_object_view << 1) | (_ctrl_pressed ? 1 : 0),
CMD_BUILD_OBJECT_AREA | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform);
break;
}
}
}
/**
* Select the first available object.
* @param change_class If true, change the class if no object in the current

@ -1872,6 +1872,7 @@ static SettingsContainer &GetSettingsTree()
limitations->Add(new SettingEntry("construction.allow_road_stops_under_bridges"));
limitations->Add(new SettingEntry("construction.allow_docks_under_bridges"));
limitations->Add(new SettingEntry("construction.purchase_land_permitted"));
limitations->Add(new SettingEntry("construction.build_object_area_permitted"));
}
SettingsPage *disasters = main->Add(new SettingsPage(STR_CONFIG_SETTING_ACCIDENTS));

@ -391,6 +391,7 @@ struct ConstructionSettings {
bool allow_road_stops_under_bridges; ///< allow road/tram stops under bridges
bool allow_docks_under_bridges; ///< allow docks under bridges
byte purchase_land_permitted; ///< whether and how purchasing land is permitted
bool build_object_area_permitted; ///< whether building objects by area is permitted
uint32 terraform_per_64k_frames; ///< how many tile heights may, over a long period, be terraformed per 65536 frames?
uint16 terraform_frame_burst; ///< how many tile heights may, over a short period, be terraformed?

@ -1936,6 +1936,14 @@ strhelp = STR_CONFIG_SETTING_PURCHASE_LAND_PERMITTED_HELPTEXT
strval = STR_PURCHASE_LAND_PERMITTED_NO
patxname = ""purchase_land_permitted.construction.purchase_land_permitted""
[SDT_BOOL]
base = GameSettings
var = construction.build_object_area_permitted
def = true
str = STR_CONFIG_SETTING_BUILD_OBJECT_PERMITTED
strhelp = STR_CONFIG_SETTING_BUILD_OBJECT_PERMITTED_HELPTEXT
patxname = ""build_object_area_permitted.construction.build_object_area_permitted""
[SDT_BOOL]
base = GameSettings
var = station.adjacent_stations

@ -177,6 +177,7 @@ enum ViewportDragDropSelectionProcess {
DDSP_MEASURE, ///< Measurement tool
DDSP_DRAW_PLANLINE, ///< Draw a line for a plan
DDSP_BUY_LAND, ///< Purchase land
DDSP_BUILD_OBJECT, ///< Build object
/* Rail specific actions */
DDSP_PLACE_RAIL, ///< Rail placement

Loading…
Cancel
Save