25#include "table/strings.h"
43 if (grf_type == IT_INVALID)
return IT_INVALID;
44 if (!
HasBit(grf_type, 7))
return GB(grf_type, 0, 7);
46 return _industry_mngr.GetID(
GB(grf_type, 0, 7), grf_id);
70 return 0xFF << 8 | gfx;
90 return 0xFF << 8 | indtsp->
grf_prop.subst_id;
93static uint32_t GetClosestIndustry(
TileIndex tile, IndustryType type,
const Industry *current)
95 uint32_t best_dist = UINT32_MAX;
98 if (industry == current->index)
continue;
119 uint32_t grf_id =
static_cast<uint32_t
>(
object.GetRegister(0x100));
120 IndustryType industry_type;
121 uint32_t closest_dist = UINT32_MAX;
127 industry_type = param_set_id;
143 if (layout_filter == 0 && !town_filter) {
146 closest_dist = GetClosestIndustry(current->
location.
tile, industry_type, current);
152 if (industry == current->index)
continue;
155 if ((layout_filter == 0 || i->
selected_layout == layout_filter) && (!town_filter || i->
town == current->
town)) {
162 return count << 16 |
GB(closest_dist, 0, 16);
173 case 0x80:
return this->tile.base();
174 case 0x81:
return GB(this->tile.base(), 8, 8);
177 case 0x82:
return this->
industry->town->index.base();
180 case 0x85:
Debug(grf, 0,
"NewGRFs shouldn't be doing pointer magic");
break;
183 case 0x86:
return this->
industry->selected_layout;
211 Debug(grf, 1,
"Unhandled variable 0x{:X} (no available industry) in callback 0x{:x}", variable, this->
ro.callback);
222 if (callback.
Any({IndustryCallbackMask::ProductionCargoArrival, IndustryCallbackMask::Production256Ticks})) {
224 if (this->
industry->prod_level == 0)
return 0;
240 case 0x44:
return this->
industry->selected_layout;
253 return this->
industry->founder.base() | (is_ai ? 0x10000 : 0) | (colours << 24);
256 case 0x46:
return this->
industry->construction_date.base();
259 case 0x47:
return this->
industry->ctlflags.base();
291 return GetClosestIndustry(this->tile,
type, this->
industry);
310 uint8_t layout_filter = 0;
311 bool town_filter =
false;
312 if (variable == 0x68) {
313 int32_t reg = this->
ro.GetRegister(0x101);
314 layout_filter =
GB(reg, 0, 8);
315 town_filter =
HasBit(reg, 8);
329 auto it = this->
industry->GetCargoProduced(cargo);
330 if (it == std::end(this->
industry->produced))
return 0;
332 case 0x69:
return it->waiting;
333 case 0x6A:
return it->history[THIS_MONTH].production;
334 case 0x6B:
return it->history[THIS_MONTH].transported;
335 case 0x6C:
return it->history[LAST_MONTH].production;
336 case 0x6D:
return it->history[LAST_MONTH].transported;
337 case 0x70:
return it->rate;
338 case 0x71:
return it->history[LAST_MONTH].PctTransported();
339 default: NOT_REACHED();
348 auto it = this->
industry->GetCargoAccepted(cargo);
349 if (it == std::end(this->
industry->accepted))
return 0;
350 if (variable == 0x6E)
return it->last_accepted.base();
351 if (variable == 0x6F)
return it->waiting;
358 case 0x7C:
return (this->
industry->psa !=
nullptr) ? this->
industry->psa->GetValue(parameter) : 0;
361 case 0x80:
return this->
industry->location.tile.base();
362 case 0x81:
return GB(this->
industry->location.tile.base(), 8, 8);
364 case 0x82:
return this->
industry->town->index.base();
367 case 0x85:
Debug(grf, 0,
"NewGRFs shouldn't be doing pointer magic");
break;
368 case 0x86:
return this->
industry->location.w;
369 case 0x87:
return this->
industry->location.h;
372 case 0x89:
return this->
industry->GetProduced(variable - 0x88).cargo;
373 case 0x8A:
return this->
industry->GetProduced(0).waiting;
374 case 0x8B:
return GB(this->
industry->GetProduced(0).waiting, 8, 8);
375 case 0x8C:
return this->
industry->GetProduced(1).waiting;
376 case 0x8D:
return GB(this->
industry->GetProduced(1).waiting, 8, 8);
378 case 0x8F:
return this->
industry->GetProduced(variable - 0x8E).rate;
381 case 0x92:
return this->
industry->GetAccepted(variable - 0x90).cargo;
382 case 0x93:
return this->
industry->prod_level;
384 case 0x94:
return this->
industry->GetProduced(0).history[THIS_MONTH].production;
385 case 0x95:
return GB(this->
industry->GetProduced(0).history[THIS_MONTH].production, 8, 8);
386 case 0x96:
return this->
industry->GetProduced(1).history[THIS_MONTH].production;
387 case 0x97:
return GB(this->
industry->GetProduced(1).history[THIS_MONTH].production, 8, 8);
389 case 0x98:
return this->
industry->GetProduced(0).history[THIS_MONTH].transported;
390 case 0x99:
return GB(this->
industry->GetProduced(0).history[THIS_MONTH].transported, 8, 8);
391 case 0x9A:
return this->
industry->GetProduced(1).history[THIS_MONTH].transported;
392 case 0x9B:
return GB(this->
industry->GetProduced(1).history[THIS_MONTH].transported, 8, 8);
395 case 0x9D:
return this->
industry->GetProduced(variable - 0x9C).history[LAST_MONTH].PctTransported();
397 case 0x9E:
return this->
industry->GetProduced(0).history[LAST_MONTH].production;
398 case 0x9F:
return GB(this->
industry->GetProduced(0).history[LAST_MONTH].production, 8, 8);
399 case 0xA0:
return this->
industry->GetProduced(1).history[LAST_MONTH].production;
400 case 0xA1:
return GB(this->
industry->GetProduced(1).history[LAST_MONTH].production, 8, 8);
402 case 0xA2:
return this->
industry->GetProduced(0).history[LAST_MONTH].transported;
403 case 0xA3:
return GB(this->
industry->GetProduced(0).history[LAST_MONTH].transported, 8, 8);
404 case 0xA4:
return this->
industry->GetProduced(1).history[LAST_MONTH].transported;
405 case 0xA5:
return GB(this->
industry->GetProduced(1).history[LAST_MONTH].transported, 8, 8);
408 case 0xA7:
return this->
industry->founder.base();
409 case 0xA8:
return this->
industry->random_colour;
411 case 0xAA:
return this->
industry->counter;
412 case 0xAB:
return GB(this->
industry->counter, 8, 8);
413 case 0xAC:
return this->
industry->was_cargo_delivered;
416 case 0xB3:
return this->
industry->construction_type;
418 if (this->
industry->accepted.empty())
return 0;
419 auto it = std::max_element(std::begin(this->
industry->accepted), std::end(this->industry->accepted), [](
const auto &a,
const auto &b) { return a.last_accepted < b.last_accepted; });
424 Debug(grf, 1,
"Unhandled industry variable 0x{:X}", variable);
442 if (this->
industry->index == IndustryID::Invalid())
return;
444 if (this->
industry->psa ==
nullptr) {
446 if (value == 0)
return;
454 this->
industry->psa->StoreValue(pos, value);
494 bool readonly =
true;
501 if (t ==
nullptr)
return nullptr;
509 return GSF_INDUSTRIES;
531 return object.ResolveCallback(regs100);
549 Industry ind(IndustryID::Invalid());
555 ind.
random = initial_random_bits;
560 std::array<int32_t, 16> regs100;
561 uint16_t result =
object.ResolveCallback(regs100);
586 if (res != 0) default_prob = 0;
591 }
else if (res > 0x100) {
612 object.callback_param2 = reason;
614 auto deref_ind_prod = [&object](
int field,
bool use_register) -> int32_t {
615 return use_register ?
object.GetRegister(field) : field;
618 for (uint loop = 0;; loop++) {
621 if (loop >= 0x10000) {
631 SB(
object.callback_param2, 8, 16, loop);
633 if (group ==
nullptr)
break;
635 if (group->version == 0xFF) {
645 bool deref = (group->version >= 1);
647 if (group->version < 2) {
649 for (uint i = 0; i < group->num_input && i < ind->
accepted.size(); i++) {
653 for (uint i = 0; i < group->num_output && i < ind->
produced.size(); i++) {
659 for (uint i = 0; i < group->num_input; i++) {
661 if (it == std::end(ind->
accepted))
continue;
662 it->waiting =
ClampTo<uint16_t>(it->waiting - deref_ind_prod(group->subtract_input[i], deref) * multiplier);
664 for (uint i = 0; i < group->num_output; i++) {
666 if (it == std::end(ind->
produced))
continue;
667 it->waiting =
ClampTo<uint16_t>(it->waiting + std::max(deref_ind_prod(group->add_output[i], deref), 0) * multiplier);
671 int32_t again = deref_ind_prod(group->again, deref);
672 if (again == 0)
break;
674 SB(
object.callback_param2, 24, 8, again);
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Common return value for all commands.
static constexpr TimerGame< struct Economy >::Year ORIGINAL_BASE_YEAR
static constexpr TimerGame< struct Calendar >::Date DAYS_TILL_ORIGINAL_BASE_YEAR
Definition of stuff that is very close to a company, like the company struct itself.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Functions related to errors.
@ WL_WARNING
Other information.
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
const IndustrySpec * GetIndustrySpec(IndustryType thistype)
Accessor for array _industry_specs.
const IndustryTileSpec * GetIndustryTileSpec(IndustryGfx gfx)
Accessor for array _industry_tile_specs.
IndustryGfx GetCleanIndustryGfx(Tile t)
Get the industry graphics ID for the given industry tile as stored in the without translation.
uint8_t GetIndustryRandomBits(Tile tile)
Get the random bits for this tile.
static const IndustryGfx NEW_INDUSTRYTILEOFFSET
original number of tiles
static const IndustryType NEW_INDUSTRYOFFSET
original number of industry types
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like IT_...
static const IndustryGfx INVALID_INDUSTRYTILE
one above amount is considered invalid
static const IndustryGfx NUM_INDUSTRYTILES
total number of industry tiles, new and old
@ ProdCallbackRandom
Production callback needs random bits in var 10.
@ BuiltOnWater
is built on water (oil rig)
@ ProdMultiHandling
Automatic production multiplier handling.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
constexpr To ClampTo(From value)
Clamp the given value down to lie within the requested type.
uint32_t GetBadgeVariableResult(const GRFFile &grffile, std::span< const BadgeID > badges, uint32_t parameter)
Test for a matching badge in a list of badges, returning the number of matching bits.
Functions related to NewGRF badges.
@ Probability
industry availability/probability callback
@ RefuseCargo
option out of accepting cargo
CallbackID
List of implemented NewGRF callbacks.
@ CBID_INDUSTRY_PROBABILITY
Called to determine if the given industry type is available.
@ CBID_INDUSTRY_REFUSE_CARGO
Called to determine if the industry can still accept or refuse more cargo arrival.
@ CBID_INDUSTRY_LOCATION
Called to determine if the given industry can be built on specific area.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Cargo support for NewGRFs.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span< const int32_t > textstack, const GRFFile *grffile, StringID default_error)
Get the error message from a shape/location/slope check callback result.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
uint32_t GetTerrainType(TileIndex tile, TileContext context)
Function used by houses (and soon industries) to get information on type of "terrain" the tile it is ...
TileIndex GetNearbyTile(uint8_t parameter, TileIndex tile, bool signed_offsets, Axis axis)
Get the tile at the given offset.
uint32_t GetIndustryIDAtOffset(TileIndex tile, const Industry *i, uint32_t cur_grfid)
Make an analysis of a tile and check for its belonging to the same industry, and/or the same grf file...
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32_t grf_id)
Map the GRF local type to an industry type.
static uint32_t GetCountAndDistanceOfClosestInstance(const ResolverObject &object, uint8_t param_set_id, uint8_t layout_filter, bool town_filter, const Industry *current)
Implementation of both var 67 and 68 since the mechanism is almost the same, it is easier to regroup ...
CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, size_t layout, uint32_t seed, uint16_t initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type)
Check that the industry callback allows creation of the industry.
uint16_t GetIndustryCallback(CallbackID callback, uint32_t param1, uint32_t param2, Industry *industry, IndustryType type, TileIndex tile, std::span< int32_t > regs100)
Perform an industry callback.
void IndustryProductionCallback(Industry *ind, int reason)
Get the industry production callback and apply it to the industry.
uint32_t GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCallType creation_type, uint32_t default_prob)
Check with callback CBID_INDUSTRY_PROBABILITY whether the industry can be built.
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoType cargo_type)
Check whether an industry temporarily refuses to accept a certain cargo.
static const GRFFile * GetGrffile(IndustryType type)
Get the grf file associated with the given industry type.
Functions for NewGRF industries.
uint32_t GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i, uint32_t cur_grfid)
Make an analysis of a tile and check for its belonging to the same industry, and/or the same grf file...
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32_t grf_id)
Map the GRF local type to an industry type.
IndustryAvailabilityCallType
From where has callback CBID_INDUSTRY_PROBABILITY been called.
uint32_t GetNearbyIndustryTileInformation(uint8_t parameter, TileIndex tile, IndustryID index, bool signed_offsets, bool grf_version8)
Based on newhouses equivalent, but adapted for newindustries.
Functions to handle the town part of NewGRF towns.
Pseudo random number generator.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Functions related to OTTD's strings.
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
uint8_t GetCompanyRecolourOffset(LiveryScheme livery_scheme, bool use_secondary=true) const
Get offset for recolour palette of specific company.
const struct GRFFile * grffile
grf file that introduced this entity
uint16_t local_id
id defined by the grf file for this entity
uint32_t grfid
grfid that introduced this entity.
Dynamic data of a loaded NewGRF.
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID).
IndustriesResolverObject(TileIndex tile, Industry *indus, IndustryType type, uint32_t random_bits=0, CallbackID callback=CBID_NO_CALLBACK, uint32_t callback_param1=0, uint32_t callback_param2=0)
Constructor of the industries resolver.
std::optional< TownScopeResolver > town_scope
Scope resolver for the associated town (if needed and available, else std::nullopt).
TownScopeResolver * GetTown()
Get or create the town scope object associated with the industry.
GrfSpecFeature GetFeature() const override
Get the feature number being resolved for.
uint32_t GetDebugID() const override
Get an identifier for the item being resolved.
IndustriesScopeResolver industries_scope
Scope resolver for the industry.
uint32_t GetRandomTriggers() const override
Get the triggers.
IndustryType type
Type of the industry.
uint32_t random_bits
Random bits of the new industry.
uint32_t GetVariable(uint8_t variable, uint32_t parameter, bool &available) const override
Get a variable value.
uint32_t GetRandomBits() const override
Get a few random bits.
void StorePSA(uint pos, int32_t value) override
Store a value into the persistent storage area (PSA).
TileIndex tile
Tile owned by the industry.
Industry * industry
Industry being resolved.
Defines the data structure for constructing industry.
IndustryCallbackMasks callback_mask
Bitmask of industry callbacks that have to be called.
SubstituteGRFFileProps grf_prop
properties related to the grf file
StringID name
Displayed name of the industry.
IndustryBehaviours behaviour
How this industry will behave, and how others entities can use it.
Defines the data structure of each individual tile of an industry.
SubstituteGRFFileProps grf_prop
properties related to the grf file
Defines the internal data of a functional industry.
IndustryType type
type of industry.
bool IsCargoAccepted() const
Test if this industry accepts any cargo.
PersistentStorage * psa
Persistent storage for NewGRF industries.
uint8_t prod_level
general production level
ProducedCargoes::iterator GetCargoProduced(CargoType cargo)
Get produced cargo slot for a specific cargo type.
ProducedCargoes produced
produced cargo slots
uint16_t random
Random value used for randomisation of all kinds of things.
Owner founder
Founder of the industry.
uint8_t selected_layout
Which tile layout was used when creating the industry.
AcceptedCargoes accepted
accepted cargo slots
static uint16_t GetIndustryTypeCount(IndustryType type)
Get the count of industries for this type.
TileArea location
Location of the industry.
bool TileBelongsToIndustry(TileIndex tile) const
Check if a given tile belongs to this industry.
AcceptedCargoes::iterator GetCargoAccepted(CargoType cargo)
Get accepted cargo slot for a specific cargo type.
static std::array< FlatSet< IndustryID >, NUM_INDUSTRYTYPES > industries
List of industries of each type.
uint16_t w
The width of the area.
TileIndex tile
The base tile of the area.
static Industry * Get(auto index)
static bool CanAllocateItem(size_t n=1)
static T * Create(Targs &&... args)
static Company * GetIfValid(auto index)
Interface for SpriteGroup-s to access the gamestate.
uint32_t callback_param2
Second parameter (var 18) of the callback.
ResolverObject(const GRFFile *grffile, CallbackID callback=CBID_NO_CALLBACK, uint32_t callback_param1=0, uint32_t callback_param2=0)
Resolver constructor.
CallbackID callback
Callback being resolved.
uint32_t callback_param1
First parameter (var 10) of the callback.
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
ResolverObject & ro
Surrounding resolver object.
const struct SpriteGroup * GetSpriteGroup(bool entity_exists) const
Get the standard sprite group.
bool HasSpriteGroups() const
Check whether the entity has sprite groups.
uint16_t override_id
id of the entity been replaced by
Scope resolver for a town.
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
uint8_t GetAnimationFrame(Tile t)
Get the current animation frame.
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
static constexpr uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in ZOOM_BASE.
Definition of the game-calendar-timer.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
HouseZone GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Window functions not directly related to making/drawing windows.
@ WC_INDUSTRY_VIEW
Industry view; Window numbers: