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); }
public void DisableMove() { _moveEnabled = false; _moveManager.CancelMove(); }