mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-10-31 15:20:10 +00:00
Add: [Script] Game script control of industry production level.
(cherry picked from commit 1c56991213
)
This commit is contained in:
parent
7839a71d7e
commit
4c6ed36b6a
@ -121,6 +121,7 @@ CommandProc CmdBuildIndustry;
|
||||
CommandProc CmdIndustrySetFlags;
|
||||
CommandProc CmdIndustrySetExclusivity;
|
||||
CommandProc CmdIndustrySetText;
|
||||
CommandProc CmdIndustrySetProduction;
|
||||
|
||||
CommandProc CmdSetCompanyManagerFace;
|
||||
CommandProc CmdSetCompanyColour;
|
||||
@ -385,6 +386,7 @@ static const Command _command_proc_table[] = {
|
||||
DEF_CMD(CmdIndustrySetFlags, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_INDUSTRY_SET_FLAGS
|
||||
DEF_CMD(CmdIndustrySetExclusivity, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_INDUSTRY_SET_EXCLUSIVITY
|
||||
DEF_CMD(CmdIndustrySetText, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_INDUSTRY_SET_TEXT
|
||||
DEF_CMD(CmdIndustrySetProduction, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_INDUSTRY_SET_PRODUCTION
|
||||
|
||||
DEF_CMD(CmdSetCompanyManagerFace, 0, CMDT_OTHER_MANAGEMENT ), // CMD_SET_COMPANY_MANAGER_FACE
|
||||
DEF_CMD(CmdSetCompanyColour, 0, CMDT_OTHER_MANAGEMENT ), // CMD_SET_COMPANY_COLOUR
|
||||
|
@ -351,6 +351,7 @@ enum Commands {
|
||||
CMD_INDUSTRY_SET_FLAGS, ///< change industry control flags
|
||||
CMD_INDUSTRY_SET_EXCLUSIVITY, ///< change industry exclusive consumer/supplier
|
||||
CMD_INDUSTRY_SET_TEXT, ///< change additional text for the industry
|
||||
CMD_INDUSTRY_SET_PRODUCTION, ///< change industry production
|
||||
|
||||
CMD_SET_COMPANY_MANAGER_FACE, ///< set the manager's face of the company
|
||||
CMD_SET_COMPANY_COLOUR, ///< set the colour of the company
|
||||
|
@ -50,8 +50,10 @@ enum IndustryControlFlags : byte {
|
||||
* Industry can not close regardless of production level or time since last delivery.
|
||||
* This does not prevent a closure already announced. */
|
||||
INDCTL_NO_CLOSURE = 1 << 2,
|
||||
/** Indicates that the production level of the industry is externally controlled. */
|
||||
INDCTL_EXTERNAL_PROD_LEVEL = 1 << 3,
|
||||
/** Mask of all flags set */
|
||||
INDCTL_MASK = INDCTL_NO_PRODUCTION_DECREASE | INDCTL_NO_PRODUCTION_INCREASE | INDCTL_NO_CLOSURE,
|
||||
INDCTL_MASK = INDCTL_NO_PRODUCTION_DECREASE | INDCTL_NO_PRODUCTION_INCREASE | INDCTL_NO_CLOSURE | INDCTL_EXTERNAL_PROD_LEVEL,
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(IndustryControlFlags);
|
||||
|
||||
|
@ -66,6 +66,8 @@ IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
|
||||
IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES];
|
||||
IndustryBuildData _industry_builder; ///< In-game manager of industries.
|
||||
|
||||
static int WhoCanServiceIndustry(Industry *ind);
|
||||
|
||||
/**
|
||||
* This function initialize the spec arrays of both
|
||||
* industry and industry tiles.
|
||||
@ -2204,6 +2206,75 @@ CommandCost CmdIndustrySetFlags(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set industry production.
|
||||
* @param flags Type of operation.
|
||||
* @param ind_id IndustryID
|
||||
* @param prod_level Production level.
|
||||
* @param show_news Show a news message on production change.
|
||||
* @return Empty cost or an error.
|
||||
*/
|
||||
CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byte prod_level, bool show_news)
|
||||
{
|
||||
if (_current_company != OWNER_DEITY) return CMD_ERROR;
|
||||
if (prod_level < PRODLEVEL_MINIMUM || prod_level > PRODLEVEL_MAXIMUM) return CMD_ERROR;
|
||||
|
||||
Industry *ind = Industry::GetIfValid(ind_id);
|
||||
if (ind == nullptr) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
StringID str = STR_NULL;
|
||||
if (prod_level > ind->prod_level) {
|
||||
str = GetIndustrySpec(ind->type)->production_up_text;
|
||||
} else if (prod_level < ind->prod_level) {
|
||||
str = GetIndustrySpec(ind->type)->production_down_text;
|
||||
}
|
||||
|
||||
ind->ctlflags |= INDCTL_EXTERNAL_PROD_LEVEL;
|
||||
ind->prod_level = prod_level;
|
||||
ind->RecomputeProductionMultipliers();
|
||||
|
||||
/* Show news message if requested. */
|
||||
if (show_news && str != STR_NULL) {
|
||||
NewsType nt;
|
||||
switch (WhoCanServiceIndustry(ind)) {
|
||||
case 0: nt = NT_INDUSTRY_NOBODY; break;
|
||||
case 1: nt = NT_INDUSTRY_OTHER; break;
|
||||
case 2: nt = NT_INDUSTRY_COMPANY; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
/* Set parameters of news string */
|
||||
if (str > STR_LAST_STRINGID) {
|
||||
SetDParam(0, STR_TOWN_NAME);
|
||||
SetDParam(1, ind->town->index);
|
||||
SetDParam(2, GetIndustrySpec(ind->type)->name);
|
||||
} else {
|
||||
SetDParam(0, ind->index);
|
||||
}
|
||||
AddIndustryNewsItem(str, nt, ind->index);
|
||||
}
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set industry production.
|
||||
* @param tile unused.
|
||||
* @param flags type of operation
|
||||
* @param p1 IndustryID.
|
||||
* @param p2 various bitstuffed elements
|
||||
* - p2 = (bit 0 - 7) - production level
|
||||
* - p2 = (bit 8) - whether to show news
|
||||
* @param text unused.
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdIndustrySetProduction(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
return CmdIndustrySetProduction(flags, (IndustryID)p1, GB(p2, 0, 8), HasBit(p2, 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change exclusive consumer or supplier for the industry.
|
||||
* @param flags Type of operation.
|
||||
@ -2717,7 +2788,7 @@ static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accept
|
||||
* service the industry, and 1 otherwise (only competitors can service the
|
||||
* industry)
|
||||
*/
|
||||
static int WhoCanServiceIndustry(Industry *ind)
|
||||
int WhoCanServiceIndustry(Industry *ind)
|
||||
{
|
||||
if (ind->stations_near.size() == 0) return 0; // No stations found at all => nobody services
|
||||
|
||||
@ -2919,6 +2990,11 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
|
||||
/* If override flags are set, prevent actually changing production if any was decided on */
|
||||
if ((i->ctlflags & INDCTL_NO_PRODUCTION_DECREASE) && (div > 0 || increment < 0)) return;
|
||||
if ((i->ctlflags & INDCTL_NO_PRODUCTION_INCREASE) && (mul > 0 || increment > 0)) return;
|
||||
if (i->ctlflags & INDCTL_EXTERNAL_PROD_LEVEL) {
|
||||
div = 0;
|
||||
mul = 0;
|
||||
increment = 0;
|
||||
}
|
||||
|
||||
if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
|
||||
if ((_cur_year - i->last_prod_year) >= PROCESSING_INDUSTRY_ABANDONMENT_YEARS && Chance16(1, original_economy ? 2 : 180)) {
|
||||
|
@ -78,6 +78,8 @@
|
||||
* \li GSVehicleList_DefaultGroup
|
||||
* \li GSGoal::IsValidGoalDestination
|
||||
* \li GSGoal::SetDestination
|
||||
* \li GSIndustry::GetProductionLevel
|
||||
* \li GSIndustry::SetProductionLevel
|
||||
*
|
||||
* API removals:
|
||||
* \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
|
||||
|
@ -292,3 +292,19 @@
|
||||
::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company);
|
||||
return ScriptObject::DoCommand(0, industry_id, ((uint8)owner), CMD_INDUSTRY_SET_EXCLUSIVITY);
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptIndustry::GetProductionLevel(IndustryID industry_id)
|
||||
{
|
||||
Industry *i = Industry::GetIfValid(industry_id);
|
||||
if (i == nullptr) return 0;
|
||||
return i->prod_level;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptIndustry::SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news)
|
||||
{
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, IsValidIndustry(industry_id));
|
||||
EnforcePrecondition(false, prod_level >= PRODLEVEL_MINIMUM && prod_level <= PRODLEVEL_MAXIMUM);
|
||||
|
||||
return ScriptObject::DoCommand(0, industry_id, ((uint8)prod_level) | (show_news ? (1 << 8) : 0), CMD_INDUSTRY_SET_PRODUCTION);
|
||||
}
|
||||
|
@ -48,6 +48,10 @@ public:
|
||||
* This does not prevent a closure already announced.
|
||||
*/
|
||||
INDCTL_NO_CLOSURE = ::INDCTL_NO_CLOSURE,
|
||||
/**
|
||||
* Indicates that the production level of the industry is controlled by a game script.
|
||||
*/
|
||||
INDCTL_EXTERNAL_PROD_LEVEL = ::INDCTL_EXTERNAL_PROD_LEVEL,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -324,6 +328,27 @@ public:
|
||||
*/
|
||||
static bool SetExclusiveConsumer(IndustryID industry_id, ScriptCompany::CompanyID company_id);
|
||||
|
||||
/**
|
||||
* Gets the current production level of an industry.
|
||||
* @param industry_id The index of the industry.
|
||||
* @api -ai
|
||||
*/
|
||||
static SQInteger GetProductionLevel(IndustryID industry_id);
|
||||
|
||||
/**
|
||||
* Sets the current production level of an industry.
|
||||
* @note Setting the production level automatically sets the control flag INDCTL_EXTERNAL_PROD_LEVEL if it wasn't already set.
|
||||
* Normal production behaviour can be restored by clearing the control flag.
|
||||
* @param industry_id The index of the industry.
|
||||
* @param prod_level The production level to set.
|
||||
* @param show_news If set to true and the production changed, generate a production change news message. If set to false, no news message is shown.
|
||||
* @pre IsValidIndustry(industry_id).
|
||||
* @pre ScriptCompanyMode::IsDeity().
|
||||
* @pre prod_level >= 4 && prod_level <= 128.
|
||||
* @return True if the action succeeded.
|
||||
* @api -ai
|
||||
*/
|
||||
static bool SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news);
|
||||
};
|
||||
|
||||
#endif /* SCRIPT_INDUSTRY_HPP */
|
||||
|
Loading…
Reference in New Issue
Block a user