private IEnumerator <MoveDescriptor> FollowMoveKeyPoints(Stack <RoadData> moveKeyPoints, RoadData finalDestination, RetryData retryData)
    {
        RoadData lastKeyPoint = occupiedRoad;

        foreach (RoadData keyPoint in moveKeyPoints)
        {
            if (keyPoint != null && keyPoint.Neighbors().Contains(occupiedRoad))
            {
                AnticipateNextOrientation(occupiedRoad, keyPoint, _moveManager.orientation);
            }

            RoadData lastRoad = occupiedRoad;
            while (occupiedRoad != keyPoint)
            {
                string           currentOrientation = _moveManager.orientation;
                Stack <RoadData> roadPath           = RoadsPathfinding.RoadPathStar(keyPoint, occupiedRoad, _keyPointsModulo, currentOrientation, finalDestination);

                if (roadPath == null)//On annule cet énumérateur et on relance la recherche
                {
                    if (retryData == null)
                    {
                        retryData = new RetryData(lastKeyPoint, finalDestination);
                    }

                    retryData.IncrementCounter();

                    _moveManager.CancelMove();

                    if (retryData.triesCounter == MAX_MOVE_TRIES)
                    {
                        onStuckEvent.Invoke(retryData);
                    }
                    else
                    {
                        MoveTo(finalDestination, UnityEngine.Random.Range(0.25f, 1.5f), retryData); //Ce qui relance donc une coroutine qui va s'occuper de ça!
                    }
                    yield break;
                }
                else if (roadPath.Count == 0)
                {
                    break; //Si le roadPath est vide, c'est qu'on est déjà à destination, ou suffisamment proche de celle-ci pour passer au prochain keyPoint
                }

                RoadData nextRoad = roadPath.Pop();

                if (nextRoad != lastRoad || UnityEngine.Random.Range(1, 100) == 1)
                {
                    foreach (RoadData toReserve in roadPath)
                    {
                        toReserve.roadLock.reservationsNber++;
                    }

                    MoveDescriptor toApply = new MoveDescriptor(nextRoad.transform.position, occupiedRoad.transform.position, speed, 0.1f);

                    string orientationToUnlock = currentOrientation;

                    if (MovementWithoutUnshift(occupiedRoad.roadLock, currentOrientation, toApply))//Partage la case avec un autre dans une orientation contraire
                    {
                        _moveManager.UseShiftForMovement(toApply);
                    }
                    else if (occupiedRoad.roadLock.split != RoadLock.DIAGONAL_SPLIT)//!NoNeedToRelock())
                    {
                        occupiedRoad.roadLock.UnlockFor(currentOrientation, gameObject);
                        occupiedRoad.roadLock.LockFor(toApply.orientation, gameObject);
                        orientationToUnlock = toApply.orientation;
                    }

                    nextRoad.roadLock.LockFor(toApply.orientation, gameObject);
                    //+++++> C'est la ligne ci-dessus qui est chiante: avec un diag split, on risque de relocker dans la mme direction que le contenu principal...>TROUVER UNE SOLUTION
                    //>>>> cas de double split à gérer via une condition spéciale (offre spéciale, SUPER PROMO) dans le RoadLock (avec qques var globales :/)

                    yield return(toApply);

                    lastRoad = occupiedRoad;
                    occupiedRoad.roadLock.UnlockFor(orientationToUnlock, gameObject);
                    occupiedRoad = nextRoad;

                    foreach (RoadData toFree in roadPath)
                    {
                        toFree.roadLock.reservationsNber--;
                    }

                    if (roadPath.Count != 0)//Donc, s'il y a encore une case sur laquelle bouger par la suite jusqu'au prochain keypoint
                    {
                        RoadData secondNextRoad = roadPath.Pop();
                        AnticipateNextOrientation(nextRoad, secondNextRoad, toApply.orientation);
                    }
                }
                else
                {
                    yield return(null);
                }
            }

            lastKeyPoint = keyPoint;
        }

        yield return(null);
    }
Beispiel #2
0
 public void DisableMove()
 {
     _moveEnabled = false;
     _moveManager.CancelMove();
 }