* Update the cached visual effect. * @param allow_power_change true if the wagon-is-powered-state may change. */
| 2634 | * @param allow_power_change true if the wagon-is-powered-state may change. |
| 2635 | */ |
| 2636 | void Vehicle::UpdateVisualEffect(bool allow_power_change) |
| 2637 | { |
| 2638 | bool powered_before = HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER); |
| 2639 | const Engine *e = this->GetEngine(); |
| 2640 | |
| 2641 | /* Evaluate properties */ |
| 2642 | uint8_t visual_effect; |
| 2643 | switch (e->type) { |
| 2644 | case VEH_TRAIN: visual_effect = e->VehInfo<RailVehicleInfo>().visual_effect; break; |
| 2645 | case VEH_ROAD: visual_effect = e->VehInfo<RoadVehicleInfo>().visual_effect; break; |
| 2646 | case VEH_SHIP: visual_effect = e->VehInfo<ShipVehicleInfo>().visual_effect; break; |
| 2647 | default: visual_effect = 1 << VE_DISABLE_EFFECT; break; |
| 2648 | } |
| 2649 | |
| 2650 | /* Check powered wagon / visual effect callback */ |
| 2651 | if (e->info.callback_mask.Test(VehicleCallbackMask::VisualEffect)) { |
| 2652 | uint16_t callback = GetVehicleCallback(CBID_VEHICLE_VISUAL_EFFECT, 0, 0, this->engine_type, this); |
| 2653 | |
| 2654 | if (callback != CALLBACK_FAILED) { |
| 2655 | if (callback >= 0x100 && e->GetGRF()->grf_version >= 8) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_VISUAL_EFFECT, callback); |
| 2656 | |
| 2657 | callback = GB(callback, 0, 8); |
| 2658 | /* Avoid accidentally setting 'visual_effect' to the default value |
| 2659 | * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */ |
| 2660 | if (callback == VE_DEFAULT) { |
| 2661 | assert(HasBit(callback, VE_DISABLE_EFFECT)); |
| 2662 | SB(callback, VE_TYPE_START, VE_TYPE_COUNT, 0); |
| 2663 | } |
| 2664 | visual_effect = callback; |
| 2665 | } |
| 2666 | } |
| 2667 | |
| 2668 | /* Apply default values */ |
| 2669 | if (visual_effect == VE_DEFAULT || |
| 2670 | (!HasBit(visual_effect, VE_DISABLE_EFFECT) && GB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT) == VE_TYPE_DEFAULT)) { |
| 2671 | /* Only train engines have default effects. |
| 2672 | * Note: This is independent of whether the engine is a front engine or articulated part or whatever. */ |
| 2673 | if (e->type != VEH_TRAIN || e->VehInfo<RailVehicleInfo>().railveh_type == RAILVEH_WAGON || !IsInsideMM(e->VehInfo<RailVehicleInfo>().engclass, EC_STEAM, EC_MONORAIL)) { |
| 2674 | if (visual_effect == VE_DEFAULT) { |
| 2675 | visual_effect = 1 << VE_DISABLE_EFFECT; |
| 2676 | } else { |
| 2677 | SetBit(visual_effect, VE_DISABLE_EFFECT); |
| 2678 | } |
| 2679 | } else { |
| 2680 | if (visual_effect == VE_DEFAULT) { |
| 2681 | /* Also set the offset */ |
| 2682 | visual_effect = (VE_OFFSET_CENTRE - (e->VehInfo<RailVehicleInfo>().engclass == EC_STEAM ? 4 : 0)) << VE_OFFSET_START; |
| 2683 | } |
| 2684 | SB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT, e->VehInfo<RailVehicleInfo>().engclass - EC_STEAM + VE_TYPE_STEAM); |
| 2685 | } |
| 2686 | } |
| 2687 | |
| 2688 | this->vcache.cached_vis_effect = visual_effect; |
| 2689 | |
| 2690 | if (!allow_power_change && powered_before != HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER)) { |
| 2691 | ToggleBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER); |
| 2692 | ShowNewGrfVehicleError(this->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_POWERED_WAGON, GRFBug::VehPoweredWagon, false); |
| 2693 | } |
no test coverage detected