Beispiel #1
0
        public int2 Expand( World world, float[][ , ] passableCost )
        {
            var p = queue.Pop();
            cellInfo[ p.Location.X, p.Location.Y ].Seen = true;

            var custom2 = world.customTerrain[p.Location.X, p.Location.Y];
            var thisCost = (custom2 != null)
                ? custom2.GetCost(p.Location, umt)
                : passableCost[(int)umt][p.Location.X, p.Location.Y];

            if (thisCost == float.PositiveInfinity)
                return p.Location;

            foreach( int2 d in directions )
            {
                int2 newHere = p.Location + d;

                if (!world.Map.IsInMap(newHere.X, newHere.Y)) continue;
                if( cellInfo[ newHere.X, newHere.Y ].Seen )
                    continue;

                var custom = world.customTerrain[newHere.X, newHere.Y];
                var costHere = (custom != null) ? custom.GetCost(newHere, umt) : passableCost[(int)umt][newHere.X, newHere.Y];

                if (costHere == float.PositiveInfinity)
                    continue;

                if (!buildingInfluence.CanMoveHere(newHere, ignoreBuilding))
                    continue;

                // Replicate real-ra behavior of not being able to enter a cell if there is a mixture of crushable and uncrushable units
                if (checkForBlocked && (unitInfluence.GetUnitsAt(newHere).Any(a => !world.IsActorPathableToCrush(a, umt))))
                    continue;

                if (customBlock != null && customBlock(newHere))
                    continue;

                var est = heuristic( newHere );
                if( est == float.PositiveInfinity )
                    continue;

                float cellCost = ((d.X * d.Y != 0) ? 1.414213563f : 1.0f) * costHere;

                // directional bonuses for smoother flow!
                if (((newHere.X & 1) == 0) && d.Y < 0) cellCost -= .1f;
                else if (((newHere.X & 1) == 1) && d.Y > 0) cellCost -= .1f;
                if (((newHere.Y & 1) == 0) && d.X < 0) cellCost -= .1f;
                else if (((newHere.Y & 1) == 1) && d.X > 0) cellCost -= .1f;

                float newCost = cellInfo[ p.Location.X, p.Location.Y ].MinCost + cellCost;

                if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost )
                    continue;

                cellInfo[ newHere.X, newHere.Y ].Path = p.Location;
                cellInfo[ newHere.X, newHere.Y ].MinCost = newCost;

                queue.Add( new PathDistance( newCost + est, newHere ) );

            }
            return p.Location;
        }