Exemple #1
0
        public override void Update(Microsoft.Xna.Framework.GameTime gameTime, BoundingFrustum cameraFrustum, SwimmingObject[] enemies, int enemiesSize, 
            SwimmingObject[] fish, int fishSize, int changeDirection, HydroBot tank, List<DamageBullet> enemyBullet)
        {
            EffectHelpers.GetEffectConfiguration(ref fogColor, ref ambientColor, ref diffuseColor, ref specularColor);

            if (lastPower != HydroBot.turtlePower)
            {
                float lastMaxHealth = maxHealth;
                maxHealth = GameConstants.TurtleStartingHealth * HydroBot.turtlePower;
                health += (maxHealth - lastMaxHealth);
                speedFactor = 1.5f + (HydroBot.turtlePower - 1) / 4;
                lastPower = HydroBot.turtlePower;
            }

            BaseEnemy potentialEnemy = lookForEnemy(enemies, enemiesSize);
            if (!isReturnBot && !isCasting && potentialEnemy != null)
            {
                // It is OK to cast?
                if (PoseidonGame.playTime.TotalSeconds - lastCast.TotalSeconds > coolDown.TotalSeconds)// && HydroBot.currentHitPoint < HydroBot.maxHitPoint)
                {
                    isCasting = true;
                    isReturnBot = false;
                    isWandering = false;
                    isChasing = false;
                    isFighting = false;

                    // For this case, I choose to set the forward direction statically rather than
                    // facing different enemy since potentialEnemy may die, run away, etc
                    Vector3 facingDirection = potentialEnemy.Position - Position;
                    ForwardDirection = (float)Math.Atan2(facingDirection.X, facingDirection.Z);

                    firstCast = true;

                    startCasting = PoseidonGame.playTime;
                    PoseidonGame.audio.frozenBreathe.Play();
                }
            }

            if (isCasting == true)
            {
                // Casting timeout
                if (PoseidonGame.playTime.TotalSeconds - startCasting.TotalSeconds > standingTime.TotalSeconds)
                {
                    isCasting = false; // Done casting
                    isWandering = true; // Let the wander state do the wandering task, (and also lock enemy is potential enemy != null)

                    lastCast = PoseidonGame.playTime;
                } // Effect during cast
                else {
                    FrozenBreathe(enemies, enemiesSize, firstCast);
                    firstCast = false;
                }
                RestoreNormalAnimation();
            }

            Vector3 destination = tank.Position + new Vector3(AfterX, 0, AfterZ);
            if (isWandering == true)
            {
                // If the fish is far from the point after the bot's back or is the bot moving
                if (Vector3.Distance(tank.Position, Position) > HydroBot.controlRadius || (tank.isMoving() && Vector3.Distance(tank.Position, Position) > 50f))
                {
                    isWandering = false;
                    isReturnBot = true;
                    isChasing = false;
                    isFighting = false;

                    seekDestination(destination, enemies, enemiesSize, fish, fishSize, tank, speedFactor);
                }
                else
                {
                    currentTarget = potentialEnemy;
                    if (currentTarget == null) // See no enemy
                        randomWalk(changeDirection, enemies, enemiesSize, fish, fishSize, tank);
                    else
                    { // Hunt him down
                        isWandering = false;
                        isReturnBot = false;
                        isChasing = true;
                        isFighting = false;

                        seekDestination(currentTarget.Position, enemies, enemiesSize, fish, fishSize, tank, speedFactor);
                    }
                }
            }// End wandering

            // If return is the current state
            else if (isReturnBot == true)
            {
                // If the fish is near the point after the bot's back, wander
                if (Vector3.Distance(destination, Position) < HydroBot.controlRadius * 0.5 &&
                    Vector3.Distance(tank.Position, Position) < HydroBot.controlRadius)
                {
                    float test = Vector3.Distance(destination, Position);

                    isWandering = true;
                    isReturnBot = false;
                    isChasing = false;
                    isFighting = false;

                    randomWalk(changeDirection, enemies, enemiesSize, fish, fishSize, tank);
                }
                else
                    seekDestination(destination, enemies, enemiesSize, fish, fishSize, tank, speedFactor);
            }
            // If the fish is chasing some enemy
            else if (isChasing == true)
            {
                if (Vector3.Distance(tank.Position, Position) > HydroBot.controlRadius * 1.25f)
                {  // If too far, return to bot
                    isWandering = false;
                    isReturnBot = true;
                    isChasing = false;
                    isFighting = false;

                    currentTarget = null;

                    seekDestination(destination, enemies, enemiesSize, fish, fishSize, tank, speedFactor);
                }
                else if (Vector3.Distance(Position, currentTarget.Position) <
                    5f + BoundingSphere.Radius + currentTarget.BoundingSphere.Radius) // Too close then attack
                {
                    isWandering = false;
                    isReturnBot = false;
                    isChasing = false;
                    isFighting = true;

                    attack();
                }
                else
                    seekDestination(currentTarget.Position, enemies, enemiesSize, fish, fishSize, tank, speedFactor);
            }
            // If fighting some enemy
            else if (isFighting == true)
            {
                // Enemy is down, return to bot
                if (currentTarget == null || currentTarget.health <= 0)
                {
                    isWandering = false;
                    isReturnBot = true;
                    isChasing = false;
                    isFighting = false;

                    currentTarget = null;

                    seekDestination(destination, enemies, enemiesSize, fish, fishSize, tank, speedFactor);
                }
                else
                {
                    // If the enemy ran away and the fish is not too far from bot
                    if (Vector3.Distance(tank.Position, Position) >= HydroBot.controlRadius)
                    {
                        isWandering = false;
                        isReturnBot = true;
                        isChasing = false;
                        isFighting = false;

                        currentTarget = null;

                        seekDestination(destination, enemies, enemiesSize, fish, fishSize, tank, speedFactor);
                    } // Or enemy ran away
                    else if (Vector3.Distance(Position, currentTarget.Position) >=
                      10f + BoundingSphere.Radius + currentTarget.BoundingSphere.Radius)
                    {
                        isWandering = false;
                        isReturnBot = false;
                        isChasing = true;
                        isFighting = false;

                        seekDestination(currentTarget.Position, enemies, enemiesSize, fish, fishSize, tank, speedFactor);
                    }
                    else
                        attack();
                }
            }

            // if clip player has been initialized, update it
            if (clipPlayer != null || BoundingSphere.Intersects(cameraFrustum))
            {
                qRotation = Quaternion.CreateFromAxisAngle(
                                Vector3.Up,
                                ForwardDirection);
                float scale = 0.7f;
                if (isBigBoss) scale *= 2.0f;
                fishMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationY((float)MathHelper.Pi * 2) *
                                    Matrix.CreateFromQuaternion(qRotation) *
                                    Matrix.CreateTranslation(Position);
                clipPlayer.update(gameTime.ElapsedGameTime, true, fishMatrix);
            }
        }