public override void Enter()
        {
            _targetAngle = AntMath.AngleDeg(_control.Position, _blackboard.EnemyTank.Position);

            // Calc spawn point for the bullet.
            // This point should be outside the tank body,
            // otherwise this bullet will damage our self.
            var ang = _control.Tower.Angle * AntMath.RADIANS;
            var p   = _control.Position;

            p.x += 0.45f * Mathf.Cos(ang);
            p.y += 0.45f * Mathf.Sin(ang);

            // Spawn and execute the bullet.
            var        bullet = Game.Instance.SpawnBullet(p, _control.transform.parent);
            Quaternion q      = Quaternion.AngleAxis(_control.Tower.Angle, Vector3.forward);

            bullet.transform.rotation = q;
            bullet.Execute(_control.Tower.Angle);

            _control.Tower.TakeAmmo(1);
            _delay = 0.75f;

            _control.Tower.ShotEffect();
        }
    public override void Enter()
    {
        // Search base on the map.
        var go = GameObject.Find("Base");

        if (go != null)
        {
            // This action called if we don't see the base.
            // So try to find base select random position around
            // the base until we will found it.
            var basePos = go.transform.position;
            _targetPos = new Vector3(
                basePos.x + AntMath.RandomRangeFloat(-2.0f, 2.0f),
                basePos.y + AntMath.RandomRangeFloat(-2.0f, 2.0f),
                0.0f
                );

            // Calc target angle.
            _targetAngle  = AntMath.AngleDeg(_t.position, _targetPos);
            _t.rotation   = Quaternion.Euler(_t.rotation.x, _t.rotation.y, _targetAngle);
            _targetAngle *= Mathf.Deg2Rad;
        }
        else
        {
            Debug.Log("Base not found!");
            Finish();
        }
    }
        public void Update(float aDeltaTime, float aTimeScale)
        {
            if (_movement.gravity)
            {
                _velocity.x += _movement.gravityFactor.x * aDeltaTime * aTimeScale;
                _velocity.y += _movement.gravityFactor.y * aDeltaTime * aTimeScale;

                if (_movement.rotate)
                {
                    Angle = AntMath.AngleDeg(_velocity);
                }
            }
            else
            {
                _delta      = _particle.CurrentLifeTime / _particle.LifeTime;
                _angle      = Angle * AntMath.RADIANS;
                _velocity.x = _speed * Mathf.Cos(_angle);
                _velocity.y = _speed * Mathf.Sin(_angle);

                if (_movement.animateSpeed)
                {
                    _speed = AntMath.Lerp(_startSpeed, _endSpeed, _movement.speedCurve.Evaluate(_delta));
                }
                else
                {
                    _speed += _movement.accel * aDeltaTime * aTimeScale;
                    _speed *= _movement.drag;
                }
            }

            _position           = _transform.position;
            _position.x        += _velocity.x * aDeltaTime * aTimeScale;
            _position.y        += _velocity.y * aDeltaTime * aTimeScale;
            _transform.position = _position;
        }
Beispiel #4
0
 private void UpdateAngle(bool aForce = false)
 {
     _updateAngleInterval -= Time.deltaTime;
     if (_updateAngleInterval < 0.0f || aForce)
     {
         _updateAngleInterval = 0.2f;
         _targetAngle         = AntMath.AngleDeg((Vector2)_control.Position, _nextPoint);
     }
 }
Beispiel #5
0
 public override void Start()
 {
     // Считываем из памяти информацию о положении врага.
     if (_blackboard["EnemyVisible"].AsBool)
     {
         _targetAngle = AntMath.AngleDeg((Vector2)_control.Position,
                                         _blackboard["EnemyVisible_Pos"].AsVector2);
     }
 }
        public Vector2 GetOutputPoint(Vector2 aToPosition)
        {
            var   pos = Position;
            float ang = AntMath.AngleDeg(pos, aToPosition);

            return(new Vector2(
                       pos.x + 10.0f * Mathf.Cos((ang + 90.0f) * Mathf.Deg2Rad),
                       pos.y + 10.0f * Mathf.Sin((ang + 90.0f) * Mathf.Deg2Rad)
                       ));
        }
        public Vector2 GetInputPoint(AntAIBaseNode aFromNode)
        {
            var pos = Position;

            pos.x += rect.width * 0.5f;
            pos.y += rect.height * 0.5f;
            float ang = AntMath.AngleDeg(pos, aFromNode.Position);

            return(new Vector2(
                       pos.x - 10.0f * Mathf.Cos((ang + 90.0f) * Mathf.Deg2Rad),
                       pos.y - 10.0f * Mathf.Sin((ang + 90.0f) * Mathf.Deg2Rad)
                       ));
        }
Beispiel #8
0
 public bool IsSee(Vector2 aPoint)
 {
     if (AntMath.Distance(_t.position.x, _t.position.y, aPoint.x, aPoint.y) < radius)
     {
         float angle = AntMath.Angle(AntMath.AngleDeg(_t.position.x, _t.position.y, aPoint.x, aPoint.y));
         float diff  = AntMath.AngleDifferenceDeg(angle, Angle);
         if (AntMath.InRange(diff, lowerLimit, upperLimit))
         {
             if (Config.Instance.showVision)
             {
                 AntDrawer.DrawLine(_t.position.x, _t.position.y, aPoint.x, aPoint.y, Color.yellow);
             }
             return(true);
         }
     }
     return(false);
 }
    public override void Enter()
    {
        // Search base on the map.
        var go = GameObject.Find("Base");

        if (go != null)
        {
            _targetPos = go.transform.position;

            // Calc target angle.
            _targetAngle  = AntMath.AngleDeg(_t.position, _targetPos);
            _t.rotation   = Quaternion.Euler(_t.rotation.x, _t.rotation.y, _targetAngle);
            _targetAngle *= Mathf.Deg2Rad;
        }
        else
        {
            Debug.Log("Base not found!");
            Finish();
        }
    }
Beispiel #10
0
 public override void Enter()
 {
     // Setup target angle.
     _targetAngle = AntMath.AngleDeg(_control.Position, _blackboard.EnemyTank.Position);
     _control.StopMove();
 }
Beispiel #11
0
        public void GetConditions(AntAIAgent aAgent, AntAICondition aWorldState)
        {
            // Получаем список всех объектов которые необходимо отслеживать.
            if (_visualNodes == null)
            {
                _visualNodes = AntEngine.Current.GetNodes <VisualNode>();
            }

            // 1. Обновляем информацию о себе.
            // -------------------------------
            aWorldState.Set(aAgent.planner, "ArmedWithGun", control.Tower.HasGun);
            aWorldState.Set(aAgent.planner, "ArmedWithBomb", control.Tower.HasBomb);
            aWorldState.Set(aAgent.planner, "HasAmmo", control.Tower.HasAmmo);
            aWorldState.Set(aAgent.planner, "Injured", (health.HP != health.maxHP));
            aWorldState.Set(aAgent.planner, "EnemyAlive", true);             // Наш враг всегда жив, потому что респавнится.
            aWorldState.Set(aAgent.planner, "Alive", (health.HP > 0.0f));
            aWorldState.Set(aAgent.planner, "HasObstacle", sensor.HasObstacle);

            if (sensor.HasObstacle)
            {
                sensor.HasObstacle = false;
            }

            // 2. Обрабатываем зрение.
            // -----------------------
            // Сбрасываем состояние всех возможных значений зрения.
            aWorldState.Set(aAgent.planner, "NearEnemy", false);
            aWorldState.Set(aAgent.planner, "EnemyVisible", false);
            aWorldState.Set(aAgent.planner, "GunInlineOfSight", false);
            aWorldState.Set(aAgent.planner, "AmmoInlineOfSight", false);
            aWorldState.Set(aAgent.planner, "BombInlineOfSight", false);
            aWorldState.Set(aAgent.planner, "HealInlineOfSight", false);

            VisualNode visual;

            // Перебираем все объекты которые можно просматривать.
            for (int i = 0, n = _visualNodes.Count; i < n; i++)
            {
                visual = _visualNodes[i];
                // Если объект из другой группы.
                if (vision.group != visual.Visual.group)
                {
                    // Если объект попадает в область зрения.
                    if (vision.IsSee(visual.entity.Position))
                    {
                        blackboard[visual.Visual.conditionName].AsBool = true;
                        blackboard[string.Concat(visual.Visual.conditionName, "_Pos")].AsVector2 = visual.entity.Position;

                        // Отмечаем что видим.
                        aWorldState.Set(aAgent.planner, visual.Visual.conditionName, true);

                        if (vision.enemyGroup == visual.Visual.group &&
                            AntMath.Distance(control.Position, visual.entity.Position) < 1.5f)
                        {
                            aWorldState.Set(aAgent.planner, "NearEnemy", true);
                        }
                    }
                }
            }

            // 3. Обрабатываем наведение пушки на врага.
            // -----------------------------------------
            aWorldState.Set(aAgent.planner, "EnemyLinedUp", false);
            if (aWorldState.Has(aAgent.planner, "EnemyVisible") && control.Tower.HasGun)
            {
                if (blackboard["EnemyVisible"].AsBool)
                {
                    float angle = AntMath.AngleDeg((Vector2)control.Position, blackboard["EnemyVisible_Pos"].AsVector2);
                    if (AntMath.Equal(AntMath.Angle(control.Tower.Angle), AntMath.Angle(angle), 10.0f))
                    {
                        aWorldState.Set(aAgent.planner, "EnemyLinedUp", true);
                    }
                }
            }
        }
        private void UpdateMovement()
        {
            if (AntMath.Distance(_currentPoint, (Vector2)_t.position) < 0.5f)
            {
                // Arrived to the current way point.
                _pointIndex++;
                if (_pointIndex < _route.Count)
                {
                    // Move to next one.
                    _currentPoint = _route[_pointIndex];
                }
                else
                {
                    // This is end of the way.
                    float dist = AntMath.Distance(_currentPoint, (Vector2)_t.position);
                    if (dist < 0.5f)
                    {
                        // Enable break.
                        _speed   = AntMath.Lerp(_speed, 0.0f, 1.0f - breakCurve.Evaluate(dist / 0.5f));
                        _isBrake = true;
                    }

                    if (AntMath.Equal(_speed, 0.0f, 0.1f))
                    {
                        // Absolutely arrived.
                        StopMove();
                        if (EventArrived != null)
                        {
                            EventArrived(this);
                        }
                    }
                }

                _steeringTime = 0.0f;
                _isSteering   = false;
            }

            float targetAngle = AntMath.Angle(AntMath.AngleDeg(_t.position, _currentPoint));

            _debugTargetAngle = targetAngle * AntMath.RADIANS;
            float angleDiff = AntMath.AngleDifference(Angle, targetAngle) * AntMath.DEGREES;

            // If our direction incorrect.
            if (!AntMath.Equal(angleDiff, 0.0f, 0.01f) && !_isSteering)
            {
                // Correct our angle to the current way point.
                _isSteering        = true;
                _steeringTime      = 0.0f;
                _totalSteeringTime = totalSteeringTime * (1.0f - Mathf.Abs(angleDiff / 360.0f));
            }

            // Acceleration!
            if (!_isBrake && _accelerationTime < totalAccelTime)
            {
                _accelerationTime += Time.deltaTime;
                _speed             = AntMath.Lerp(_speed, moveSpeed, accelCurve.Evaluate(_accelerationTime / totalAccelTime));
            }

            // Correction of the angle.
            if (_isSteering)
            {
                _steeringTime += Time.deltaTime;
                Angle          = AntMath.LerpAngleDeg(Angle, targetAngle, steeringCurve.Evaluate(_steeringTime / _totalSteeringTime));
                if (AntMath.Equal(angleDiff, 0.0f, 0.01f))
                {
                    _isSteering   = false;
                    _steeringTime = 0.0f;
                }
            }

            // Movement.
            float ang = Angle * AntMath.RADIANS;

            Velocity = new Vector2(_speed * Mathf.Cos(ang), _speed * Mathf.Sin(ang));
        }
        public void CollectConditions(AntAIAgent aAgent, AntAICondition aWorldState)
        {
            // 1. Remove all stored data from previous ticks.
            // ----------------------------------------------
            ClearSensors();

            // 2. Get fresh Vision and Touch data.
            // -----------------------------
            UpdateVision();
            UpdateTouch();

            // 3. Update World State.
            // ----------------------
            aWorldState.Set(TankScenario.Alive, true);
            aWorldState.Set(TankScenario.Injured, (_control.Health < _control.maxHealth));
            aWorldState.Set(TankScenario.EnemyAlive, true);             // All time is true ;)

            aWorldState.Set(TankScenario.HasGun, _control.Tower.IsHasGun);
            aWorldState.Set(TankScenario.HasAmmo, _control.Tower.IsHasAmmo);
            aWorldState.Set(TankScenario.HasBomb, _control.Tower.IsHasBomb);

            // Reset items visibility.
            aWorldState.Set(TankScenario.SeeGun, false);
            aWorldState.Set(TankScenario.SeeAmmo, false);
            aWorldState.Set(TankScenario.SeeBomb, false);
            aWorldState.Set(TankScenario.SeeRepair, false);

            // Update vision for items.
            for (int i = 0; i < SEE_ITEMS_COUNT; i++)
            {
                if (_seeItems[i] != null)
                {
                    // Adds founded spawner and item to the our memory.
                    // This data maybe will be required by bot in the near future.
                    _blackboard.TrackSpawner(_seeItems[i].Position, _seeItems[i].kind);
                    _blackboard.TrackItem(_seeItems[i], _seeItems[i].kind);

                    // Update the world state.
                    switch (_seeItems[i].kind)
                    {
                    case ItemKind.Gun:
                        aWorldState.Set(TankScenario.SeeGun, true);
                        break;

                    case ItemKind.Ammo:
                        aWorldState.Set(TankScenario.SeeAmmo, true);
                        break;

                    case ItemKind.Bomb:
                        aWorldState.Set(TankScenario.SeeBomb, true);
                        break;

                    case ItemKind.Repair:
                        aWorldState.Set(TankScenario.SeeRepair, true);
                        break;
                    }
                }
            }

            // Update vision for enemies.
            aWorldState.Set(TankScenario.SeeEnemy, false);

            for (int i = 0; i < TANKS_COUNT; i++)
            {
                if (_seeTanks[i] != null)
                {
                    _blackboard.TrackTank(_seeTanks[i]);
                    aWorldState.Set(TankScenario.SeeEnemy, true);
                }
            }

            // Check the enemy on line of the fire.
            aWorldState.Set(TankScenario.OnLineofFire, false);

            if (_blackboard.HasEnemy)
            {
                float angle = AntMath.AngleDeg(_control.Position, _blackboard.EnemyTank.Position);
                if (AntMath.Equal(AntMath.Angle(angle), AntMath.Angle(_control.Tower.Angle), 10.0f))
                {
                    aWorldState.Set(TankScenario.OnLineofFire, true);
                }
            }

            // Check the touching of enemy tanks.
            aWorldState.Set(TankScenario.NearEnemy, false);

            for (int i = 0; i < TANKS_COUNT; i++)
            {
                if (_touchTanks[i] != null)
                {
                    aWorldState.Set(TankScenario.NearEnemy, true);
                    break;
                }
            }
        }