Changeset - r24481:a5bae7e5e10a
[Not reviewed]
master
0 11 0
Niels Martin Hansen - 3 years ago 2020-12-22 13:21:31
nielsm@indvikleren.dk
Feature: Influence industry production changes from GS (#7912)
11 files changed with 185 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/command.cpp
Show inline comments
 
@@ -97,6 +97,7 @@ CommandProc CmdInsertOrder;
 
CommandProc CmdChangeServiceInt;
 

	
 
CommandProc CmdBuildIndustry;
 
CommandProc CmdIndustryCtrl;
 

	
 
CommandProc CmdSetCompanyManagerFace;
 
CommandProc CmdSetCompanyColour;
 
@@ -265,6 +266,8 @@ static const Command _command_proc_table
 
	DEF_CMD(CmdChangeServiceInt,                               0, CMDT_VEHICLE_MANAGEMENT    ), // CMD_CHANGE_SERVICE_INT
 

	
 
	DEF_CMD(CmdBuildIndustry,                          CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_INDUSTRY
 
	DEF_CMD(CmdIndustryCtrl,                           CMD_DEITY, CMDT_OTHER_MANAGEMENT      ), // CMD_INDUSTRY_CTRL
 

	
 
	DEF_CMD(CmdSetCompanyManagerFace,                          0, CMDT_OTHER_MANAGEMENT      ), // CMD_SET_COMPANY_MANAGER_FACE
 
	DEF_CMD(CmdSetCompanyColour,                               0, CMDT_OTHER_MANAGEMENT      ), // CMD_SET_COMPANY_COLOUR
 

	
src/command_type.h
Show inline comments
 
@@ -230,6 +230,7 @@ enum Commands {
 
	CMD_CHANGE_SERVICE_INT,           ///< change the server interval of a vehicle
 

	
 
	CMD_BUILD_INDUSTRY,               ///< build a new industry
 
	CMD_INDUSTRY_CTRL,                ///< change industry properties
 

	
 
	CMD_SET_COMPANY_MANAGER_FACE,     ///< set the manager's face of the company
 
	CMD_SET_COMPANY_COLOUR,           ///< set the colour of the company
src/industry.h
Show inline comments
 
@@ -35,6 +35,26 @@ enum ProductionLevels {
 
};
 

	
 
/**
 
 * Flags to control/override the behaviour of an industry.
 
 * These flags are controlled by game scripts.
 
 */
 
enum IndustryControlFlags : byte {
 
	/** No flags in effect */
 
	INDCTL_NONE                   = 0,
 
	/** When industry production change is evaluated, rolls to decrease are ignored. */
 
	INDCTL_NO_PRODUCTION_DECREASE = 1 << 0,
 
	/** When industry production change is evaluated, rolls to increase are ignored. */
 
	INDCTL_NO_PRODUCTION_INCREASE = 1 << 1,
 
	/**
 
	 * 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,
 
	/** Mask of all flags set */
 
	INDCTL_MASK = INDCTL_NO_PRODUCTION_DECREASE | INDCTL_NO_PRODUCTION_INCREASE | INDCTL_NO_CLOSURE,
 
};
 
DECLARE_ENUM_AS_BIT_SET(IndustryControlFlags);
 

	
 
/**
 
 * Defines the internal data of a functional industry.
 
 */
 
struct Industry : IndustryPool::PoolItem<&_industry_pool> {
 
@@ -59,6 +79,7 @@ struct Industry : IndustryPool::PoolItem
 
	byte random_colour;            ///< randomized colour of the industry, for display purpose
 
	Year last_prod_year;           ///< last year of production
 
	byte was_cargo_delivered;      ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry
 
	IndustryControlFlags ctlflags; ///< flags overriding standard behaviours
 

	
 
	PartOfSubsidy part_of_subsidy; ///< NOSAVE: is this industry a source/destination of a subsidy?
 
	StationList stations_near;     ///< NOSAVE: List of nearby stations.
src/industry_cmd.cpp
Show inline comments
 
@@ -1753,6 +1753,7 @@ static void DoCreateNewIndustry(Industry
 
	i->was_cargo_delivered = false;
 
	i->last_prod_year = _cur_year;
 
	i->founder = founder;
 
	i->ctlflags = INDCTL_NONE;
 

	
 
	i->construction_date = _date;
 
	i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
 
@@ -2049,6 +2050,43 @@ CommandCost CmdBuildIndustry(TileIndex t
 
	return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
 
}
 

	
 
/**
 
 * Change industry properties
 
 * @param tile Unused.
 
 * @param flags Type of operation.
 
 * @param p1 IndustryID
 
 * @param p2 various bitstuffed elements
 
 * - p2 = (bit 0 - 7) - action to perform:
 
 *                      0 = set control flags
 
 * - p2 = (bit 8 - 15) - IndustryControlFlags
 
 *                       (only used with set control flags)
 
 * @param text unused
 
 * @return Empty cost or an error.
 
 */
 
CommandCost CmdIndustryCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	if (_current_company != OWNER_DEITY) return CMD_ERROR;
 

	
 
	Industry *ind = Industry::GetIfValid(p1);
 
	if (ind == nullptr) return CMD_ERROR;
 

	
 
	uint8 action = GB(p2, 0, 8);
 

	
 
	switch (action) {
 
		case 0: {
 
			IndustryControlFlags ctlflags = (IndustryControlFlags)GB(p2, 8, 8) & INDCTL_MASK;
 

	
 
			if (flags & DC_EXEC) ind->ctlflags = ctlflags;
 

	
 
			break;
 
		}
 

	
 
		default:
 
			NOT_REACHED();
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/**
 
 * Create a new industry of random layout.
 
@@ -2659,7 +2697,7 @@ static void ChangeIndustryProduction(Ind
 
				}
 
			}
 
		} else if (_settings_game.economy.type == ET_SMOOTH) {
 
			closeit = true;
 
			closeit = !(i->ctlflags & (INDCTL_NO_CLOSURE | INDCTL_NO_PRODUCTION_DECREASE));
 
			for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
 
				if (i->produced_cargo[j] == CT_INVALID) continue;
 
				uint32 r = Random();
 
@@ -2692,6 +2730,10 @@ static void ChangeIndustryProduction(Ind
 
					new_prod = Clamp(new_prod, 0, 16);
 
				}
 

	
 
				/* If override flags are set, prevent actually changing production if any was decided on */
 
				if ((i->ctlflags & INDCTL_NO_PRODUCTION_DECREASE) && new_prod < old_prod) continue;
 
				if ((i->ctlflags & INDCTL_NO_PRODUCTION_INCREASE) && new_prod > old_prod) continue;
 

	
 
				/* Do not stop closing the industry when it has the lowest possible production rate */
 
				if (new_prod == old_prod && old_prod > 1) {
 
					closeit = false;
 
@@ -2711,6 +2753,10 @@ static void ChangeIndustryProduction(Ind
 
		}
 
	}
 

	
 
	/* 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 (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
 
		if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, original_economy ? 2 : 180)) {
 
			closeit = true;
 
@@ -2728,6 +2774,7 @@ static void ChangeIndustryProduction(Ind
 
	while (div-- != 0 && !closeit) {
 
		if (i->prod_level == PRODLEVEL_MINIMUM) {
 
			closeit = true;
 
			break;
 
		} else {
 
			i->prod_level = max(i->prod_level / 2, (int)PRODLEVEL_MINIMUM); // typecast to int required to please MSVC
 
			recalculate_multipliers = true;
 
@@ -2750,7 +2797,7 @@ static void ChangeIndustryProduction(Ind
 
	if (recalculate_multipliers) i->RecomputeProductionMultipliers();
 

	
 
	/* Close if needed and allowed */
 
	if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
 
	if (closeit && !CheckIndustryCloseDownProtection(i->type) && !(i->ctlflags & INDCTL_NO_CLOSURE)) {
 
		i->prod_level = PRODLEVEL_CLOSURE;
 
		SetWindowDirty(WC_INDUSTRY_VIEW, i->index);
 
		str = indspec->closure_text;
src/newgrf_industries.cpp
Show inline comments
 
@@ -248,6 +248,9 @@ static uint32 GetCountAndDistanceOfClose
 

	
 
		case 0x46: return this->industry->construction_date; // Date when built - long format - (in days)
 

	
 
		/* Override flags from GS */
 
		case 0x47: return this->industry->ctlflags;
 

	
 
		/* Get industry ID at offset param */
 
		case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, this->industry->location.tile, false), this->industry, this->ro.grffile->grfid);
 

	
src/saveload/industry_sl.cpp
Show inline comments
 
@@ -56,6 +56,7 @@ static const SaveLoad _industry_desc[] =
 
	SLE_CONDVAR(Industry, last_prod_year,             SLE_FILE_U8 | SLE_VAR_I32,  SL_MIN_VERSION, SLV_31),
 
	SLE_CONDVAR(Industry, last_prod_year,             SLE_INT32,                 SLV_31, SL_MAX_VERSION),
 
	    SLE_VAR(Industry, was_cargo_delivered,        SLE_UINT8),
 
	SLE_CONDVAR(Industry, ctlflags,                   SLE_UINT8,                 SLV_GS_INDUSTRY_CONTROL, SL_MAX_VERSION),
 

	
 
	SLE_CONDVAR(Industry, founder,                    SLE_UINT8,                 SLV_70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, construction_date,          SLE_INT32,                 SLV_70, SL_MAX_VERSION),
src/saveload/saveload.h
Show inline comments
 
@@ -320,6 +320,8 @@ enum SaveLoadVersion : uint16 {
 
	SLV_START_PATCHPACKS,                   ///< 220  First known patchpack to use a version just above ours.
 
	SLV_END_PATCHPACKS = 286,               ///< 286  Last known patchpack to use a version just above ours.
 

	
 
	SLV_GS_INDUSTRY_CONTROL,                ///< 287  PR#7912 GS industry control.
 

	
 
	SL_MAX_VERSION,                         ///< Highest possible saveload version
 
};
 

	
src/script/api/game_changelog.hpp
Show inline comments
 
@@ -21,6 +21,10 @@
 
 * \li GSEventStoryPageButtonClick
 
 * \li GSEventStoryPageTileSelect
 
 * \li GSEventStoryPageVehicleSelect
 
 * \li GSIndustry::GetCargoLastAcceptedDate
 
 * \li GSIndustry::GetControlFlags
 
 * \li GSIndustry::GetLastProductionYear
 
 * \li GSIndustry::SetControlFlags
 
 * \li GSStoryPage::MakePushButtonReference
 
 * \li GSStoryPage::MakeTileButtonReference
 
 * \li GSStoryPage::MakeVehicleButtonReference
src/script/api/script_cargo.hpp
Show inline comments
 
@@ -57,6 +57,7 @@ public:
 
		/* Note: these values represent part of the in-game CargoTypes enum */
 
		CT_AUTO_REFIT = ::CT_AUTO_REFIT, ///< Automatically choose cargo type when doing auto-refitting.
 
		CT_NO_REFIT   = ::CT_NO_REFIT,   ///< Do not refit cargo of a vehicle.
 
		CT_INVALID    = ::CT_INVALID,    ///< An invalid cargo type.
 
	};
 

	
 
	/**
src/script/api/script_industry.cpp
Show inline comments
 
@@ -16,6 +16,7 @@
 
#include "../../station_base.h"
 
#include "../../newgrf_industries.h"
 
#include "table/strings.h"
 
#include <numeric>
 

	
 
#include "../../safeguards.h"
 

	
 
@@ -204,3 +205,39 @@
 

	
 
	return ::Industry::Get(industry_id)->type;
 
}
 

	
 
int32 ScriptIndustry::GetLastProductionYear(IndustryID industry_id)
 
{
 
	Industry *i = Industry::GetIfValid(industry_id);
 
	if (i == nullptr) return 0;
 
	return i->last_prod_year;
 
}
 

	
 
ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type)
 
{
 
	Industry *i = Industry::GetIfValid(industry_id);
 
	if (i == nullptr) return ScriptDate::DATE_INVALID;
 

	
 
	if (cargo_type == CT_INVALID) {
 
		return (ScriptDate::Date)std::accumulate(std::begin(i->last_cargo_accepted_at), std::end(i->last_cargo_accepted_at), 0, [](Date a, Date b) { return std::max(a, b); });
 
	} else {
 
		int index = i->GetCargoAcceptedIndex(cargo_type);
 
		if (index < 0) return ScriptDate::DATE_INVALID;
 
		return (ScriptDate::Date)i->last_cargo_accepted_at[index];
 
	}
 
}
 

	
 
uint32 ScriptIndustry::GetControlFlags(IndustryID industry_id)
 
{
 
	Industry *i = Industry::GetIfValid(industry_id);
 
	if (i == nullptr) return 0;
 
	return i->ctlflags;
 
}
 

	
 
bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flags)
 
{
 
	if (ScriptObject::GetCompany() != OWNER_DEITY) return false;
 
	if (!IsValidIndustry(industry_id)) return false;
 

	
 
	return ScriptObject::DoCommand(0, industry_id, 0 | ((control_flags & ::INDCTL_MASK) << 8), CMD_INDUSTRY_CTRL);
 
}
src/script/api/script_industry.hpp
Show inline comments
 
@@ -11,6 +11,8 @@
 
#define SCRIPT_INDUSTRY_HPP
 

	
 
#include "script_object.hpp"
 
#include "script_date.hpp"
 
#include "../../industry.h"
 

	
 
/**
 
 * Class that handles all industry related functions.
 
@@ -26,6 +28,27 @@ public:
 
	};
 

	
 
	/**
 
	 * Control flags for industry
 
	 * @api -ai
 
	 */
 
	enum IndustryControlFlags {
 
		/**
 
		 * When industry production change is evaluated, rolls to decrease are ignored.
 
		 * This also prevents industry closure due to production dropping to the lowest level.
 
		 */
 
		INDCTL_NO_PRODUCTION_DECREASE = ::INDCTL_NO_PRODUCTION_DECREASE,
 
		/**
 
		 * When industry production change is evaluated, rolls to increase are ignored.
 
		 */
 
		INDCTL_NO_PRODUCTION_INCREASE = ::INDCTL_NO_PRODUCTION_INCREASE,
 
		/**
 
		 * Industry can not close regardless of production level or time since last delivery.
 
		 * This does not prevent a closure already announced.
 
		 */
 
		INDCTL_NO_CLOSURE             = ::INDCTL_NO_CLOSURE,
 
	};
 

	
 
	/**
 
	 * Gets the number of industries.
 
	 * @return The number of industries.
 
	 * @note The maximum valid IndustryID can be higher than the value returned.
 
@@ -196,6 +219,46 @@ public:
 
	 * @return The IndustryType of the industry.
 
	 */
 
	static IndustryType GetIndustryType(IndustryID industry_id);
 

	
 
	/**
 
	 * Get the last year this industry had any production output.
 
	 * @param industry_id The index of the industry.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @return Year the industry last had production, 0 if error.
 
	 * @api -ai
 
	 */
 
	static int32 GetLastProductionYear(IndustryID industry_id);
 

	
 
	/**
 
	 * Get the last date this industry accepted any cargo delivery.
 
	 * @param industry_id The index of the industry.
 
	 * @param cargo_type The cargo to query, or CT_INVALID to query latest of all accepted cargoes.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre IsValidCargo(cargo_type) || cargo_type == CT_INVALID.
 
	 * @return Date the industry last received cargo from a delivery, or ScriptDate::DATE_INVALID on error.
 
	 * @api -ai
 
	 */
 
	static ScriptDate::Date GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type);
 

	
 
	/**
 
	 * Get the current control flags for an industry.
 
	 * @param industry_id The index of the industry.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @return Bit flags of the IndustryControlFlags enumeration.
 
	 * @api -ai
 
	 */
 
	static uint32 GetControlFlags(IndustryID industry_id);
 

	
 
	/**
 
	 * Change the control flags for an industry.
 
	 * @param industry_id The index of the industry.
 
	 * @param control_flags New flags as a combination of IndustryControlFlags values.
 
	 * @pre IsValidIndustry(industry_id).
 
	 * @pre No ScriptCompanyMode may be in scope.
 
	 * @return True if the action succeeded.
 
	 * @api -ai
 
	 */
 
	static bool SetControlFlags(IndustryID industry_id, uint32 control_flags);
 
};
 

	
 
#endif /* SCRIPT_INDUSTRY_HPP */
0 comments (0 inline, 0 general)