* Handle a crashed train. * @param v First train vehicle. * @return %Vehicle chain still exists. */
| 3740 | * @return %Vehicle chain still exists. |
| 3741 | */ |
| 3742 | static bool HandleCrashedTrain(Train *v) |
| 3743 | { |
| 3744 | int state = ++v->crash_anim_pos; |
| 3745 | |
| 3746 | if (state == 4 && !v->vehstatus.Test(VehState::Hidden)) { |
| 3747 | CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); |
| 3748 | } |
| 3749 | |
| 3750 | uint32_t r; |
| 3751 | if (state <= 200 && Chance16R(1, 7, r)) { |
| 3752 | int index = (r * 10 >> 16); |
| 3753 | |
| 3754 | Vehicle *u = v; |
| 3755 | do { |
| 3756 | if (--index < 0) { |
| 3757 | r = Random(); |
| 3758 | |
| 3759 | CreateEffectVehicleRel(u, |
| 3760 | GB(r, 8, 3) + 2, |
| 3761 | GB(r, 16, 3) + 2, |
| 3762 | GB(r, 0, 3) + 5, |
| 3763 | EV_EXPLOSION_SMALL); |
| 3764 | break; |
| 3765 | } |
| 3766 | } while ((u = u->Next()) != nullptr); |
| 3767 | } |
| 3768 | |
| 3769 | if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v); |
| 3770 | |
| 3771 | if (state >= 4440 && !(v->tick_counter & 0x1F)) { |
| 3772 | bool ret = v->Next() != nullptr; |
| 3773 | DeleteLastWagon(v); |
| 3774 | return ret; |
| 3775 | } |
| 3776 | |
| 3777 | return true; |
| 3778 | } |
| 3779 | |
| 3780 | /** Maximum speeds for train that is broken down or approaching line end */ |
| 3781 | static const uint16_t _breakdown_speeds[16] = { |
no test coverage detected