diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 14802dfd68..48c92495a7 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -468,6 +468,22 @@ static uint32 GetGRFParameter(EngineID engine_type, byte parameter) } +static uint8 LiveryHelper(EngineID engine, const Vehicle *v) +{ + const Livery *l; + + if (v == NULL) { + l = GetEngineLivery(engine, _current_player, INVALID_ENGINE, NULL); + } else if (v->type == VEH_TRAIN) { + l = GetEngineLivery((v->u.rail.first_engine != INVALID_ENGINE && (IsArticulatedPart(v) || UsesWagonOverride(v))) ? v->u.rail.first_engine : v->engine_type, v->owner, v->u.rail.first_engine, v); + } else { + l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v); + } + + return l->colour1 + l->colour2 * 16; +} + + static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) { const Vehicle *v = GRV(object); @@ -475,7 +491,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_player; // Owner information + case 0x43: return _current_player | (LiveryHelper(object->u.vehicle.self_type, NULL) << 24); // Owner information case 0x46: return 0; // Motion counter case 0x48: return GetEngine(object->u.vehicle.self_type)->flags; // Vehicle Type Info case 0xC4: return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; // Build year @@ -544,7 +560,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by } case 0x43: // Player information - return v->owner; + return v->owner | (GetPlayer(v->owner)->is_ai ? 0x10000 : 0) | (LiveryHelper(v->engine_type, v) << 24); case 0x44: // Aircraft information if (v->type != VEH_AIRCRAFT) return UINT_MAX; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index d4cdcd083c..384590e640 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2467,26 +2467,13 @@ UnitID GetFreeUnitNumber(byte type) return unit; } -static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v) + +const Livery *GetEngineLivery(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v) { - SpriteID map = PAL_NONE; const Player *p = GetPlayer(player); LiveryScheme scheme = LS_DEFAULT; CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type; - /* Check if we should use the colour map callback */ - if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) { - uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v); - /* A return value of 0xC000 is stated to "use the default two-color - * maps" which happens to be the failure action too... */ - if (callback != CALLBACK_FAILED && callback != 0xC000) { - map = GB(callback, 0, 14); - /* If bit 14 is set, then the company colours are applied to the - * map else it's returned as-is. */ - if (!HASBIT(callback, 14)) return map; - } - } - /* The default livery is always available for use, but its in_use flag determines * whether any _other_ liveries are in use. */ if (p->livery[LS_DEFAULT].in_use && (_patches.liveries == 2 || (_patches.liveries == 1 && player == _local_player))) { @@ -2563,12 +2550,35 @@ static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, Engine if (!p->livery[scheme].in_use) scheme = LS_DEFAULT; } + return &p->livery[scheme]; +} + + +static SpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v) +{ + SpriteID map = PAL_NONE; + + /* Check if we should use the colour map callback */ + if (HASBIT(EngInfo(engine_type)->callbackmask, CBM_COLOUR_REMAP)) { + uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v); + /* A return value of 0xC000 is stated to "use the default two-color + * maps" which happens to be the failure action too... */ + if (callback != CALLBACK_FAILED && callback != 0xC000) { + map = GB(callback, 0, 14); + /* If bit 14 is set, then the company colours are applied to the + * map else it's returned as-is. */ + if (!HASBIT(callback, 14)) return map; + } + } + bool twocc = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC); if (map == PAL_NONE) map = twocc ? (SpriteID)SPR_2CCMAP_BASE : (SpriteID)PALETTE_RECOLOR_START; - map += p->livery[scheme].colour1; - if (twocc) map += p->livery[scheme].colour2 * 16; + const Livery *livery = GetEngineLivery(engine_type, player, parent_engine_type, v); + + map += livery->colour1; + if (twocc) map += livery->colour2 * 16; return map; } diff --git a/src/vehicle.h b/src/vehicle.h index 20a5797693..4d4b51abc6 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -551,6 +551,8 @@ VARDEF uint16 _returned_refit_capacity; static const VehicleID INVALID_VEHICLE = 0xFFFF; +const struct Livery *GetEngineLivery(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v); + /** * Get the colour map for an engine. This used for unbuilt engines in the user interface. * @param engine_type ID of engine