Allow building objects by area (1x1 objects only)
Add setting (default on)
This commit is contained in:
@@ -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,15 +415,46 @@ public:
|
||||
|
||||
void OnPlaceObject(Point pt, TileIndex tile) override
|
||||
{
|
||||
DoCommandP(tile, ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index)->Index(),
|
||||
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
|
||||
{
|
||||
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
|
||||
|
Reference in New Issue
Block a user