private void UpdateState(GameTime time) { float dt = time.ElapsedGameTimeSeconds; smoke.EmitEnabled = false; switch (currentState) { case CityState.Rotate: remainingRotationTime -= dt; if (remainingRotationTime < 0) { switch (rotationPurpose) { case CityRotationPurpose.Throw: ThrowNow(); break; case CityRotationPurpose.Receive: ReceiveNow(); break; case CityRotationPurpose.ThrowContinued: ThrowNowContinued(); break; case CityRotationPurpose.Fear: ChangeState(CityState.Fear); break; default: ChangeState(CityState.Stopped); break; } rotationPurpose = CityRotationPurpose.None; } float progress = MathEx.Saturate(1 - remainingRotationTime / rotationTime); currentFacing = Quaternion.Slerp(rotationSrc, rotationTarget, progress); if (isVisible) stopped[currentForm].Update(time); break; case CityState.PostCatch: catchingRelease[currentForm].Update(time); break; case CityState.Catch: catching[currentForm].Update(time); break; case CityState.Fear: fear[currentForm].Update(time); break; case CityState.Idle: idle[currentForm].Update(time); break; case CityState.Laugh: laugh[currentForm].Update(time); break; case CityState.Stopped: //if (reThrowDelay > 0) //{ // reThrowDelay -= dt; // if (reThrowDelay < 0) // { // ThrowContinued(throwRgball.FollowingCity, throwRgball.GetRemainingPath(), throwRgball.Balls); // } //} // handle the requrest in the throw queue first, if any if (throwQueue.Count > 0) { ThrowTask tt = throwQueue.Head(); Quaternion targetRot = GetOrientation(tt.throwPath[0].Position); RotateTo(targetRot, 0.5f); SetRotationPurpose(CityRotationPurpose.Throw); break; } // then if any balls to pass on, if any and throwContCheckCD is ready throwContCheckCD -= dt; if (receivedRGBall.Count > 0 && throwContCheckCD < 0) { RGatheredBall rgb = receivedRGBall.Dequeue(); if (!rgb.IsPathFinished) { ThrowContinued(rgb.FollowingCity, rgb.GetRemainingPath(), rgb.Balls); break; } throwContCheckCD = 0.5f; } smoke.EmitEnabled = true; // to idle if (nextIdleAnimationCD > 0) { nextIdleAnimationCD -= dt; } else { nextIdleAnimationCD = Randomizer.GetRandomSingle() * 3 + 2.5f; bool goIdle = Randomizer.GetRandomBool(); if (goIdle) { ChangeState(CityState.Idle); } else { float rotTime = Randomizer.GetRandomSingle() * 0.5f + 0.5f; float facingChange = Randomizer.GetRandomSingle() * MathEx.PIf - MathEx.PiOver2; Quaternion nextFacing = currentFacing * Quaternion.RotationAxis(Vector3.UnitY, facingChange); RotateTo(nextFacing, rotTime); } } if (isVisible) stopped[currentForm].Update(time); break; case CityState.Throw: throwing[currentForm].Update(time); break; case CityState.ThrowContinued: throwing[currentForm].Update(time); break; case CityState.WakeingUp: wakeingUp[currentForm].Update(time); break; case CityState.Sleeping: if (isVisible) sleeping[currentForm].Update(time); break; case CityState.WaitingGather: if (throwRgball.CurrentState == RGatheredBall.State.WaitingThrow) { ChangeState(CityState.Throw); } else if (throwRgball.CurrentState == RGatheredBall.State.Finished) { ChangeState(CityState.Stopped); throwRgball = null; } else { // check if the balls in the RGatheredBall is gone for some reason // the city should turn back to normal to aviod dead lock if (throwRgball.Balls.Count == 0) { ChangeState(CityState.Stopped); throwRgball = null; } else { bool passed = false; for (int i = 0; i < throwRgball.Balls.Count; i++) { if (!throwRgball.Balls[i].IsDied) { passed = true; } } if (!passed) { ChangeState(CityState.Stopped); throwRgball = null; } } } throwingPrepare[currentForm].Update(time); break; } }
void SetRotationPurpose(CityRotationPurpose porpose) { rotationPurpose = porpose; }