diff options
-rw-r--r-- | train_cmd.c | 58 | ||||
-rw-r--r-- | vehicle.h | 8 |
2 files changed, 49 insertions, 17 deletions
diff --git a/train_cmd.c b/train_cmd.c index d6d9b08b2..c85c90540 100644 --- a/train_cmd.c +++ b/train_cmd.c @@ -95,18 +95,32 @@ void TrainConsistChanged(Vehicle *v) { // power is the sum of the powers of all engines and powered wagons in the consist power += rvi_u->power; + if (rvi_u->visual_effect != 0) { + u->u.rail.cached_vis_effect = rvi_u->visual_effect; + } else { + if (rvi_u->flags & RVI_WAGON) { + // Wagons have no effect by default + u->u.rail.cached_vis_effect = 0x40; + } else if (rvi_u->engclass == 0) { + // Steam is offset by -4 units + u->u.rail.cached_vis_effect = 4; + } else { + // Diesel fumes and sparks come from the centre + u->u.rail.cached_vis_effect = 8; + } + } + // check if its a powered wagon CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON); if ((rvi_v->pow_wag_power != 0) && (rvi_u->flags & RVI_WAGON) && UsesWagonOverride(u)) { - uint16 callback = CALLBACK_FAILED; - - if (HASBIT(rvi_u->callbackmask, CBM_WAGON_POWER)) - callback = GetCallBackResult(CBID_WAGON_POWER, u->engine_type, u); + if (HASBIT(rvi_u->callbackmask, CBM_WAGON_POWER)) { + uint16 callback = GetCallBackResult(CBID_WAGON_POWER, u->engine_type, u); - if (callback == CALLBACK_FAILED) - callback = rvi_u->visual_effect; + if (callback != CALLBACK_FAILED) + u->u.rail.cached_vis_effect = callback; + } - if (callback < 0x40) { + if (u->u.rail.cached_vis_effect < 0x40) { /* wagon is powered */ SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status power += rvi_v->pow_wag_power; @@ -1717,9 +1731,8 @@ void OnTick_Train(void) _age_cargo_skip_counter = (_age_cargo_skip_counter == 0) ? 184 : (_age_cargo_skip_counter - 1); } -static const int8 _vehicle_smoke_pos[16] = { - -4, -4, -4, 0, 4, 4, 4, 0, - -4, 0, 4, 4, 4, 0,-4,-4, +static const int8 _vehicle_smoke_pos[8] = { + 1, 1, 1, 0, -1, -1, -1, 0 }; static void HandleLocomotiveSmokeCloud(Vehicle *v) @@ -1733,22 +1746,33 @@ static void HandleLocomotiveSmokeCloud(Vehicle *v) do { EngineID engtype = v->engine_type; + int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8; + byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2); + bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6); + int x, y; // no smoke? - if (RailVehInfo(engtype)->flags & 2 || + if ((RailVehInfo(engtype)->flags & RVI_WAGON && effect_type == 0) || + disable_effect || GetEngine(engtype)->railtype > RAILTYPE_RAIL || (v->vehstatus & VS_HIDDEN) || (v->u.rail.track & 0xC0)) continue; - switch (RailVehInfo(engtype)->engclass) { + if (effect_type == 0) { + // Use default effect type for engine class. + effect_type = RailVehInfo(engtype)->engclass; + } else { + effect_type--; + } + + x = _vehicle_smoke_pos[v->direction] * effect_offset; + y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset; + + switch (effect_type) { case 0: // steam smoke. if ( (v->tick_counter&0xF) == 0 && !IsTileDepotType(v->tile, TRANSPORT_RAIL) && !IsTunnelTile(v->tile)) { - CreateEffectVehicleRel(v, - (_vehicle_smoke_pos[v->direction]), - (_vehicle_smoke_pos[v->direction+8]), - 10, - EV_STEAM_SMOKE); + CreateEffectVehicleRel(v, x, y, 10, EV_STEAM_SMOKE); } break; @@ -62,6 +62,14 @@ typedef struct VehicleRail { // cached values, recalculated when the cargo on a train changes (in addition to the conditions above) uint16 cached_weight; // total weight of the consist. uint16 cached_veh_weight; // weight of the vehicle. + /** + * Position/type of visual effect. + * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear) + * bit 4 - 5 = type of effect. (0 = default for engine class, 1 = steam, 2 = diesel, 3 = electric) + * bit 6 = disable visual effect. + * bit 7 = disable powered wagons. + */ + byte cached_vis_effect; // NOSAVE: for wagon override - id of the first engine in train // 0xffff == not in train |