コード例 #1
0
    /**
     * Déclenche (via une coroutine) le mouvement du transporteur vers la maison la
     * plus proche (sur le réseau routier), où il sera détruit (utile pour se
     * débarrasser des transporteurs dont le bâtiment principal est détruit).
     * Le stock sera alors perdu. Si aucune maison n'est disponible, le
     * transporteur ne bouge pas, et la coroutine va continuer d'attendre une
     * maison vers laquelle se rendre.
     **/
    private IEnumerator GoHome()
    {
        RoadRouteManager roadRouteManager = GetComponent <RoadRouteManager>();

        while (true)
        {
            //TODO utiliser un findNearestObjectWithPath (Utils) pour être plus générique.
            GameObject[] homesArray = GameObject.FindGameObjectsWithTag("Home");

            float         minDistance   = 0.0f;
            FreightAreaIn nearestHomeIn = null;
            foreach (GameObject home in homesArray)
            {
                FreightAreaIn homeIn = home.GetComponent <BuildingStock>().freightAreaData.freightAreaIn;

                float distance = RoadsPathfinding.RealDistanceBetween(homeIn.road, roadRouteManager.occupiedRoad);
                if (distance > 0.0f && (nearestHomeIn == null || minDistance > distance))
                {
                    minDistance   = distance;
                    nearestHomeIn = homeIn;
                }
                yield return(null);
            }

            if (nearestHomeIn != null)//Sinon, c'est qu'il n'y a AUCUNE maison satisfaisante, et la boucle principale se charge de relancer la recherche
            {
                destination = nearestHomeIn.GetComponentInParent <BuildingStock>();
                roadRouteManager.MoveTo(destination.freightAreaData.freightAreaIn.road, Random.Range(0.5f, 3.0f), null);
                yield break;
            }

            yield return(null);
        }
    }
コード例 #2
0
ファイル: Home.cs プロジェクト: Gonuhe/EternityKnights
    private IEnumerator SortAvailableKeepAsideOrderManagersByDistance(Cell <PriorityQueue <float, KeepAsideOrderManager> > rslt)
    {
        StockManager stockManager = GameManager.instance.cityBuilderData.stockManager;

        PriorityQueue <float, KeepAsideOrderManager> rsltQueue           = new PriorityQueue <float, KeepAsideOrderManager>();
        IEnumerator <KeepAsideOrderManager>          keepAsideEnumerator = stockManager.AllKeepAsideOrderManagers();

        while (keepAsideEnumerator.MoveNext())
        {
            KeepAsideOrderManager keepAsideManager = keepAsideEnumerator.Current;

            if (keepAsideManager != null)//On vérifie s'il n'a pas été détruit
            {
                float distance = Vector2.Distance(transform.position, keepAsideManager.transform.position);

                if (distance <= keepAsideManager.availabilityRange)//Pour éviter les calculs inutiles ; si ce n'est pas le cas, il est de toute façon trop loin
                {
                    FreightAreaIn  inArea  = keepAsideManager.freightAreaData.freightAreaIn;
                    FreightAreaOut outHome = freightAreaData.freightAreaOut;

                    float roadDistance = RoadsPathfinding.RealDistanceBetween(inArea.road, outHome.road);

                    if (roadDistance > 0.0f && roadDistance <= keepAsideManager.availabilityRange)
                    {
                        rsltQueue.Push(roadDistance, keepAsideManager);
                    }
                }
            }

            yield return(null);
        }

        rslt.value = rsltQueue;
    }
コード例 #3
0
    /**
     * Coroutine à lancer pour trier selon leur distance (sur le réseau
     * routier) à cette route les bâtiments capable de recevoir des commandes.
     **/
    public IEnumerator SortOrderManagersByDistance(Cell <PriorityQueue <float, OrderManager> > rslt)
    {
        PriorityQueue <float, OrderManager> rsltQueue = new PriorityQueue <float, OrderManager>();
        StockManager stockManager = GameManager.instance.cityBuilderData.stockManager;
        IEnumerator <OrderManager> allOrderManagers = stockManager.AllOrderManagers();

        while (allOrderManagers.MoveNext())
        {
            OrderManager orderManager = allOrderManagers.Current;

            if (orderManager != null)
            {
                float realDistanceToOrderManager = RoadsPathfinding.RealDistanceBetween(this, orderManager.freightAreaData.freightAreaOut.road);
                if (realDistanceToOrderManager > 0.0f)
                {
                    rsltQueue.Push(realDistanceToOrderManager, orderManager);
                }
            }

            yield return(null);
        }

        rslt.value = rsltQueue;

        yield return(null);
    }
コード例 #4
0
ファイル: Prefect.cs プロジェクト: Gonuhe/EternityKnights
    public IEnumerator goOnTour(List <GameObject> toVisit)
    {
        if (prefecture != null)
        {
            List <GameObject> toReVisit = new List <GameObject>();
            toVisit.Remove(prefecture);
            _tour = TSP.GetItinary(prefecture, toVisit);
            GameObject _currentDestination;
            while (!_tour.IsEmpty())
            {
                _continueTour        = false;
                _tryAgainToVisitHome = 50;

                _currentDestination = _tour.Pop();
                goalFA = _currentDestination.GetComponentInChildren <FreightAreaIn>();
                if (goalFA != null && RoadsPathfinding.RealDistanceBetween(GetComponent <RoadRouteManager>().occupiedRoad, goalFA.road) != -1)
                //Il existe encore une route vers ce batiment
                {
                    GetComponent <RoadRouteManager>().MoveTo(goalFA.road);
                    yield return(new WaitUntil(() => _continueTour || goalFA == null || gameObject.GetComponent <RoadRouteManager>().occupiedRoad == goalFA.road));

                    if (goalFA != null && _continueTour)//On a pas pu atteindre la maison et on a choisi de la skipper
                    {
                        toReVisit.Add(goalFA.gameObject);
                    }
                    if (goalFA != null && !_continueTour)
                    {
                        Building building = _currentDestination.GetComponent <Building>();
                        if (building != null)
                        {
                            building.RestoreHealth();
                        }
                        GetComponent <SpriteRenderer>().enabled = false;//TODO il est toujours sur la FA et donc le lock est toujours activé !
                        yield return(new WaitForSeconds(Random.Range(2.0f, 5.0f)));

                        GetComponent <SpriteRenderer>().enabled = true;
                    }
                }
            }
            if (toReVisit.Count != 0 && _trytoRevisitCount-- != 0)
            {
                StartCoroutine(goOnTour(toReVisit));
            }
            else
            {
                StartCoroutine(GoBack());
            }
        }
    }
コード例 #5
0
    /**
     * Coroutine à lancer pour effectuer une recherche parmi les entrepôts disponibles
     * quel est le plus proche remplissant une condition donnée. Pour les calculs
     * de distance, ce sont ici les freight area d'ENTREE (in) qui sont utilisées, ATTENTION!
     **/
    public static IEnumerator FindNearestWarehouseSatisfyingCondition(RoadData startPoint, Func <Warehouse, bool> acceptanceFunction, Cell <Warehouse> rslt, HashSet <FreightAreaIn> toIgnore)
    {
        PriorityQueue <float, Warehouse> sortedWarehouses = new PriorityQueue <float, Warehouse>();
        IEnumerator <Warehouse>          allWarehouses    = GameManager.instance.cityBuilderData.stockManager.AllWarehouses();

        while (allWarehouses.MoveNext())
        {
            Warehouse warehouse = allWarehouses.Current;

            if (warehouse != null)// Car il peut avoir été détruit depuis le début de la coroutine !
            {
                FreightAreaIn warehouseIn = warehouse.orderManager.freightAreaData.freightAreaIn;
                if (!toIgnore.Contains(warehouseIn) && acceptanceFunction(warehouse))
                {
                    float distanceToWarehouse = Vector2.Distance(warehouseIn.transform.position, startPoint.transform.position);
                    sortedWarehouses.Push(distanceToWarehouse, warehouse);
                }
            }
        }

        if (!sortedWarehouses.IsEmpty())
        {
            Warehouse bestWarehouse = sortedWarehouses.Pop();
            float     pathDistance  = RoadsPathfinding.RealDistanceBetween(startPoint, bestWarehouse.orderManager.freightAreaData.freightAreaIn.road);

            yield return(null);

            while (!sortedWarehouses.IsEmpty() && (pathDistance > sortedWarehouses.LowestKey() || pathDistance < 0.0f))
            {
                Warehouse nearestAsTheCrowFlies = sortedWarehouses.Pop();
                float     newPathDistance       = RoadsPathfinding.RealDistanceBetween(startPoint, nearestAsTheCrowFlies.orderManager.freightAreaData.freightAreaIn.road);
                if (newPathDistance >= 0.0f && (newPathDistance < pathDistance || pathDistance < 0.0f))
                {
                    pathDistance  = newPathDistance;
                    bestWarehouse = nearestAsTheCrowFlies;
                }
                yield return(null);
            }

            if (pathDistance >= 0.0f)
            {
                rslt.value = bestWarehouse;
            }
        }
    }
コード例 #6
0
    //TODO faire une version avec une co-routine plus efficace (un pathfinding/frame)
    public static GameObject GetNearestObjectWithPath(RoadData origin, string tag, HashSet <GameObject> exclude)
    {
        GameObject[] objectsWithTag = GameObject.FindGameObjectsWithTag(tag);
        float        minDistance    = Mathf.Infinity;
        GameObject   nearest        = null;

        foreach (GameObject nearObject in objectsWithTag)
        {
            RoadData destinationRoadData = nearObject.GetComponentInChildren <FreightAreaIn>() == null ? null : nearObject.GetComponentInChildren <FreightAreaIn>().road;
            if (destinationRoadData != null && (exclude == null || (exclude != null && !exclude.Contains(nearObject))))
            {
                float distance = RoadsPathfinding.RealDistanceBetween(destinationRoadData, origin);

                if (distance != -1.0f && distance < minDistance)
                {
                    minDistance = distance;
                    nearest     = nearObject;
                }
            }
        }
        return(nearest);
    }
コード例 #7
0
ファイル: TSP.cs プロジェクト: Gonuhe/EternityKnights
    //TODO pour l'instant, pas de TSP, c'est un algo qui établi un itinéraire en prenant à chaque fois le gameObject le plus proche à vol d'oiseau du précédent.

    /**
     * Pré : origin doit avoir un RoadData
     * */
    public static PriorityQueue <int, GameObject> GetItinary(GameObject origin, List <GameObject> toVisit)
    {
        PriorityQueue <int, GameObject> rslt = new PriorityQueue <int, GameObject>();


        GameObject previous = origin;
        int        i        = 0;

        while (toVisit.Count > 0)
        {
            GameObject nearest = GetNearestObject(previous, toVisit);

            if (previous.GetComponentInChildren <RoadData>() != null &&
                nearest.GetComponentInChildren <RoadData>() != null &&
                RoadsPathfinding.RealDistanceBetween(previous.GetComponentInChildren <RoadData>(), nearest.GetComponentInChildren <RoadData>()) != -1)//On checke qu'il y a quand même bien un passage
            {
                rslt.Push(i, nearest);
                previous = nearest;
                i++;
            }
            toVisit.Remove(nearest);
        }
        return(rslt);
    }