Add rate limit for object construction

pull/192/head
Jonathan G Rennison 4 years ago
parent f0f5ce5840
commit 2d350d26db

@ -89,6 +89,7 @@ struct CompanyProperties {
uint32 clear_limit; ///< Amount of tiles we can (still) clear (times 65536).
uint32 tree_limit; ///< Amount of trees we can (still) plant (times 65536).
uint32 purchase_land_limit; ///< Amount of tiles we can (still) purchase (times 65536).
uint32 build_object_limit; ///< Amount of tiles we can (still) build objects on (times 65536).
/**
* If \c true, the company is (also) controlled by the computer (a NoAI program).
@ -107,7 +108,7 @@ struct CompanyProperties {
face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0),
location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0),
months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0),
terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), is_ai(false) {}
terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), build_object_limit(0), is_ai(false) {}
};
struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {

@ -66,6 +66,7 @@ Company::Company(uint16 name_1, bool is_ai)
this->clear_limit = _settings_game.construction.clear_frame_burst << 16;
this->tree_limit = _settings_game.construction.tree_frame_burst << 16;
this->purchase_land_limit = _settings_game.construction.purchase_land_frame_burst << 16;
this->build_object_limit = _settings_game.construction.build_object_frame_burst << 16;
for (uint j = 0; j < 4; j++) this->share_owners[j] = COMPANY_SPECTATOR;
InvalidateWindowData(WC_PERFORMANCE_DETAIL, 0, INVALID_COMPANY);
@ -279,6 +280,7 @@ void UpdateLandscapingLimits()
c->clear_limit = min(c->clear_limit + _settings_game.construction.clear_per_64k_frames, (uint32)_settings_game.construction.clear_frame_burst << 16);
c->tree_limit = min(c->tree_limit + _settings_game.construction.tree_per_64k_frames, (uint32)_settings_game.construction.tree_frame_burst << 16);
c->purchase_land_limit = min(c->purchase_land_limit + _settings_game.construction.purchase_land_per_64k_frames, (uint32)_settings_game.construction.purchase_land_frame_burst << 16);
c->build_object_limit = min(c->build_object_limit + _settings_game.construction.build_object_per_64k_frames, (uint32)_settings_game.construction.build_object_frame_burst << 16);
}
}

@ -5561,6 +5561,7 @@ STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... comp
STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Can't purchase this land area...
STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... you already own it!
STR_ERROR_PURCHASE_LAND_LIMIT_REACHED :{WHITE}... land area purchasing limit reached
STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... object construction limit reached
# Group related errors
STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Can't create group...

@ -304,11 +304,13 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
}
int hq_score = 0;
int build_object_size = 0;
Company *c = nullptr;
switch (type) {
case OBJECT_TRANSMITTER:
case OBJECT_LIGHTHOUSE:
if (!IsTileFlat(tile)) return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
build_object_size = 1;
break;
case OBJECT_OWNED_LAND:
@ -344,8 +346,18 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
/* This may never be constructed using this method. */
return CMD_ERROR;
default: // i.e. NewGRF provided.
default: { // i.e. NewGRF provided.
const ObjectSpec *spec = ObjectSpec::Get(type);
build_object_size = GB(spec->size, 0, 4) * GB(spec->size, 4, 4);
break;
}
}
if (build_object_size > 0) {
c = Company::GetIfValid(_current_company);
if (c != nullptr && (int)GB(c->build_object_limit, 16, 16) < build_object_size) {
return_cmd_error(STR_ERROR_BUILD_OBJECT_LIMIT_REACHED);
}
}
if (flags & DC_EXEC) {
@ -355,6 +367,7 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score);
if (type == OBJECT_OWNED_LAND && c != nullptr) c->purchase_land_limit -= 1 << 16;
if (build_object_size > 0 && c != nullptr) c->build_object_limit -= build_object_size << 16;
}
cost.AddCost(ObjectSpec::Get(type)->GetBuildCost() * size_x * size_y);

@ -3750,6 +3750,13 @@ bool AfterLoadGame()
}
}
if (SlXvIsFeatureMissing(XSLFI_BUILD_OBJECT_RATE_LIMIT)) {
/* Introduced build object limit. */
for (Company *c : Company::Iterate()) {
c->build_object_limit = _settings_game.construction.build_object_frame_burst << 16;
}
}
if (SlXvIsFeaturePresent(XSLFI_MORE_COND_ORDERS, 1, 1)) {
for (Order *order : Order::Iterate()) {
// Insertion of OCV_MAX_RELIABILITY between OCV_REMAINING_LIFETIME and OCV_CARGO_WAITING

@ -293,6 +293,7 @@ static const SaveLoad _company_desc[] = {
SLE_CONDVAR(CompanyProperties, clear_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, tree_limit, SLE_UINT32, SLV_175, SL_MAX_VERSION),
SLE_CONDVAR_X(CompanyProperties, purchase_land_limit, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BUY_LAND_RATE_LIMIT)),
SLE_CONDVAR_X(CompanyProperties, build_object_limit, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BUILD_OBJECT_RATE_LIMIT)),
SLE_END()
};

@ -128,6 +128,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_EXTRA_CHEATS, XSCF_NULL, 1, 1, "extra_cheats", nullptr, nullptr, "CHTX" },
{ XSLFI_TOWN_MULTI_BUILDING, XSCF_NULL, 1, 1, "town_multi_building", nullptr, nullptr, nullptr },
{ XSLFI_SHIP_LOST_COUNTER, XSCF_NULL, 1, 1, "ship_lost_counter", nullptr, nullptr, nullptr },
{ XSLFI_BUILD_OBJECT_RATE_LIMIT,XSCF_NULL, 1, 1, "build_object_rate_limit", nullptr, nullptr, nullptr },
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
};

@ -85,6 +85,7 @@ enum SlXvFeatureIndex {
XSLFI_EXTRA_CHEATS, ///< Extra cheats
XSLFI_TOWN_MULTI_BUILDING, ///< Allow multiple stadium/church buildings in a single town
XSLFI_SHIP_LOST_COUNTER, ///< Ship lost counter
XSLFI_BUILD_OBJECT_RATE_LIMIT, ///< Build object rate limit
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk

@ -400,6 +400,8 @@ struct ConstructionSettings {
uint16 tree_frame_burst; ///< how many trees may, over a short period, be planted?
uint32 purchase_land_per_64k_frames; ///< how many tiles may, over a long period, be purchased per 65536 frames?
uint16 purchase_land_frame_burst; ///< how many tiles may, over a short period, be purchased?
uint32 build_object_per_64k_frames; ///< how many tiles may, over a long period, have objects built on them per 65536 frames?
uint16 build_object_frame_burst; ///< how many tiles may, over a short period, have objects built on them?
uint8 tree_growth_rate; ///< tree growth rate
};

@ -651,6 +651,28 @@ interval = 1
cat = SC_EXPERT
patxname = ""buy_land_rate_limit.construction.purchase_land_frame_burst""
[SDT_VAR]
base = GameSettings
var = construction.build_object_per_64k_frames
type = SLE_UINT32
def = 32 << 16
min = 0
max = 1 << 30
interval = 1
cat = SC_EXPERT
patxname = ""build_object_rate_limit.construction.build_object_per_64k_frames""
[SDT_VAR]
base = GameSettings
var = construction.build_object_frame_burst
type = SLE_UINT16
def = 2048
min = 0
max = 1 << 30
interval = 1
cat = SC_EXPERT
patxname = ""build_object_rate_limit.construction.build_object_frame_burst""
[SDT_BOOL]
base = GameSettings
var = construction.autoslope

Loading…
Cancel
Save