diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index f4161fc826..0867b2675f 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -25,6 +25,8 @@ #include "genworld.h" #include "newgrf_spritegroup.h" #include "newgrf_text.h" +#include "livery.h" +#include "company_base.h" #include "table/strings.h" @@ -452,6 +454,18 @@ uint32 GetNearbyTileInformation(TileIndex tile) return tile_type << 24 | z << 16 | terrain_type << 8 | tileh; } +/** + * Returns company information like in vehicle var 43 or station var 43. + * @param owner Owner of the object. + * @param l Livery of the object; NULL to use default. + * @return NewGRF company information. + */ +uint32 GetCompanyInfo(CompanyID owner, const Livery *l) +{ + if (l == NULL && Company::IsValidID(owner)) l = &Company::Get(owner)->livery[LS_DEFAULT]; + return owner | (Company::IsValidAiID(owner) ? 0x10000 : 0) | (l != NULL ? (l->colour1 << 24) | (l->colour2 << 28) : 0); +} + /** * Get the error message from a shape/location/slope check callback result. * @param cb_res Callback result to translate. If bit 10 is set this is a standard error message, otherwise a NewGRF provided string. diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 77d62479ec..ec669d907d 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -21,6 +21,7 @@ #include "core/smallvec_type.hpp" #include "command_type.h" #include "direction_type.h" +#include "company_type.h" /** Context for tile accesses */ enum TileContext { @@ -269,6 +270,7 @@ extern ObjectOverrideManager _object_mngr; uint32 GetTerrainType(TileIndex tile, TileContext context = TCX_NORMAL); TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets = true, Axis axis = INVALID_AXIS); uint32 GetNearbyTileInformation(TileIndex tile); +uint32 GetCompanyInfo(CompanyID owner, const struct Livery *l = NULL); CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, uint32 grfid, StringID default_error); /** diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index f2f28883a1..f69142a250 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -432,12 +432,21 @@ static void VehicleSetTriggers(const ResolverObject *object, int triggers) } -static uint8 LiveryHelper(EngineID engine, const Vehicle *v) +/** + * Determines the livery of an engine. + * + * This always uses dual company colours independent of GUI settings. So it is desync-safe. + * + * @param engine Engine type + * @param v Vehicle, NULL in purchase list. + * @return Livery to use + */ +static const Livery *LiveryHelper(EngineID engine, const Vehicle *v) { const Livery *l; if (v == NULL) { - if (!Company::IsValidID(_current_company)) return 0; + if (!Company::IsValidID(_current_company)) return NULL; l = GetEngineLivery(engine, _current_company, INVALID_ENGINE, NULL, LIT_ALL); } else if (v->IsGroundVehicle()) { l = GetEngineLivery(v->engine_type, v->owner, v->GetGroundVehicleCache()->first_engine, v, LIT_ALL); @@ -445,7 +454,7 @@ static uint8 LiveryHelper(EngineID engine, const Vehicle *v) l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v, LIT_ALL); } - return l->colour1 + l->colour2 * 16; + return l; } /** @@ -481,7 +490,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by if (v == NULL) { /* Vehicle does not exist, so we're in a purchase list */ switch (variable) { - case 0x43: return _current_company | (Company::IsValidAiID(_current_company) ? 0x10000 : 0) | (LiveryHelper(object->u.vehicle.self_type, NULL) << 24); // Owner information + case 0x43: return GetCompanyInfo(_current_company, LiveryHelper(object->u.vehicle.self_type, NULL)); // Owner information case 0x46: return 0; // Motion counter case 0x47: { // Vehicle cargo info const Engine *e = Engine::Get(object->u.vehicle.self_type); @@ -581,7 +590,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by case 0x43: // Company information if (!HasBit(v->grf_cache.cache_valid, NCVV_COMPANY_INFORMATION)) { - v->grf_cache.company_information = v->owner | (Company::IsHumanID(v->owner) ? 0 : 0x10000) | (LiveryHelper(v->engine_type, v) << 24); + v->grf_cache.company_information = GetCompanyInfo(v->owner, LiveryHelper(v->engine_type, v)); SetBit(v->grf_cache.cache_valid, NCVV_COMPANY_INFORMATION); } return v->grf_cache.company_information; diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 4a6535e27e..8dfd866be4 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -287,7 +287,7 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by case 0x47: case 0x49: return 0x2110000; // Platforms, tracks & position case 0x42: return 0; // Rail type (XXX Get current type from GUI?) - case 0x43: return _current_company; // Station owner + case 0x43: return GetCompanyInfo(_current_company); // Station owner case 0x44: return 2; // PBS status case 0x67: // Land info of nearby tile if (object->u.station.axis != INVALID_AXIS && tile != INVALID_TILE) { @@ -318,7 +318,7 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by return _svc.v41; case 0x42: return GetTerrainType(tile) | (GetReverseRailTypeTranslation(GetRailType(tile), object->u.station.statspec->grf_prop.grffile) << 8); - case 0x43: return st->owner; // Station owner + case 0x43: return GetCompanyInfo(st->owner); // Station owner case 0x44: return HasStationReservation(tile) ? 7 : 4; // PBS status case 0x45: if (!HasBit(_svc.valid, 2)) { _svc.v45 = GetRailContinuationInfo(tile); SetBit(_svc.valid, 2); }