コード例 #1
0
ファイル: PlaceBuilding.cs プロジェクト: xXBlu3f1r3Xx/OpenRA
        public void ResolveOrder(Actor self, Order order)
        {
            var os = order.OrderString;

            if (os != "PlaceBuilding" &&
                os != "LineBuild" &&
                os != "PlacePlug")
            {
                return;
            }

            self.World.AddFrameEndTask(w =>
            {
                var prevItems = GetNumBuildables(self.Owner);

                if (order.TargetActor.IsDead)
                {
                    return;
                }

                var unit  = self.World.Map.Rules.Actors[order.TargetString];
                var queue = order.TargetActor.TraitsImplementing <ProductionQueue>()
                            .FirstOrDefault(q => q.CanBuild(unit) && q.CurrentItem() != null && q.CurrentItem().Item == order.TargetString && q.CurrentItem().RemainingTime == 0);

                if (queue == null)
                {
                    return;
                }

                var producer     = queue.MostLikelyProducer();
                var faction      = producer.Trait != null ? producer.Trait.Faction : self.Owner.Faction.InternalName;
                var buildingInfo = unit.Traits.Get <BuildingInfo>();

                var buildableInfo = unit.Traits.GetOrDefault <BuildableInfo>();
                if (buildableInfo != null && buildableInfo.ForceFaction != null)
                {
                    faction = buildableInfo.ForceFaction;
                }

                if (os == "LineBuild")
                {
                    var playSounds = true;
                    foreach (var t in BuildingUtils.GetLineBuildCells(w, order.TargetLocation, order.TargetString, buildingInfo))
                    {
                        var building = w.CreateActor(order.TargetString, new TypeDictionary
                        {
                            new LocationInit(t),
                            new OwnerInit(order.Player),
                            new FactionInit(faction)
                        });

                        if (playSounds)
                        {
                            foreach (var s in buildingInfo.BuildSounds)
                            {
                                Sound.PlayToPlayer(order.Player, s, building.CenterPosition);
                            }
                        }

                        playSounds = false;
                    }
                }
                else if (os == "PlacePlug")
                {
                    var host = self.World.WorldActor.Trait <BuildingInfluence>().GetBuildingAt(order.TargetLocation);
                    if (host == null)
                    {
                        return;
                    }

                    var plugInfo = unit.Traits.GetOrDefault <PlugInfo>();
                    if (plugInfo == null)
                    {
                        return;
                    }

                    var location  = host.Location;
                    var pluggable = host.TraitsImplementing <Pluggable>()
                                    .FirstOrDefault(p => location + p.Info.Offset == order.TargetLocation && p.AcceptsPlug(host, plugInfo.Type));

                    if (pluggable == null)
                    {
                        return;
                    }

                    pluggable.EnablePlug(host, plugInfo.Type);
                    foreach (var s in buildingInfo.BuildSounds)
                    {
                        Sound.PlayToPlayer(order.Player, s, host.CenterPosition);
                    }
                }
                else
                {
                    if (!self.World.CanPlaceBuilding(order.TargetString, buildingInfo, order.TargetLocation, null) ||
                        !buildingInfo.IsCloseEnoughToBase(self.World, order.Player, order.TargetString, order.TargetLocation))
                    {
                        return;
                    }

                    var building = w.CreateActor(order.TargetString, new TypeDictionary
                    {
                        new LocationInit(order.TargetLocation),
                        new OwnerInit(order.Player),
                        new FactionInit(faction),
                    });

                    foreach (var s in buildingInfo.BuildSounds)
                    {
                        Sound.PlayToPlayer(order.Player, s, building.CenterPosition);
                    }
                }

                if (producer.Actor != null)
                {
                    foreach (var nbp in producer.Actor.TraitsImplementing <INotifyBuildingPlaced>())
                    {
                        nbp.BuildingPlaced(producer.Actor);
                    }
                }

                queue.FinishProduction();

                if (buildingInfo.RequiresBaseProvider)
                {
                    // May be null if the build anywhere cheat is active
                    // BuildingInfo.IsCloseEnoughToBase has already verified that this is a valid build location
                    var provider = buildingInfo.FindBaseProvider(w, self.Owner, order.TargetLocation);
                    if (provider != null)
                    {
                        provider.Trait <BaseProvider>().BeginCooldown();
                    }
                }

                if (GetNumBuildables(self.Owner) > prevItems)
                {
                    w.Add(new DelayedAction(info.NewOptionsNotificationDelay,
                                            () => Sound.PlayNotification(self.World.Map.Rules, order.Player, "Speech", info.NewOptionsNotification, order.Player.Faction.InternalName)));
                }
            });
        }
コード例 #2
0
        void IResolveOrder.ResolveOrder(Actor self, Order order)
        {
            var os = order.OrderString;

            if (os != "PlaceBuilding" &&
                os != "LineBuild" &&
                os != "PlacePlug")
            {
                return;
            }

            self.World.AddFrameEndTask(w =>
            {
                var prevItems      = GetNumBuildables(self.Owner);
                var targetActor    = w.GetActorById(order.ExtraData);
                var targetLocation = w.Map.CellContaining(order.Target.CenterPosition);

                if (targetActor == null || targetActor.IsDead)
                {
                    return;
                }

                var actorInfo = self.World.Map.Rules.Actors[order.TargetString];
                var queue     = targetActor.TraitsImplementing <ProductionQueue>()
                                .FirstOrDefault(q => q.CanBuild(actorInfo) && q.AllQueued().Any(i => i.Done && i.Item == order.TargetString));

                if (queue == null)
                {
                    return;
                }

                // Find the ProductionItem associated with the building that we are trying to place
                var item = queue.AllQueued().FirstOrDefault(i => i.Done && i.Item == order.TargetString);

                if (item == null)
                {
                    return;
                }

                // Override with the alternate actor
                if (order.ExtraLocation.X > 0)
                {
                    var variant = actorInfo.TraitInfos <PlaceBuildingVariantsInfo>()
                                  .SelectMany(p => p.Actors)
                                  .Skip(order.ExtraLocation.X - 1)
                                  .FirstOrDefault();

                    if (variant != null)
                    {
                        actorInfo = self.World.Map.Rules.Actors[variant];
                    }
                }

                var producer     = queue.MostLikelyProducer();
                var faction      = producer.Trait?.Faction ?? self.Owner.Faction.InternalName;
                var buildingInfo = actorInfo.TraitInfo <BuildingInfo>();

                var buildableInfo = actorInfo.TraitInfoOrDefault <BuildableInfo>();
                if (buildableInfo != null && buildableInfo.ForceFaction != null)
                {
                    faction = buildableInfo.ForceFaction;
                }

                if (os == "LineBuild")
                {
                    // Build the parent actor first
                    var placed = w.CreateActor(actorInfo.Name, new TypeDictionary
                    {
                        new LocationInit(targetLocation),
                        new OwnerInit(order.Player),
                        new FactionInit(faction),
                        new PlaceBuildingInit()
                    });

                    foreach (var s in buildingInfo.BuildSounds)
                    {
                        Game.Sound.PlayToPlayer(SoundType.World, order.Player, s, placed.CenterPosition);
                    }

                    // Build the connection segments
                    var segmentType = actorInfo.TraitInfo <LineBuildInfo>().SegmentType;
                    if (string.IsNullOrEmpty(segmentType))
                    {
                        segmentType = actorInfo.Name;
                    }

                    foreach (var t in BuildingUtils.GetLineBuildCells(w, targetLocation, actorInfo, buildingInfo, order.Player))
                    {
                        if (t.Cell == targetLocation)
                        {
                            continue;
                        }

                        w.CreateActor(t.Cell == targetLocation ? actorInfo.Name : segmentType, new TypeDictionary
                        {
                            new LocationInit(t.Cell),
                            new OwnerInit(order.Player),
                            new FactionInit(faction),
                            new LineBuildDirectionInit(t.Cell.X == targetLocation.X ? LineBuildDirection.Y : LineBuildDirection.X),
                            new LineBuildParentInit(new[] { t.Actor, placed }),
                            new PlaceBuildingInit()
                        });
                    }
                }
                else if (os == "PlacePlug")
                {
                    var plugInfo = actorInfo.TraitInfoOrDefault <PlugInfo>();
                    if (plugInfo == null)
                    {
                        return;
                    }

                    foreach (var a in self.World.ActorMap.GetActorsAt(targetLocation))
                    {
                        var pluggables = a.TraitsImplementing <Pluggable>()
                                         .Where(p => p.AcceptsPlug(a, plugInfo.Type))
                                         .ToList();

                        var pluggable = pluggables.FirstOrDefault(p => a.Location + p.Info.Offset == targetLocation)
                                        ?? pluggables.FirstOrDefault();

                        if (pluggable == null)
                        {
                            return;
                        }

                        pluggable.EnablePlug(a, plugInfo.Type);
                        foreach (var s in buildingInfo.BuildSounds)
                        {
                            Game.Sound.PlayToPlayer(SoundType.World, order.Player, s, a.CenterPosition);
                        }
                    }
                }
                else
                {
                    if (!self.World.CanPlaceBuilding(targetLocation, actorInfo, buildingInfo, null) ||
                        !buildingInfo.IsCloseEnoughToBase(self.World, order.Player, actorInfo, targetLocation))
                    {
                        return;
                    }

                    var replaceableTypes = actorInfo.TraitInfos <ReplacementInfo>()
                                           .SelectMany(r => r.ReplaceableTypes)
                                           .ToHashSet();

                    if (replaceableTypes.Any())
                    {
                        foreach (var t in buildingInfo.Tiles(targetLocation))
                        {
                            foreach (var a in self.World.ActorMap.GetActorsAt(t))
                            {
                                if (a.TraitsImplementing <Replaceable>().Any(r => !r.IsTraitDisabled && r.Info.Types.Overlaps(replaceableTypes)))
                                {
                                    self.World.Remove(a);
                                }
                            }
                        }
                    }

                    var building = w.CreateActor(actorInfo.Name, new TypeDictionary
                    {
                        new LocationInit(targetLocation),
                        new OwnerInit(order.Player),
                        new FactionInit(faction),
                        new PlaceBuildingInit()
                    });

                    foreach (var s in buildingInfo.BuildSounds)
                    {
                        Game.Sound.PlayToPlayer(SoundType.World, order.Player, s, building.CenterPosition);
                    }
                }

                if (producer.Actor != null)
                {
                    foreach (var nbp in producer.Actor.TraitsImplementing <INotifyBuildingPlaced>())
                    {
                        nbp.BuildingPlaced(producer.Actor);
                    }
                }

                queue.EndProduction(item);

                // FindBaseProvider may return null if the build anywhere cheat is active
                // BuildingInfo.IsCloseEnoughToBase has already verified that this is a valid build location
                if (buildingInfo.RequiresBaseProvider)
                {
                    buildingInfo.FindBaseProvider(w, self.Owner, targetLocation)?.BeginCooldown();
                }

                if (GetNumBuildables(self.Owner) > prevItems)
                {
                    triggerNotification = true;
                }
            });
        }
コード例 #3
0
ファイル: PlaceBuilding.cs プロジェクト: cjshmyr/OpenRA
        void IResolveOrder.ResolveOrder(Actor self, Order order)
        {
            var os = order.OrderString;

            if (os != "PlaceBuilding" &&
                os != "LineBuild" &&
                os != "PlacePlug")
            {
                return;
            }

            self.World.AddFrameEndTask(w =>
            {
                var prevItems = GetNumBuildables(self.Owner);

                if (order.TargetActor.IsDead)
                {
                    return;
                }

                var unit  = self.World.Map.Rules.Actors[order.TargetString];
                var queue = order.TargetActor.TraitsImplementing <ProductionQueue>()
                            .FirstOrDefault(q => q.CanBuild(unit) && q.CurrentItem() != null && q.CurrentItem().Item == order.TargetString && q.CurrentItem().RemainingTime == 0);

                if (queue == null)
                {
                    return;
                }

                var producer     = queue.MostLikelyProducer();
                var faction      = producer.Trait != null ? producer.Trait.Faction : self.Owner.Faction.InternalName;
                var buildingInfo = unit.TraitInfo <BuildingInfo>();

                var buildableInfo = unit.TraitInfoOrDefault <BuildableInfo>();
                if (buildableInfo != null && buildableInfo.ForceFaction != null)
                {
                    faction = buildableInfo.ForceFaction;
                }

                if (os == "LineBuild")
                {
                    // Build the parent actor first
                    var placed = w.CreateActor(order.TargetString, new TypeDictionary
                    {
                        new LocationInit(order.TargetLocation),
                        new OwnerInit(order.Player),
                        new FactionInit(faction),
                    });

                    foreach (var s in buildingInfo.BuildSounds)
                    {
                        Game.Sound.PlayToPlayer(SoundType.World, order.Player, s, placed.CenterPosition);
                    }

                    // Build the connection segments
                    var segmentType = unit.TraitInfo <LineBuildInfo>().SegmentType;
                    if (string.IsNullOrEmpty(segmentType))
                    {
                        segmentType = order.TargetString;
                    }

                    foreach (var t in BuildingUtils.GetLineBuildCells(w, order.TargetLocation, order.TargetString, buildingInfo))
                    {
                        if (t.First == order.TargetLocation)
                        {
                            continue;
                        }

                        w.CreateActor(t.First == order.TargetLocation ? order.TargetString : segmentType, new TypeDictionary
                        {
                            new LocationInit(t.First),
                            new OwnerInit(order.Player),
                            new FactionInit(faction),
                            new LineBuildDirectionInit(t.First.X == order.TargetLocation.X ? LineBuildDirection.Y : LineBuildDirection.X),
                            new LineBuildParentInit(new[] { t.Second, placed })
                        });
                    }
                }
                else if (os == "PlacePlug")
                {
                    var host = self.World.WorldActor.Trait <BuildingInfluence>().GetBuildingAt(order.TargetLocation);
                    if (host == null)
                    {
                        return;
                    }

                    var plugInfo = unit.TraitInfoOrDefault <PlugInfo>();
                    if (plugInfo == null)
                    {
                        return;
                    }

                    var location  = host.Location;
                    var pluggable = host.TraitsImplementing <Pluggable>()
                                    .FirstOrDefault(p => location + p.Info.Offset == order.TargetLocation && p.AcceptsPlug(host, plugInfo.Type));

                    if (pluggable == null)
                    {
                        return;
                    }

                    pluggable.EnablePlug(host, plugInfo.Type);
                    foreach (var s in buildingInfo.BuildSounds)
                    {
                        Game.Sound.PlayToPlayer(SoundType.World, order.Player, s, host.CenterPosition);
                    }
                }
                else
                {
                    if (!self.World.CanPlaceBuilding(order.TargetString, buildingInfo, order.TargetLocation, null) ||
                        !buildingInfo.IsCloseEnoughToBase(self.World, order.Player, order.TargetString, order.TargetLocation))
                    {
                        return;
                    }

                    var building = w.CreateActor(order.TargetString, new TypeDictionary
                    {
                        new LocationInit(order.TargetLocation),
                        new OwnerInit(order.Player),
                        new FactionInit(faction),
                    });

                    foreach (var s in buildingInfo.BuildSounds)
                    {
                        Game.Sound.PlayToPlayer(SoundType.World, order.Player, s, building.CenterPosition);
                    }
                }

                if (producer.Actor != null)
                {
                    foreach (var nbp in producer.Actor.TraitsImplementing <INotifyBuildingPlaced>())
                    {
                        nbp.BuildingPlaced(producer.Actor);
                    }
                }

                queue.FinishProduction();

                if (buildingInfo.RequiresBaseProvider)
                {
                    // May be null if the build anywhere cheat is active
                    // BuildingInfo.IsCloseEnoughToBase has already verified that this is a valid build location
                    var provider = buildingInfo.FindBaseProvider(w, self.Owner, order.TargetLocation);
                    if (provider != null)
                    {
                        provider.Trait <BaseProvider>().BeginCooldown();
                    }
                }

                if (GetNumBuildables(self.Owner) > prevItems)
                {
                    triggerNotification = true;
                }
            });
        }