예제 #1
0
        WPos PreviewPosition(World world, ActorReference actor)
        {
            var centerPositionInit = actor.GetOrDefault <CenterPositionInit>();

            if (centerPositionInit != null)
            {
                return(centerPositionInit.Value);
            }

            var locationInit = actor.GetOrDefault <LocationInit>();

            if (locationInit != null)
            {
                var cell   = locationInit.Value;
                var offset = WVec.Zero;

                var subCellInit = reference.GetOrDefault <SubCellInit>();
                var subCell     = subCellInit != null ? subCellInit.Value : SubCell.Any;

                var buildingInfo = Info.TraitInfoOrDefault <BuildingInfo>();
                if (buildingInfo != null)
                {
                    offset = buildingInfo.CenterOffset(world);
                }

                return(world.Map.CenterOfSubCell(cell, subCell) + offset);
            }
            else
            {
                throw new InvalidDataException("Actor {0} must define Location or CenterPosition".F(ID));
            }
        }
예제 #2
0
        void IUtilityCommand.Run(Utility utility, string[] args)
        {
            var modData = Game.ModData = utility.ModData;

            map = new Map(modData, new Folder(Platform.EngineDir).OpenPackage(args[1], modData.ModFiles));
            Console.WriteLine("Resizing map {0} from {1} to {2},{3}", map.Title, map.MapSize, width, height);
            map.Resize(width, height);

            var forRemoval = new List <MiniYamlNode>();

            foreach (var kv in map.ActorDefinitions)
            {
                var actor        = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                var locationInit = actor.GetOrDefault <LocationInit>();
                if (locationInit == null)
                {
                    continue;
                }

                if (!map.Contains(locationInit.Value))
                {
                    Console.WriteLine($"Removing actor {actor.Type} located at {locationInit.Value} due being outside of the new map boundaries.");
                    forRemoval.Add(kv);
                }
            }

            foreach (var kv in forRemoval)
            {
                map.ActorDefinitions.Remove(kv);
            }

            map.Save((IReadWritePackage)map.Package);
        }
예제 #3
0
        public EditorActorPreview(WorldRenderer worldRenderer, string id, ActorReference reference, PlayerReference owner)
        {
            ID                 = id;
            this.reference     = reference;
            Owner              = owner;
            this.worldRenderer = worldRenderer;

            if (!reference.Contains <FactionInit>())
            {
                reference.Add(new FactionInit(owner.Faction));
            }

            if (!reference.Contains <OwnerInit>())
            {
                reference.Add(new OwnerInit(owner.Name));
            }

            var world = worldRenderer.World;

            if (!world.Map.Rules.Actors.TryGetValue(reference.Type.ToLowerInvariant(), out Info))
            {
                throw new InvalidDataException($"Actor {id} of unknown type {reference.Type.ToLowerInvariant()}");
            }

            CenterPosition = PreviewPosition(world, reference);

            var location = reference.Get <LocationInit>().Value;
            var ios      = Info.TraitInfoOrDefault <IOccupySpaceInfo>();

            var subCellInit = reference.GetOrDefault <SubCellInit>();
            var subCell     = subCellInit != null ? subCellInit.Value : SubCell.Any;

            var radarColorInfo = Info.TraitInfoOrDefault <RadarColorFromTerrainInfo>();

            RadarColor = radarColorInfo == null ? owner.Color : radarColorInfo.GetColorFromTerrain(world);

            Footprint = ios?.OccupiedCells(Info, location, subCell) ?? new Dictionary <CPos, SubCell>()
            {
                { location, SubCell.FullCell }
            };

            tooltip = Info.TraitInfos <EditorOnlyTooltipInfo>().FirstOrDefault(info => info.EnabledByDefault) as TooltipInfoBase
                      ?? Info.TraitInfos <TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault);

            DescriptiveName = tooltip != null ? tooltip.Name : Info.Name;

            GeneratePreviews();

            // Bounds are fixed from the initial render.
            // If this is a problem, then we may need to fetch the area from somewhere else
            var r = previews.SelectMany(p => p.ScreenBounds(worldRenderer, CenterPosition));

            Bounds = r.Union();

            SelectionBox = new SelectionBoxAnnotationRenderable(new WPos(CenterPosition.X, CenterPosition.Y, 8192),
                                                                new Rectangle(Bounds.X, Bounds.Y, Bounds.Width, Bounds.Height), Color.White);
        }
예제 #4
0
        public void Run(Action <string> emitError, Action <string> emitWarning, ModData modData, Map map)
        {
            var playerNames = new MapPlayers(map.PlayerDefinitions).Players.Values
                              .Select(p => p.Name)
                              .ToHashSet();

            // Check for actors that require specific owners
            var actorsWithRequiredOwner = map.Rules.Actors
                                          .Where(a => a.Value.HasTraitInfo <RequiresSpecificOwnersInfo>())
                                          .ToDictionary(a => a.Key, a => a.Value.TraitInfo <RequiresSpecificOwnersInfo>());

            foreach (var kv in map.ActorDefinitions)
            {
                var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                var ownerInit      = actorReference.GetOrDefault <OwnerInit>();
                if (ownerInit == null)
                {
                    emitError("Actor {0} is not owned by any player.".F(kv.Key));
                }
                else
                {
                    var ownerName = ownerInit.InternalName;
                    if (!playerNames.Contains(ownerName))
                    {
                        emitError("Actor {0} is owned by unknown player {1}.".F(kv.Key, ownerName));
                    }

                    if (actorsWithRequiredOwner.TryGetValue(kv.Value.Value, out var info))
                    {
                        if (!info.ValidOwnerNames.Contains(ownerName))
                        {
                            emitError("Actor {0} owner {1} is not one of ValidOwnerNames: {2}".F(kv.Key, ownerName, info.ValidOwnerNames.JoinWith(", ")));
                        }
                    }
                }
            }
        }
예제 #5
0
        public void Run(Action <string> emitError, Action <string> emitWarning, ModData modData, Map map)
        {
            var players = new MapPlayers(map.PlayerDefinitions).Players;

            if (players.Count > 64)
            {
                emitError("Defining more than 64 players is not allowed.");
            }

            var worldOwnerFound = false;
            var playerNames     = players.Values.Select(p => p.Name).ToHashSet();

            foreach (var player in players.Values)
            {
                foreach (var ally in player.Allies)
                {
                    if (!playerNames.Contains(ally))
                    {
                        emitError("Allies contains player {0} that is not in list.".F(ally));
                    }
                }

                foreach (var enemy in player.Enemies)
                {
                    if (!playerNames.Contains(enemy))
                    {
                        emitError("Enemies contains player {0} that is not in list.".F(enemy));
                    }
                }

                if (player.OwnsWorld)
                {
                    worldOwnerFound = true;
                    if (player.Enemies.Any() || player.Allies.Any())
                    {
                        emitWarning("The player {0} owning the world should not have any allies or enemies.".F(player.Name));
                    }

                    if (player.Playable)
                    {
                        emitError("The player {0} owning the world can't be playable.".F(player.Name));
                    }
                }
                else if (map.Visibility == MapVisibility.MissionSelector && player.Playable && !player.LockFaction)
                {
                    // Missions must lock the faction of the player to force the server to override the default Random faction
                    emitError("The player {0} must specify LockFaction: True.".F(player.Name));
                }
            }

            if (!worldOwnerFound)
            {
                emitError("Found no player owning the world.");
            }

            var worldActor = map.Rules.Actors[SystemActors.World];
            var factions   = worldActor.TraitInfos <FactionInfo>().Select(f => f.InternalName).ToHashSet();

            foreach (var player in players.Values)
            {
                if (!string.IsNullOrWhiteSpace(player.Faction) && !factions.Contains(player.Faction))
                {
                    emitError("Invalid faction {0} chosen for player {1}.".F(player.Faction, player.Name));
                }
            }

            if (worldActor.HasTraitInfo <MapStartingLocationsInfo>())
            {
                var playerCount = players.Count(p => p.Value.Playable);
                var spawns      = new List <CPos>();
                foreach (var kv in map.ActorDefinitions.Where(d => d.Value.Value == "mpspawn"))
                {
                    var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                    spawns.Add(s.Get <LocationInit>().Value);
                }

                if (playerCount > spawns.Count)
                {
                    emitError("The map allows {0} possible players, but defines only {1} spawn points".F(playerCount, spawns.Count));
                }

                if (spawns.Distinct().Count() != spawns.Count)
                {
                    emitError("Duplicate spawn point locations detected.");
                }
            }

            // Check for actors that require specific owners
            var actorsWithRequiredOwner = map.Rules.Actors
                                          .Where(a => a.Value.HasTraitInfo <RequiresSpecificOwnersInfo>())
                                          .ToDictionary(a => a.Key, a => a.Value.TraitInfo <RequiresSpecificOwnersInfo>());

            foreach (var kv in map.ActorDefinitions)
            {
                var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                var ownerInit      = actorReference.GetOrDefault <OwnerInit>();
                if (ownerInit == null)
                {
                    emitError("Actor {0} is not owned by any player.".F(kv.Key));
                }
                else
                {
                    var ownerName = ownerInit.InternalName;
                    if (!playerNames.Contains(ownerName))
                    {
                        emitError("Actor {0} is owned by unknown player {1}.".F(kv.Key, ownerName));
                    }

                    if (actorsWithRequiredOwner.TryGetValue(kv.Value.Value, out var info))
                    {
                        if (!info.ValidOwnerNames.Contains(ownerName))
                        {
                            emitError("Actor {0} owner {1} is not one of ValidOwnerNames: {2}".F(kv.Key, ownerName, info.ValidOwnerNames.JoinWith(", ")));
                        }
                    }
                }
            }
        }
예제 #6
0
 public T GetInitOrDefault <T>(TraitInfo info) where T : ActorInit
 {
     return(reference.GetOrDefault <T>(info));
 }
예제 #7
0
        protected void Run(Utility utility, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = ModData = utility.ModData;

            var filename = args[1];
            var flag     = args[2];

            if (string.IsNullOrWhiteSpace(flag))
            {
                flag = "VH";
            }

            bool flipHorizontal = flag.Contains("H");
            bool flipVertical   = flag.Contains("V");

            MirrorType mirrorType = MirrorType.Horizontal;

            if (flipVertical)
            {
                mirrorType = MirrorType.Vertical;
            }
            if (flipHorizontal && flipVertical)
            {
                mirrorType = MirrorType.HorizontalAndVertical;
            }

            var targetPath = "..\\mods\\dr\\maps";

            var package = new Folder(targetPath).OpenPackage(filename, ModData.ModFiles);

            if (package == null)
            {
                Console.WriteLine("Couldn't find map file: " + filename);
                return;
            }

            Map = new Map(ModData, package);
            var size = Map.MapSize;

            switch (mirrorType)
            {
            case MirrorType.Horizontal:
                size = size.WithX(size.X / 2);
                break;

            case MirrorType.Vertical:
                size = size.WithY(size.Y / 2);
                break;

            case MirrorType.HorizontalAndVertical:
                size = size / 2;
                break;
            }

            // Tiles
            for (int x = 0; x < size.X; x++)
            {
                for (int y = 0; y < size.Y; y++)
                {
                    var pos           = new CPos(x, y);
                    var transformTile = new TileTransform()
                    {
                        Tile       = Map.Tiles[pos],
                        MirrorType = mirrorType,
                        Position   = pos
                    };

                    foreach (var tt in transformTile.GetTransforms(Map))
                    {
                        var newPos = tt.Position;
                        Map.Tiles[newPos] = tt.Tile;
                    }
                }
            }

            // Actors
            actorIndex = GetHighestActorIndex();
            int multiCount = 0;

            var actorDefs    = new List <ActorReference>();
            var removeActors = new List <MiniYamlNode>();

            foreach (var a in Map.ActorDefinitions)
            {
                var existing = new ActorReference(a.Value.Value, a.Value.ToDictionary());
                var pos      = existing.GetOrDefault <LocationInit>().Value;
                var owner    = existing.Get <OwnerInit>();

                if (pos.X < 0 || pos.X >= size.X ||
                    pos.Y < 0 || pos.Y >= size.Y)
                {
                    removeActors.Add(a);
                    continue;
                }

                var actor = new ActorTransform()
                {
                    Actor      = existing,
                    Position   = pos,
                    MirrorType = mirrorType,
                };

                if (actor.Actor.Type == "mpspawn")
                {
                    multiCount++;
                }

                foreach (var at in actor.GetTransforms(Map))
                {
                    var ar = new ActorReference(actor.Actor.Type)
                    {
                        new LocationInit(at.Position),
                        owner
                    };

                    actorDefs.Add(ar);

                    if (at.Actor.Type == "mpspawn")
                    {
                        multiCount++;
                    }
                }
            }

            foreach (var a in actorDefs)
            {
                Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + ++actorIndex, a.Save()));
            }

            foreach (var a in removeActors)
            {
                Map.ActorDefinitions.Remove(a);
            }

            if (multiCount > 0)
            {
                var mapPlayers = new MapPlayers(Map.Rules, multiCount);
                Map.PlayerDefinitions = mapPlayers.ToMiniYaml();
            }

            // Resources
            for (int x = 0; x < size.X; x++)
            {
                for (int y = 0; y < size.Y; y++)
                {
                    var pos      = new CPos(x, y);
                    var resource = new ResourceTransform()
                    {
                        Tile       = Map.Resources[pos],
                        MirrorType = mirrorType,
                        Position   = pos
                    };

                    foreach (var rt in resource.GetTransforms(Map))
                    {
                        var newPos = rt.Position;
                        Map.Resources[newPos] = rt.Tile;
                    }
                }
            }

            var dest = Path.Combine(targetPath, Path.GetFileNameWithoutExtension(filename) + ".oramap");

            Map.Save(ZipFileLoader.Create(dest));
            Console.WriteLine(dest + " saved.");
        }