| 3206 | } |
| 3207 | |
| 3208 | bool Player::OnLevelChanging(Actors::ActorBase* initiator, ExitType exitType) |
| 3209 | { |
| 3210 | // Deactivate any shield |
| 3211 | if (_activeShieldTime > 70.0f) { |
| 3212 | _activeShieldTime = 70.0f; |
| 3213 | } |
| 3214 | |
| 3215 | if (_spawnedBird != nullptr) { |
| 3216 | _spawnedBird->FlyAway(); |
| 3217 | _spawnedBird = nullptr; |
| 3218 | } |
| 3219 | |
| 3220 | switch (_levelExiting) { |
| 3221 | case LevelExitingState::Waiting: { |
| 3222 | if (CanJump() && std::abs(_speed.X) < 1.0f && std::abs(_speed.Y) < 1.0f) { |
| 3223 | _levelExiting = LevelExitingState::Transition; |
| 3224 | |
| 3225 | ForceCancelTransition(); |
| 3226 | |
| 3227 | SetPlayerTransition(AnimState::TransitionEndOfLevel, false, true, SpecialMoveType::None, [this]() { |
| 3228 | _renderer.setDrawEnabled(false); |
| 3229 | _levelExiting = LevelExitingState::Ready; |
| 3230 | }); |
| 3231 | PlayPlayerSfx("EndOfLevel1"_s, 1.0f / _levelHandler->GetPlayers().size()); |
| 3232 | |
| 3233 | SetState(ActorState::ApplyGravitation, false); |
| 3234 | _speed.X = 0.0f; |
| 3235 | _speed.Y = 0.0f; |
| 3236 | _externalForce.X = 0.0f; |
| 3237 | _externalForce.Y = 0.0f; |
| 3238 | _internalForceY = 0.0f; |
| 3239 | } else if (_lastPoleTime <= 0.0f) { |
| 3240 | // Waiting timeout - use warp transition instead |
| 3241 | _levelExiting = LevelExitingState::Transition; |
| 3242 | |
| 3243 | ForceCancelTransition(); |
| 3244 | |
| 3245 | SetPlayerTransition(_isFreefall ? AnimState::TransitionWarpInFreefall : AnimState::TransitionWarpIn, false, true, SpecialMoveType::None, [this]() { |
| 3246 | _renderer.setDrawEnabled(false); |
| 3247 | _levelExiting = LevelExitingState::Ready; |
| 3248 | }); |
| 3249 | PlayPlayerSfx("WarpIn"_s, 1.0f / _levelHandler->GetPlayers().size()); |
| 3250 | _levelHandler->PlayerExecuteRumble(this, "Warp"_s); |
| 3251 | |
| 3252 | SetState(ActorState::ApplyGravitation, false); |
| 3253 | _speed.X = 0.0f; |
| 3254 | _speed.Y = 0.0f; |
| 3255 | _externalForce.X = 0.0f; |
| 3256 | _externalForce.Y = 0.0f; |
| 3257 | _internalForceY = 0.0f; |
| 3258 | } else { |
| 3259 | // Refresh animation state, because UpdateAnimation() is not called when _controllable is false |
| 3260 | AnimState oldState = _currentAnimation->State; |
| 3261 | AnimState newState = (oldState & CompositeAnimMask); |
| 3262 | if (std::abs(_speed.X) > std::numeric_limits<float>::epsilon()) { |
| 3263 | newState |= AnimState::Walk; |
| 3264 | } |
| 3265 | if (!CanJump()) { |
no test coverage detected