Пример #1
0
        /// <summary>
        ///  Update called for the Flying state
        /// </summary>
        /// <param name="time"></param>
        void UpdateFly(GameTime time)
        {
            // linear lerp
            position = Vector3.Lerp(srcPosition, dstPosition, flyProgress);

            flyProgress += time.ElapsedGameTimeSeconds * 0.5f;

            // estimate the remaining time to check if the target city's catch
            // animation should be played to make it in time
            float timeStamp = destCity.CatchPreserveTime;

            timeStamp = 1.5f - timeStamp;

            if ((flyProgress / 0.5f) > timeStamp)
            {
                if (!notifyedDest)
                {
                    destCity.NotifyIncomingBall(this);

                    // only notify once
                    notifyedDest = true;
                }
            }

            // estimate the remaining time to check if the receive sound should be played
            timeStamp += 0.5f;
            if ((flyProgress / 0.5f) > timeStamp)
            {
                if (!catchSoundPlayed)
                {
                    catchSound.Fire();
                    catchSoundPlayed = true;
                }
            }

            // now adds height to the position
            {
                float       t  = flyProgress * 2;
                const float Gr = 1000;
                float       h;
                if (t < 1)
                {
                    h = Gr * t - 0.5f * (Gr * t * t);
                }
                else
                {
                    h = 0.5f * Gr - 0.5f * Gr * MathEx.Sqr(t - 1);
                }

                position += normal * h;
            }

            // finishes as long as the progress reaches 1
            if (flyProgress > 1)
            {
                ChangeState(State.Finished);
            }
        }
Пример #2
0
        void ChangeState(State newState)
        {
            if (newState == State.Flying)
            {
                for (int i = 0; i < subBalls.Count; i++)
                {
                    subBalls[i].SetDockCity(null);
                }

                srcPosition = position;


                City dstCity = goPath[0];
                this.destCity = dstCity;


                Quaternion newDstOri = dstCity.GetOrientation(srcPosition);

                normal = sourceCity.Transformation.Up + dstCity.Transformation.Up;
                normal.Normalize();

                dstPosition = GetRGBallPosition(dstCity, newDstOri);


                notifyedDest = false;
                flyProgress  = 0;

                throwSound.Fire();
            }
            else if (newState == State.Finished)
            {
                ReleaseBalls();
            }

            state = newState;
        }
Пример #3
0
        public override void Update(GameTime gameTime)
        {
            float dt = (float)gameTime.ElapsedGameTimeSeconds;

            if (weaponCoolDown > 0)
            {
                weaponCoolDown -= dt;
            }

            // accelerating and decelerating
            if (speedModifier < speedModifierTarget)
            {
                speedModifier += dt;
            }
            else if (speedModifier > speedModifierTarget)
            {
                speedModifier -= dt;
            }

            switch (state)
            {
            case RBallState.Standby:
            {
                IntegrateRoundAngle(dt);

                Vector3 pos;
                CalculateRoundTransform(currentRadius, false, out pos, out orientation);
                Position = pos;

                // stand by balls can contribute their docking city
                if (dockCity.Owner != null)
                {
                    if (dockCity.Owner == Owner)
                    {
                        dockCity.Heal(dt * props.Heal, props.HealthIncr * dt);
                        dockCity.Develop(props.Contribution, dt);
                    }
                    else
                    {
                        dockCity.Develop(-props.Contribution * 5, dt);
                    }
                }
                break;
            }

            case RBallState.Gathering:
            {
                NewMoveUpdate(dt);

                if (!isMoving)
                {
                    ChangeState(RBallState.Gathered);
                }
                break;
            }

            case RBallState.Free:
            {
                NewMoveUpdate(dt);
                if (!isMoving)
                {
                    ChangeState(RBallState.Standby);
                }
                break;
            }

            case RBallState.BeginingAttackCity:
            {
                NewMoveUpdate(dt);
                if (!isMoving)
                {
                    ChangeState(RBallState.AttackCity);
                }
                break;
            }

            case RBallState.AttackCity:
            {
                // attack when city not owned
                if (dockCity.Owner != Owner)
                {
                    IntegrateRoundAngle(dt);

                    Vector3 pos;
                    CalculateRoundTransform(CityAttackRadius, true, out pos, out orientation);
                    Position = pos;

                    //tail.Update(gameTime, position, orientation.Forward);

                    if (speedModifier >= AttackCitySpeedMod - 0.5f)
                    {
                        if (weaponCoolDown <= 0)
                        {
                            float dmg = props.Damage;
                            dockCity.Damage(dmg, Owner);
                            Damage(dmg * 0.075f);
                            weaponCoolDown = WeaponCoolDownTime;
                        }
                    }
                }
                else
                {
                    // when owned, check if the speed has decreased low enough
                    if (speedModifier < AttackCitySpeedMod * 0.3f || speedModifier < MinSpeedMod)
                    {
                        // if so, go back to normal standby position
                        Reposition();
                    }
                    else
                    {
                        // otherwise, keep moveing, decelerating
                        IntegrateRoundAngle(dt);

                        Vector3 pos;
                        CalculateRoundTransform(CityAttackRadius, true, out pos, out orientation);
                        Position = pos;

                        speedModifierTarget = MinSpeedMod;
                    }
                }

                break;
            }

            case RBallState.Defend:
            case RBallState.Attack:
            {
                if (target == null || target.Owner == Owner || target.IsDied)
                {
                    Reposition();
                }
                else
                {
                    NewMove(target.position);
                    NewMoveUpdate(dt);

                    float dist = Vector3.DistanceSquared(ref position, ref target.position);
                    if (dist < AttackRange * AttackRange)
                    {
                        if (weaponCoolDown <= 0)
                        {
                            float dmg = props.Damage;
                            target.Damage(dmg);
                            weaponCoolDown = WeaponCoolDownTime;
                        }
                    }
                }
                break;
            }

            case RBallState.Float:
            {
                NewMoveUpdate(dt);

                float dist = Vector3.DistanceSquared(position, floatingTarget.Position);

                if (dist < City.CityOutterRadius * City.CityOutterRadius)
                {
                    Free(floatingTarget);
                }

                break;
            }
            }
            base.Update(gameTime);

            // try attack if any attackable, and when in a suitable state
            if (dockCity != null &&
                (state != RBallState.Gathered && state != RBallState.Gathering && state != RBallState.Free && state != RBallState.Float))
            {
                if (dockCity.Owner != Owner)
                {
                    // In an enemy city
                    enemyCheckTime -= dt;
                    if (enemyCheckTime <= 0 && props.Damage > 10)
                    {
                        if (dockCity.NearbyOwnedBallCount == 0)
                        {
                            if (state != RBallState.AttackCity && state != RBallState.BeginingAttackCity)
                            {
                                AttackCity();
                            }
                        }
                        else
                        {
                            if (state != RBallState.Attack)
                            {
                                Attack();
                            }
                        }
                        enemyCheckTime = EnemyCheckTime;
                    }
                }
                else
                {
                    switch (Type)
                    {
                    case RBallType.Oil:
                    case RBallType.Green:
                    case RBallType.Education:
                    case RBallType.Volience:
                        if (props.Damage > 10)
                        {
                            // defend if any
                            if (dockCity.NearbyEnemyBallCount > 0)
                            {
                                if (state != RBallState.Attack)
                                {
                                    Defend();
                                }
                            }
                        }
                        break;

                    case RBallType.Health:
                    case RBallType.Disease:
                        // These type of balls
                        // defend if able to attack and the city is in good condition
                        if (dockCity.HPRate > 1 - float.Epsilon && props.Damage > 10)
                        {
                            if (dockCity.NearbyEnemyBallCount > 0)
                            {
                                if (state != RBallState.Attack)
                                {
                                    Defend();
                                }
                            }
                        }
                        break;
                    }
                }
            }


            if (shouldPlayDeathSonds)
            {
                soundObject.Position = position;
                soundObject.Update(gameTime);
                soundObject.Fire();
                shouldPlayDeathSonds = false;
            }
        }