MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / SpawnAdvancedVisualEffect

Function SpawnAdvancedVisualEffect

src/vehicle.cpp:2704–2755  ·  view source on GitHub ↗

* Call CBID_VEHICLE_SPAWN_VISUAL_EFFECT and spawn requested effects. * @param v Vehicle to create effects for. */

Source from the content-addressed store, hash-verified

2702 * @param v Vehicle to create effects for.
2703 */
2704static void SpawnAdvancedVisualEffect(const Vehicle *v)
2705{
2706 std::array<int32_t, 4> regs100;
2707 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_SPAWN_VISUAL_EFFECT, 0, Random(), v->engine_type, v, regs100);
2708 if (callback == CALLBACK_FAILED) return;
2709
2710 uint count = GB(callback, 0, 2);
2711 assert(count <= std::size(regs100));
2712 bool auto_center = HasBit(callback, 13);
2713 bool auto_rotate = !HasBit(callback, 14);
2714
2715 int8_t l_center = 0;
2716 if (auto_center) {
2717 /* For road vehicles: Compute offset from vehicle position to vehicle center */
2718 if (v->type == VEH_ROAD) l_center = -(int)(VEHICLE_LENGTH - RoadVehicle::From(v)->gcache.cached_veh_length) / 2;
2719 } else {
2720 /* For trains: Compute offset from vehicle position to sprite position */
2721 if (v->type == VEH_TRAIN) l_center = (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2722 }
2723
2724 Direction l_dir = v->direction;
2725 if (v->type == VEH_TRAIN && Train::From(v)->flags.Test(VehicleRailFlag::Flipped)) l_dir = ReverseDir(l_dir);
2726 Direction t_dir = ChangeDir(l_dir, DIRDIFF_90RIGHT);
2727
2728 int8_t x_center = _vehicle_smoke_pos[l_dir] * l_center;
2729 int8_t y_center = _vehicle_smoke_pos[t_dir] * l_center;
2730
2731 for (uint i = 0; i < count; i++) {
2732 int32_t reg = regs100[i];
2733 uint type = GB(reg, 0, 8);
2734 int8_t x = GB(reg, 8, 8);
2735 int8_t y = GB(reg, 16, 8);
2736 int8_t z = GB(reg, 24, 8);
2737
2738 if (auto_rotate) {
2739 int8_t l = x;
2740 int8_t t = y;
2741 x = _vehicle_smoke_pos[l_dir] * l + _vehicle_smoke_pos[t_dir] * t;
2742 y = _vehicle_smoke_pos[t_dir] * l - _vehicle_smoke_pos[l_dir] * t;
2743 }
2744
2745 if (type >= 0xF0) {
2746 switch (type) {
2747 case 0xF1: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_STEAM_SMOKE); break;
2748 case 0xF2: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_DIESEL_SMOKE); break;
2749 case 0xF3: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_ELECTRIC_SPARK); break;
2750 case 0xFA: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_BREAKDOWN_SMOKE_AIRCRAFT); break;
2751 default: break;
2752 }
2753 }
2754 }
2755}
2756
2757/**
2758 * Test if a bridge is above a vehicle.

Callers 1

ShowVisualEffectMethod · 0.85

Calls 9

GetVehicleCallbackFunction · 0.85
GBFunction · 0.85
HasBitFunction · 0.85
ReverseDirFunction · 0.85
ChangeDirFunction · 0.85
CreateEffectVehicleRelFunction · 0.85
TestMethod · 0.80
RandomFunction · 0.50
sizeFunction · 0.50

Tested by

no test coverage detected