コード例 #1
0
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor)
        {
            var li = self.Info.TraitInfo <MobileInfo>().LocomotorInfo;

            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();
                cached      = true;
            }

            // If a water-land transition is required, bail early
            if (domainIndex != null && !domainIndex.IsPassable(source, target, li))
            {
                return(EmptyPath);
            }

            var distance = source - target;

            if (source.Layer == target.Layer && distance.LengthSquared < 3 && li.CanMoveFreelyInto(world, self, target, null, CellConditions.All))
            {
                return new List <CPos> {
                           target
                }
            }
            ;

            List <CPos> pb;

            using (var fromSrc = PathSearch.FromPoint(world, li, self, target, source, true).WithIgnoredActor(ignoreActor))
                using (var fromDest = PathSearch.FromPoint(world, li, self, source, target, true).WithIgnoredActor(ignoreActor).Reverse())
                    pb = FindBidiPath(fromSrc, fromDest);

            return(pb);
        }
コード例 #2
0
ファイル: PathFinder.cs プロジェクト: WalterBarrett/OpenRA
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check)
        {
            // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait.
            var locomotor = ((Mobile)self.OccupiesSpace).Locomotor;

            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();
                cached      = true;
            }

            // If a water-land transition is required, bail early
            if (domainIndex != null && !domainIndex.IsPassable(source, target, locomotor))
            {
                return(EmptyPath);
            }

            var distance      = source - target;
            var canMoveFreely = locomotor.CanMoveFreelyInto(self, target, check, null);

            if (distance.LengthSquared < 3 && !canMoveFreely)
            {
                return new List <CPos> {
                }
            }
            ;

            if (source.Layer == target.Layer && distance.LengthSquared < 3 && canMoveFreely)
            {
                return new List <CPos> {
                           target
                }
            }
            ;

            List <CPos> pb;

            using (var fromSrc = PathSearch.FromPoint(world, locomotor, self, target, source, check).WithIgnoredActor(ignoreActor))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, target, check).WithIgnoredActor(ignoreActor).Reverse())
                    pb = FindBidiPath(fromSrc, fromDest);

            return(pb);
        }
コード例 #3
0
ファイル: PathFinder.cs プロジェクト: Mete0/anki-OpenRA
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check)
        {
            var mobile    = self.Trait <Mobile>();
            var locomotor = mobile.Locomotor;

            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();
                cached      = true;
            }

            // If a water-land transition is required, bail early
            if (domainIndex != null && !domainIndex.IsPassable(source, target, locomotor.Info))
            {
                return(EmptyPath);
            }

            var distance      = source - target;
            var canMoveFreely = locomotor.CanMoveFreelyInto(self, target, check, null);

            if (distance.LengthSquared < 3 && !canMoveFreely)
            {
                return new List <CPos> {
                }
            }
            ;

            if (source.Layer == target.Layer && distance.LengthSquared < 3 && canMoveFreely)
            {
                return new List <CPos> {
                           target
                }
            }
            ;

            List <CPos> pb;

            using (var fromSrc = PathSearch.FromPoint(world, locomotor, self, target, source, check).WithIgnoredActor(ignoreActor))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, target, check).WithIgnoredActor(ignoreActor).Reverse())
                    pb = FindBidiPath(fromSrc, fromDest);

            return(pb);
        }
コード例 #4
0
ファイル: HarvesterBotModule.cs プロジェクト: dnqbob/OpenRA
        Target FindNextResource(Actor actor, HarvesterTraitWrapper harv)
        {
            Func <CPos, bool> isValidResource = cell =>
                                                domainIndex.IsPassable(actor.Location, cell, harv.Locomotor) &&
                                                harv.Harvester.CanHarvestCell(actor, cell) &&
                                                claimLayer.CanClaimCell(actor, cell);

            var path = pathfinder.FindPath(
                PathSearch.Search(world, harv.Locomotor, actor, BlockedByActor.Stationary, isValidResource)
                .WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && actor.Owner.RelationshipWith(u.Owner) == PlayerRelationship.Enemy)
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
                .FromPoint(actor.Location));

            if (path.Count == 0)
            {
                return(Target.Invalid);
            }

            return(Target.FromCell(world, path[0]));
        }
コード例 #5
0
        CPos FindNextResource(Actor actor, Harvester harv)
        {
            var locomotorInfo = actor.Info.TraitInfo <MobileInfo>().LocomotorInfo;

            Func <CPos, bool> isValidResource = cell =>
                                                domainIndex.IsPassable(actor.Location, cell, locomotorInfo) &&
                                                harv.CanHarvestCell(actor, cell) &&
                                                claimLayer.CanClaimCell(actor, cell);

            var path = pathfinder.FindPath(
                PathSearch.Search(world, locomotorInfo, actor, true, isValidResource)
                .WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && actor.Owner.Stances[u.Owner] == Stance.Enemy)
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
                .FromPoint(actor.Location));

            if (path.Count == 0)
            {
                return(CPos.Zero);
            }

            return(path[0]);
        }
コード例 #6
0
        public override bool Produce(Actor self, ActorInfo producee, string productionType, TypeDictionary inits)
        {
            if (IsTraitDisabled || IsTraitPaused)
            {
                return(false);
            }

            var aircraftInfo = producee.TraitInfoOrDefault <AircraftInfo>();
            var mobileInfo   = producee.TraitInfoOrDefault <MobileInfo>();

            var destination = rp != null ? rp.Location : self.Location;

            var location = spawnLocation;

            if (!location.HasValue)
            {
                if (aircraftInfo != null)
                {
                    location = self.World.Map.ChooseClosestEdgeCell(self.Location);
                }

                if (mobileInfo != null)
                {
                    var locomotorInfo = mobileInfo.LocomotorInfo;
                    location = self.World.Map.ChooseClosestMatchingEdgeCell(self.Location,
                                                                            c => mobileInfo.CanEnterCell(self.World, null, c) && domainIndex.IsPassable(c, destination, locomotorInfo));
                }
            }

            // No suitable spawn location could be found, so production has failed.
            if (!location.HasValue)
            {
                return(false);
            }

            var pos = self.World.Map.CenterOfCell(location.Value);

            // If aircraft, spawn at cruise altitude
            if (aircraftInfo != null)
            {
                pos += new WVec(0, 0, aircraftInfo.CruiseAltitude.Length);
            }

            var initialFacing = self.World.Map.FacingBetween(location.Value, destination, 0);

            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary();
                foreach (var init in inits)
                {
                    td.Add(init);
                }

                td.Add(new LocationInit(location.Value));
                td.Add(new CenterPositionInit(pos));
                td.Add(new FacingInit(initialFacing));

                var newUnit = self.World.CreateActor(producee.Name, td);

                var move = newUnit.TraitOrDefault <IMove>();
                if (move != null)
                {
                    newUnit.QueueActivity(move.MoveTo(destination, 2));
                }

                newUnit.SetTargetLine(Target.FromCell(self.World, destination), Color.Green, false);

                if (!self.IsDead)
                {
                    foreach (var t in self.TraitsImplementing <INotifyProduction>())
                    {
                        t.UnitProduced(self, newUnit, destination);
                    }
                }

                var notifyOthers = self.World.ActorsWithTrait <INotifyOtherProduction>();
                foreach (var notify in notifyOthers)
                {
                    notify.Trait.UnitProducedByOther(notify.Actor, self, newUnit, productionType);
                }

                foreach (var t in newUnit.TraitsImplementing <INotifyBuildComplete>())
                {
                    t.BuildingComplete(newUnit);
                }
            });

            return(true);
        }
コード例 #7
0
        public override bool Produce(Actor self, ActorInfo producee, string productionType, TypeDictionary inits, int refundableValue)
        {
            if (IsTraitDisabled || IsTraitPaused)
            {
                return(false);
            }

            var aircraftInfo = producee.TraitInfoOrDefault <AircraftInfo>();
            var mobileInfo   = producee.TraitInfoOrDefault <MobileInfo>();

            var destinations = rp != null && rp.Path.Count > 0 ? rp.Path : new List <CPos> {
                self.Location
            };

            var location = spawnLocation;

            if (!location.HasValue)
            {
                if (aircraftInfo != null)
                {
                    location = self.World.Map.ChooseClosestEdgeCell(self.Location);
                }

                if (mobileInfo != null)
                {
                    var locomotor = self.World.WorldActor.TraitsImplementing <Locomotor>().First(l => l.Info.Name == mobileInfo.Locomotor);
                    location = self.World.Map.ChooseClosestMatchingEdgeCell(self.Location,
                                                                            c => mobileInfo.CanEnterCell(self.World, null, c) && domainIndex.IsPassable(c, destinations[0], locomotor));
                }
            }

            // No suitable spawn location could be found, so production has failed.
            if (!location.HasValue)
            {
                return(false);
            }

            var pos = self.World.Map.CenterOfCell(location.Value);

            // If aircraft, spawn at cruise altitude
            if (aircraftInfo != null)
            {
                pos += new WVec(0, 0, aircraftInfo.CruiseAltitude.Length);
            }

            var initialFacing = self.World.Map.FacingBetween(location.Value, destinations[0], WAngle.Zero);

            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary();
                foreach (var init in inits)
                {
                    td.Add(init);
                }

                td.Add(new LocationInit(location.Value));
                td.Add(new CenterPositionInit(pos));
                td.Add(new FacingInit(initialFacing));

                var newUnit = self.World.CreateActor(producee.Name, td);

                var move = newUnit.TraitOrDefault <IMove>();
                if (move != null)
                {
                    foreach (var cell in destinations)
                    {
                        newUnit.QueueActivity(move.MoveTo(cell, 2, evaluateNearestMovableCell: true));
                    }
                }

                if (!self.IsDead)
                {
                    foreach (var t in self.TraitsImplementing <INotifyProduction>())
                    {
                        t.UnitProduced(self, newUnit, destinations[0]);
                    }
                }

                var notifyOthers = self.World.ActorsWithTrait <INotifyOtherProduction>();
                foreach (var notify in notifyOthers)
                {
                    notify.Trait.UnitProducedByOther(notify.Actor, self, newUnit, productionType, td);
                }
            });

            return(true);
        }