Пример #1
0
        public override void Execute(float aDeltaTime, float aTimeScale)
        {
            // Aim on the target.
            if (!AntMath.Equal(AntMath.Angle(_control.towerRef.Angle), AntMath.Angle(_targetAngle), 1.0f))
            {
                float curAng = AntMath.Angle(_control.towerRef.Angle);
                float tarAng = AntMath.Angle(_targetAngle);
                if (Mathf.Abs(curAng - tarAng) > 180.0f)
                {
                    if (curAng > tarAng)
                    {
                        tarAng += 360.0f;
                    }
                    else
                    {
                        tarAng -= 360.0f;
                    }
                }

                if (curAng < tarAng)
                {
                    _control.RotateTower(1.0f, aDeltaTime);
                }
                else if (curAng > tarAng)
                {
                    _control.RotateTower(-1.0f, aDeltaTime);
                }
            }
            else
            {
                Finish();
            }
        }
Пример #2
0
        protected bool OnMove()
        {
            if (Config.Instance.showCurrentWay)
            {
                DrawWay();
            }

            // Достигли текущей точки!
            if (AntMath.Distance((Vector2)_control.Position, _nextPoint) < WayMap.Current.approachRadius)
            {
                NextPoint();
            }

            // Рулежка.
            UpdateAngle();
            if (!AntMath.Equal(AntMath.Angle(_control.Angle), AntMath.Angle(_targetAngle), 1.0f))
            {
                float curAng = AntMath.Angle(_control.Angle);
                float tarAng = AntMath.Angle(_targetAngle);
                if (Mathf.Abs(curAng - tarAng) > 180.0f)
                {
                    if (curAng > tarAng)
                    {
                        tarAng += 360.0f;
                    }
                    else
                    {
                        tarAng -= 360.0f;
                    }
                }

                if (curAng < tarAng)
                {
                    _control.isLeft  = true;
                    _control.isRight = false;
                }
                else if (curAng > tarAng)
                {
                    _control.isLeft  = false;
                    _control.isRight = true;
                }
            }
            else
            {
                _control.isLeft  = false;
                _control.isRight = false;

                // Газ.
                if (!_isWayFinished)
                {
                    _control.isForward = true;
                }
                else
                {
                    _control.isForward = false;
                }
            }

            return(_isWayFinished);
        }
 private int FindVertex(Vector2 aPoint)
 {
     for (int i = 0, n = _self.vertices.Count; i < n; i++)
     {
         if (AntMath.Equal(_self.vertices[i], aPoint))
         {
             return(i);
         }
     }
     return(-1);
 }
 public int FindEdge(Vector2 aA, Vector2 aB)
 {
     for (int i = 0, n = _self.edges.Count; i < n; i++)
     {
         if (AntMath.Equal(_self.vertices[_self.edges[i].a], aA) &&
             AntMath.Equal(_self.vertices[_self.edges[i].b], aB))
         {
             return(i);
         }
     }
     return(-1);
 }
        public override void Drag(Vector2 aDelta)
        {
            var oldPos = rect.position;

            base.Drag(aDelta);
            if (!AntMath.Equal(oldPos.x, rect.position.x) ||
                !AntMath.Equal(oldPos.y, rect.position.y))
            {
                _action.position = rect.position;
                EditorUtility.SetDirty(_scenario);
            }
        }
Пример #6
0
        private void AddPointToList(ref List <Vector2> aList, Vector2 aPoint)
        {
            for (int i = 0, n = aList.Count; i < n; i++)
            {
                if (AntMath.Equal(aList[i], aPoint))
                {
                    // This point already exists in the list, skip.
                    return;
                }
            }

            aList.Add(aPoint);
        }
Пример #7
0
        public void Reset(AntEmitter aEmitter)
        {
            IsActive      = Preset.scale.animateScale;
            _endScale     = Preset.scale.endScale;
            _startScale   = Vector2.zero;
            _startScale.x = Preset.scale.startScale.x + AntMath.RandomRangeFloat(Preset.scale.rndToScaleX);
            _startScale.y = Preset.scale.startScale.y + AntMath.RandomRangeFloat(Preset.scale.rndToScaleY);
            _curveX       = Preset.scale.scaleCurveX;
            _curveY       = Preset.scale.scaleCurveY;
            _useChild     = Preset.scale.useChildSprite;
            _proportional = Preset.scale.proportional;

            if (Preset.scale.effectLifeTime && !AntMath.Equal(_particle.Effect.lifeTime, 0.0f))
            {
                _delta        = _particle.Effect.Duration / _particle.Effect.TotalDuration;
                _delta        = AntMath.TrimToRange(_delta, 0.0f, 1.0f);
                _startScale.x = AntMath.Lerp(_startScale.x, Preset.scale.endScale.x, _curveX.Evaluate(_delta));
                _startScale.y = AntMath.Lerp(_startScale.y, Preset.scale.endScale.y, _curveY.Evaluate(_delta));
            }

            if (Preset.scale.useChildSprite)
            {
                _childTransform.localScale = new Vector3(
                    _startScale.x,
                    (Preset.scale.proportional)
                                                ? _startScale.x
                                                : _startScale.y,
                    1.0f
                    );
            }
            else
            {
                _transform.localScale = new Vector3(
                    _startScale.x,
                    (Preset.scale.proportional)
                                                ? _startScale.x
                                                : _startScale.y,
                    1.0f
                    );
            }
        }
        private void MergeNodes()
        {
            // _notFoundEdges.Clear();
            for (int i = 0, n = _from.Count; i < n; i++)
            {
                if (!AntMath.Equal(_to[i], _from[i]))
                {
                    int fromNode = _self.FindNodeByPoint(_from[i]);
                    int toNode   = _self.FindNodeByPoint(_to[i]);
                    if (toNode > -1)
                    {
                        var edges  = new int[2];
                        var center = _self.GetNodeCenter(toNode);
                        if (IsPossibleMergeTriangles(_from[i], center, ref edges))
                        {
                            var a = _self.vertices[_self.edges[edges[0]].a];
                            var b = _self.vertices[_self.edges[edges[0]].b];
                            var c = _self.vertices[_self.edges[edges[1]].a];
                            var d = _self.vertices[_self.edges[edges[1]].b];
                            if (!MergeEdgesIfNotCrossing(a, c, b, d, fromNode, toNode))
                            {
                                if (!MergeEdgesIfNotCrossing(b, c, a, d, fromNode, toNode))
                                {
                                    if (!MergeEdgesIfNotCrossing(b, d, a, c, fromNode, toNode))
                                    {
                                        MergeEdgesIfNotCrossing(a, d, b, c, fromNode, toNode);
                                    }
                                }
                            }
                        }
                    }
                }

                _to[i] = _from[i];
            }
        }
Пример #9
0
        public override void Update(float aDeltaTime)
        {
            // Процесс наведения на цель.
            if (!AntMath.Equal(AntMath.Angle(_control.Tower.Angle), AntMath.Angle(_targetAngle), 1.0f))
            {
                float curAng = AntMath.Angle(_control.Tower.Angle);
                float tarAng = AntMath.Angle(_targetAngle);
                if (Mathf.Abs(curAng - tarAng) > 180.0f)
                {
                    if (curAng > tarAng)
                    {
                        tarAng += 360.0f;
                    }
                    else
                    {
                        tarAng -= 360.0f;
                    }
                }

                if (curAng < tarAng)
                {
                    _control.isTowerLeft  = true;
                    _control.isTowerRight = false;
                }
                else if (curAng > tarAng)
                {
                    _control.isTowerLeft  = false;
                    _control.isTowerRight = true;
                }
            }
            else
            {
                _control.isTowerLeft  = false;
                _control.isTowerRight = false;
            }
        }
Пример #10
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);
                    }
                }
            }
        }
Пример #11
0
        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));
        }
        private void OnSceneGUI()
        {
            bool isDirty = false;
            // bool isRemovePressed = ((Event.current.modifiers & (EventModifiers.Command | EventModifiers.Control)) != 0);
            bool isLinkPressed   = ((Event.current.modifiers & EventModifiers.Command) != 0);
            bool isRemovePressed = ((Event.current.modifiers & EventModifiers.Control) != 0);
            bool isAddPressed    = ((Event.current.modifiers & EventModifiers.Shift) != 0);

            // DEBUG POINTS.
            // -------------

            // From Point.
            Handles.color = Color.blue;
            var delta_d = DotHandle(_self.fromPoint) - _self.fromPoint;

            if (delta_d != Vector2.zero)
            {
                _self.fromPoint += delta_d;
            }

            // To Point.
            Handles.color = Color.red;
            delta_d       = DotHandle(_self.toPoint) - _self.toPoint;
            if (delta_d != Vector2.zero)
            {
                _self.toPoint += delta_d;
            }

            // Merge nodes.
            // ------------
            if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
            {
                MergeNodes();
            }

            Handles.matrix = _self.transform.localToWorldMatrix;
            DrawMesh();

            if (!_self.editMesh)
            {
                return;
            }

            // Is pressed hotkey for linking nodes (command key).
            // --------------------------------------------------
            if (isLinkPressed)
            {
                if (_from.Count != _self.nodes.Count)
                {
                    _from.Clear();
                    _to.Clear();
                    for (int i = 0, n = _self.nodes.Count; i < n; i++)
                    {
                        _from.Add(_self.GetNodeCenter(i));
                        _to.Add(_from[_from.Count - 1]);
                    }
                }

                Handles.color = Color.yellow;
                for (int i = 0, n = _to.Count; i < n; i++)
                {
                    var p     = _to[i];
                    var delta = DotHandle(p) - p;
                    if (delta != Vector2.zero)
                    {
                        _to[i] = p + delta;
                    }

                    if (!AntMath.Equal(_to[i], _from[i]))
                    {
                        Handles.DrawLine(_from[i], _to[i]);
                        int nodeIndex = _self.FindNodeByPoint(_to[i]);
                        if (nodeIndex > -1)
                        {
                            var edges  = new int[2];
                            var center = _self.GetNodeCenter(nodeIndex);
                            DrawLinks(nodeIndex);
                            if (IsPossibleMergeTriangles(_from[i], center, ref edges))
                            {
                                Handles.color = Color.green;
                                var a = _self.vertices[_self.edges[edges[0]].a];
                                var b = _self.vertices[_self.edges[edges[0]].b];
                                var c = _self.vertices[_self.edges[edges[1]].a];
                                var d = _self.vertices[_self.edges[edges[1]].b];
                                if (!DrawEdgesIfNotCrossing(a, c, b, d))
                                {
                                    if (!DrawEdgesIfNotCrossing(b, c, a, d))
                                    {
                                        if (!DrawEdgesIfNotCrossing(b, d, a, c))
                                        {
                                            DrawEdgesIfNotCrossing(a, d, b, c);
                                        }
                                    }
                                }
                                Handles.color = Color.yellow;
                            }
                        }
                    }
                }
            }

            // If pressed hotkey for removing nodes (triangles).
            // -------------------------------------------------
            else if (isRemovePressed)
            {
                Handles.color = Color.red;
                Vector2 center;
                for (int i = 0, n = _self.nodes.Count; i < n; i++)
                {
                    center = _self.GetNodeCenter(i);
                    if (Handles.Button(center, Quaternion.identity, 0.05f, 0.05f, Handles.DotHandleCap))
                    {
                        RemoveNode(i);
                        isDirty = true;
                        break;
                    }
                }
            }

            // Pressed hotkey for adding new nodes (triangles).
            // ------------------------------------------------
            else if (isAddPressed)
            {
                var mouse = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
                var p     = _self.transform.InverseTransformPoint(mouse);
                // var pos = (Vector2) _self.transform.position;

                Handles.color = Color.white;
                int nearEdge = _self.GetNearEdge(p);
                if (nearEdge > -1)
                {
                    Handles.DrawDottedLine(_self.vertices[_self.edges[nearEdge].a], p, 1.0f);
                    Handles.DrawDottedLine(_self.vertices[_self.edges[nearEdge].b], p, 1.0f);

                    if (Handles.Button(p, Quaternion.identity, 0.05f, 0.05f, Handles.DotHandleCap))
                    {
                        var newVertex = AddVertex(p.x, p.y);

                        var edges = new int[2];
                        edges[0] = AddEdge(_self.edges[nearEdge].a, newVertex);
                        edges[1] = AddEdge(newVertex, _self.edges[nearEdge].b);

                        var newNode = AddNode(nearEdge, edges[0], edges[1]);
                        var e       = _self.edges[nearEdge];
                        e.AddNeighbor(newNode);
                        _self.edges[nearEdge] = e;

                        isDirty = true;
                    }

                    // Handles.color = Color.white;
                    // float s = HandleUtility.GetHandleSize(p) * 0.05f;
                    // for (int i = 0, n = _self.vertices.Count; i < n; i++)
                    // {
                    //  Handles.DotHandleCap(0, _self.vertices[i], Quaternion.identity, s, EventType.DragUpdated);
                    // }
                }
            }

            // Simple editing the NavMesh.
            // ---------------------------
            else
            {
                Handles.color = Color.white;
                for (int i = 0, n = _self.vertices.Count; i < n; i++)
                {
                    var p     = _self.vertices[i];
                    var delta = DotHandle(p) - p;
                    if (delta != Vector2.zero)
                    {
                        _self.vertices[i] = p + delta;
                        isDirty           = true;
                    }
                }

                // float dist;
                // float ang;
                // Vector2 pa, pb;
                // Vector2 center = Vector2.zero;
                // Handles.color = Color.green;
                // for (int i = 0, n = _self.edges.Count; i < n; i++)
                // {
                //  // if (_self.edges[i].hasNeigbors)
                //  //  continue;

                //  pa = _self.vertices[_self.edges[i].a];
                //  pb = _self.vertices[_self.edges[i].b];
                //  dist = AntMath.Distance(pa, pb) * 0.5f;
                //  ang = AntMath.AngleRad(pa, pb) - 90.0f * Mathf.Deg2Rad;
                //  center = new Vector2((pa.x + pb.x) * 0.5f, (pa.y + pb.y) * 0.5f);
                //  if (Handles.Button(center, Quaternion.identity, 0.05f, 0.05f, Handles.DotHandleCap))
                //  {
                //      // AntGeo.ExpandSegment(pa, pb, ref _c, ref _d, 100.0f);
                //      // AntLog.Trace(_self.edges[i].nodeA, _self.edges[i].nodeB, _self.edges[i].HasNeigbors);
                //      var newVertex = _self.AddVertex(
                //          center.x + dist * Mathf.Cos(ang),
                //          center.y + dist * Mathf.Sin(ang)
                //      );

                //      var edges = new int[2];
                //      edges[0] = _self.AddEdge(_self.edges[i].a, newVertex);
                //      edges[1] = _self.AddEdge(newVertex, _self.edges[i].b);

                //      var newNode = _self.AddNode(i, edges[0], edges[1]);
                //      var e = _self.edges[i];
                //      e.AddNeighbor(newNode);
                //      _self.edges[i] = e;

                //      // var edge = _self.edges[i];
                //      // _self.edges[i] = edge;
                //      isDirty = true;
                //  }
                // }
            }

            if (isDirty)
            {
                EditorUtility.SetDirty(target);
            }
        }
        private bool MergeEdgesIfNotCrossing(Vector2 aA, Vector2 aB, Vector2 aC, Vector2 aD, int aFrom, int aTo)
        {
            // Link two nodes only. (?)
            // if ((AntMath.Equal(aA, aC) && AntMath.Equal(aB, aD)) ||
            //  (AntMath.Equal(aA, aD) && AntMath.Equal(aB, aC)))
            // {
            //  AntLog.Trace("Merge two edges!");
            //  return true;
            // }

            // Create one new node.
            // --------------------
            var v = new Vector2[] { aA, aB, aC, aD };

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (i != j && AntMath.Equal(v[i], v[j]))
                    {
                        // Remove shared vertex.
                        AntArray.RemoveAt <Vector2>(ref v, i);

                        var edges = new int[3];
                        edges[0] = GetEdge(v[0], v[1]);
                        edges[1] = GetEdge(v[1], v[2]);
                        edges[2] = GetEdge(v[2], v[0]);

                        var node = AddNode(edges[0], edges[1], edges[2]);
                        LinkNodes(aFrom, node);
                        LinkNodes(node, aTo);

                        var center   = _self.GetNodeCenter(node);
                        var testNode = _self.FindNodeByPoint(center);
                        if (testNode != node)
                        {
                            // The triangle turned inside out, recreate.
                            RemoveNode(node);

                            edges[0] = GetEdge(v[0], v[2]);
                            edges[1] = GetEdge(v[2], v[1]);
                            edges[2] = GetEdge(v[1], v[0]);

                            node = AddNode(edges[0], edges[1], edges[2]);
                            LinkNodes(aFrom, node);
                            LinkNodes(node, aTo);

                            center   = _self.GetNodeCenter(node);
                            testNode = _self.FindNodeByPoint(center);
                            if (testNode != node)
                            {
                                // The triangle turned inside out, recreate.
                                RemoveNode(node);

                                edges[0] = GetEdge(v[1], v[2]);
                                edges[1] = GetEdge(v[2], v[0]);
                                edges[2] = GetEdge(v[0], v[1]);

                                node = AddNode(edges[0], edges[1], edges[2]);
                                LinkNodes(aFrom, node);
                                LinkNodes(node, aTo);

                                center   = _self.GetNodeCenter(node);
                                testNode = _self.FindNodeByPoint(center);
                                if (testNode != node)
                                {
                                    A.Warning("Wrong triangle! ({0})", node);
                                }
                            }
                        }

                        return(true);
                    }
                }
            }

            // Create two new nodes.
            // ---------------------
            if (!AntGeo.LinesCross(aA, aB, aC, aD))
            {
                var edges = new int[5];
                edges[0] = GetEdge(aA, aB);
                edges[1] = GetEdge(aB, aD);
                edges[2] = GetEdge(aD, aA);
                edges[3] = GetEdge(aA, aC);
                edges[4] = GetEdge(aC, aD);

                var nodeA = AddNode(edges[0], edges[1], edges[2]);
                var nodeB = AddNode(edges[3], edges[4], edges[2]);
                LinkNodes(aFrom, nodeA);
                LinkNodes(nodeA, nodeB);
                LinkNodes(nodeB, aTo);
                return(true);
            }

            return(false);
        }
Пример #14
0
        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;
                }
            }
        }
Пример #15
0
        public List <Vector2> FindWay(WayPoint aCurrent, WayPoint aGoal)
        {
            List <WayPoint> opened = new List <WayPoint>();
            List <WayPoint> closed = new List <WayPoint>();

            aCurrent.parent    = null;
            aCurrent.cost      = 0.0f;
            aCurrent.heuristic = aCurrent.Heuristic(aGoal);
            aCurrent.sum       = aCurrent.heuristic;
            opened.Add(aCurrent);

            WayPoint current;

            while (opened.Count > 0)
            {
                current = opened[0];
                for (int i = 1, n = opened.Count; i < n; i++)
                {
                    if (opened[i].sum < current.sum)
                    {
                        current = opened[i];
                    }
                }

                opened.Remove(current);

                if (AntMath.Equal(current.position, aGoal.position))
                {
                    return(GetPath(current));
                }

                closed.Add(current);

                WayPoint neighbor;
                int      openedIndex = -1;
                int      closedIndex = -1;
                float    cost        = 0.0f;
                for (int i = 0, n = current.neighbors.Count; i < n; i++)
                {
                    cost = current.cost + current.neighbors[i].cost;

                    neighbor = current.neighbors[i];

                    openedIndex = opened.IndexOf(neighbor);
                    closedIndex = closed.IndexOf(neighbor);

                    if (openedIndex > -1 && cost < opened[openedIndex].cost)
                    {
                        opened.RemoveAt(openedIndex);
                        openedIndex = -1;
                    }

                    if (closedIndex > -1 && cost < closed[closedIndex].cost)
                    {
                        closed.RemoveAt(closedIndex);
                        closedIndex = -1;
                    }

                    if (openedIndex == -1 && closedIndex == -1)
                    {
                        neighbor.cost      = cost;
                        neighbor.heuristic = neighbor.Heuristic(aGoal);
                        neighbor.sum       = cost + neighbor.heuristic;
                        neighbor.parent    = current;
                        opened.Add(neighbor);
                    }
                }
            }
            return(null);
        }