Esempio n. 1
0
        public void Run(ModData modData, string[] args)
        {
            Game.ModData = modData;
            map = new Map(modData, modData.ModFiles.OpenPackage(args[1]));
            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 location = actor.InitDict.Get<LocationInit>().Value(null);
                if (!map.Contains(location))
                {
                    Console.WriteLine("Removing actor {0} located at {1} due being outside of the new map boundaries.".F(actor.Type, location));
                    forRemoval.Add(kv);
                }
            }

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

            map.Save((IReadWritePackage)map.Package);
        }
Esempio n. 2
0
        public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
        {
            var players = new MapPlayers(map.PlayerDefinitions).Players;

            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 && (player.Enemies.Any() || player.Allies.Any()))
                    emitWarning("The player {0} owning the world should not have any allies or enemies.".F(player.Name));
            }

            var worldActor = map.Rules.Actors["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<MPStartLocationsInfo>())
            {
                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.InitDict.Get<LocationInit>().Value(null));
                }

                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.");
            }

            foreach (var kv in map.ActorDefinitions)
            {
                var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                var ownerInit = actorReference.InitDict.GetOrDefault<OwnerInit>();
                if (ownerInit == null)
                    emitError("Actor {0} is not owned by any player.".F(kv.Key));
                else
                {
                    var ownerName = ownerInit.PlayerName;
                    if (!playerNames.Contains(ownerName))
                        emitError("Actor {0} is owned by unknown player {1}.".F(actorReference.Type, ownerName));
                }
            }
        }
Esempio n. 3
0
        static void ReadOverlay(Map map, IniFile file, int2 fullSize)
        {
            var overlaySection    = file.GetSection("OverlayPack");
            var overlayCompressed = Convert.FromBase64String(overlaySection.Aggregate(string.Empty, (a, b) => a + b.Value));
            var overlayPack       = new byte[1 << 18];
            var temp = new byte[1 << 18];

            UnpackLCW(overlayCompressed, overlayPack, temp);

            var overlayDataSection    = file.GetSection("OverlayDataPack");
            var overlayDataCompressed = Convert.FromBase64String(overlayDataSection.Aggregate(string.Empty, (a, b) => a + b.Value));
            var overlayDataPack       = new byte[1 << 18];

            UnpackLCW(overlayDataCompressed, overlayDataPack, temp);

            var overlayIndex = new CellLayer <int>(map);

            overlayIndex.Clear(0xFF);

            for (var y = 0; y < fullSize.Y; y++)
            {
                for (var x = fullSize.X * 2 - 2; x >= 0; x--)
                {
                    var dx = (ushort)x;
                    var dy = (ushort)(y * 2 + x % 2);

                    var uv = new MPos(dx / 2, dy);
                    var rx = (ushort)((dx + dy) / 2 + 1);
                    var ry = (ushort)(dy - rx + fullSize.X + 1);

                    if (!map.Resources.Contains(uv))
                    {
                        continue;
                    }

                    overlayIndex[uv] = rx + 512 * ry;
                }
            }

            foreach (var cell in map.AllCells)
            {
                var overlayType = overlayPack[overlayIndex[cell]];
                if (overlayType == 0xFF)
                {
                    continue;
                }

                string actorType;
                if (OverlayToActor.TryGetValue(overlayType, out actorType))
                {
                    if (string.IsNullOrEmpty(actorType))
                    {
                        continue;
                    }

                    var shape = new Size(1, 1);
                    if (OverlayShapes.TryGetValue(overlayType, out shape))
                    {
                        // Only import the top-left cell of multi-celled overlays
                        var aboveType = overlayPack[overlayIndex[cell - new CVec(1, 0)]];
                        if (shape.Width > 1 && aboveType != 0xFF)
                        {
                            string a;
                            if (OverlayToActor.TryGetValue(aboveType, out a) && a == actorType)
                            {
                                continue;
                            }
                        }

                        var leftType = overlayPack[overlayIndex[cell - new CVec(0, 1)]];
                        if (shape.Height > 1 && leftType != 0xFF)
                        {
                            string a;
                            if (OverlayToActor.TryGetValue(leftType, out a) && a == actorType)
                            {
                                continue;
                            }
                        }
                    }

                    var ar = new ActorReference(actorType)
                    {
                        new LocationInit(cell),
                        new OwnerInit("Neutral")
                    };

                    DamageState damageState;
                    if (OverlayToHealth.TryGetValue(overlayType, out damageState))
                    {
                        var health = 100;
                        if (damageState == DamageState.Critical)
                        {
                            health = 25;
                        }
                        else if (damageState == DamageState.Heavy)
                        {
                            health = 50;
                        }
                        else if (damageState == DamageState.Medium)
                        {
                            health = 75;
                        }

                        if (health != 100)
                        {
                            ar.Add(new HealthInit(health));
                        }
                    }

                    map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));

                    continue;
                }

                var resourceType = ResourceFromOverlay
                                   .Where(kv => kv.Value.Contains(overlayType))
                                   .Select(kv => kv.Key)
                                   .FirstOrDefault();

                if (resourceType != 0)
                {
                    map.Resources[cell] = new ResourceTile(resourceType, overlayDataPack[overlayIndex[cell]]);
                    continue;
                }

                Console.WriteLine("{0} unknown overlay {1}", cell, overlayType);
            }
        }
Esempio n. 4
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 {0} of unknown type {1}".F(id, 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);

            if (ios != null)
            {
                Footprint = ios.OccupiedCells(Info, location, subCell);
            }
            else
            {
                var footprint = new Dictionary <CPos, SubCell>()
                {
                    { location, SubCell.FullCell }
                };
                Footprint = new ReadOnlyDictionary <CPos, SubCell>(footprint);
            }

            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);
        }
Esempio n. 5
0
        /// <summary>
        /// Creates an <see cref="ActorProxy"/> of the specified type.
        /// </summary>
        /// <typeparam name="TActor"></typeparam>
        /// <param name="reference"></param>
        /// <returns></returns>
        public static TActor Bind <TActor>(this ActorReference reference)
        {
            Contract.Requires <ArgumentNullException>(reference != null);

            return((TActor)reference.Bind(typeof(TActor)));
        }
Esempio n. 6
0
        public virtual void SaveWaypoint(int waypointNumber, ActorReference waypointReference)
        {
            var waypointName = "waypoint" + waypointNumber;

            Map.ActorDefinitions.Add(new MiniYamlNode(waypointName, waypointReference.Save()));
        }
Esempio n. 7
0
        public bool HandleMouseInput(MouseInput mi)
        {
            // Exclusively uses left and right mouse buttons, but nothing else
            if (mi.Button != MouseButton.Left && mi.Button != MouseButton.Right)
                return false;

            if (mi.Button == MouseButton.Right)
            {
                if (mi.Event == MouseInputEvent.Up)
                {
                    editorWidget.ClearBrush();
                    return true;
                }

                return false;
            }

            var cell = worldRenderer.Viewport.ViewToWorld(mi.Location);
            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
            {
                // Check the actor is inside the map
                if (!footprint.All(c => world.Map.Tiles.Contains(cell + locationOffset + c)))
                    return true;

                var newActorReference = new ActorReference(Actor.Name);
                newActorReference.Add(new OwnerInit(owner.Name));

                cell += locationOffset;
                newActorReference.Add(new LocationInit(cell));

                var ios = Actor.TraitInfoOrDefault<IOccupySpaceInfo>();
                if (ios != null && ios.SharesCell)
                {
                    var subcell = editorLayer.FreeSubCellAt(cell);
                    if (subcell != SubCell.Invalid)
                        newActorReference.Add(new SubCellInit(subcell));
                }

                var initDict = newActorReference.InitDict;

                if (Actor.HasTraitInfo<IFacingInfo>())
                    initDict.Add(new FacingInit(facing));

                if (Actor.HasTraitInfo<TurretedInfo>())
                    initDict.Add(new TurretFacingInit(facing));

                editorLayer.Add(newActorReference);
            }

            return true;
        }
Esempio n. 8
0
 void Awake()
 {
     _actorRef = GetComponent <ActorReference>();
 }
        /// <summary>
        /// Catalogs the provided actor and its identity into this registry.
        /// This method expects an external transaction to be provided for managing atomicity
        /// </summary>
        /// <param name="tx">The <see cref="ITransaction"/> this Add operation is part of.</param>
        /// <param name="reference"><see cref="ActorReference"/> to store into internal state</param>
        /// <param name="identity">The underlying identity of the provided actor. This is not the actor id</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/></param>
        /// <returns><see cref="Task"/></returns>
        protected async Task AddActorAsync(ITransaction tx, ActorReference reference, Identity identity, CancellationToken cancellationToken)
        {
            var referenceMap = await GetReferenceMapAsync();

            var indexMap = await GetIndexMapAsync();

            var indexableRef = new IndexableActorReference(reference);
            var indexLookup  = await referenceMap.TryGetValueAsync(tx, indexableRef, ReliableCollectionDefaults.ReadTimeout, cancellationToken);

            long       index;
            IndexState state;

            if (indexLookup.HasValue)
            {
                index = indexLookup.Value;
                var stateLookup = await indexMap.TryGetValueAsync(tx, index, ReliableCollectionDefaults.ReadTimeout, cancellationToken);

                if (!stateLookup.HasValue)
                {
                    throw new InvalidOperationException($"{indexableRef.StringRepresentation} is missing its internal IndexState");
                }
                state = stateLookup.Value;
                IndexState newState;
                if (Equals(state.Identity, identity))
                {
                    newState = state;
                }
                else
                {
                    newState = new IndexState
                    {
                        Reference = reference,
                        Identity  = identity,
                        Index     = index
                    };
                    // replace old state
                    await indexMap.SetAsync(tx, index, newState, ReliableCollectionDefaults.WriteTimeout, cancellationToken);
                }

                await OnUpdateActorAsync(tx, state, newState, cancellationToken);
            }
            else
            {
                var identityMap = await GetIdentityMapAsync();

                var existingIndex = await identityMap.TryGetValueAsync(tx, identity, ReliableCollectionDefaults.ReadTimeout, cancellationToken);

                if (existingIndex.HasValue)
                {
                    var existingState = await indexMap.TryGetValueAsync(tx, existingIndex.Value);

                    throw new InvalidOperationException($"{identity} is already registered to Actor {new IndexableActorReference(existingState.Value.Reference).StringRepresentation}");
                }

                var propertiesMap = await GetPropertiesMapAsync();

                index = (long)await propertiesMap.AddOrUpdateAsync(tx, "currentIndex", 1L, (key, value) => (long)value + 1, ReliableCollectionDefaults.WriteTimeout, cancellationToken);

                state = new IndexState
                {
                    Reference = reference,
                    Identity  = identity,
                    Index     = index
                };

                await referenceMap.AddAsync(tx, indexableRef, index, ReliableCollectionDefaults.WriteTimeout, cancellationToken);

                await indexMap.AddAsync(tx, index, state, ReliableCollectionDefaults.WriteTimeout, cancellationToken);

                await identityMap.AddAsync(tx, identity, index, ReliableCollectionDefaults.WriteTimeout, cancellationToken);

                await OnAddActorAsync(tx, state, cancellationToken);
            }
        }
		static void ReadTerrainActors(Map map, IniFile file, int2 fullSize)
		{
			var terrainSection = file.GetSection("Terrain", true);
			foreach (var kv in terrainSection)
			{
				var pos = int.Parse(kv.Key);
				var ry = pos / 1000;
				var rx = pos - ry * 1000;
				var dx = rx - ry + fullSize.X - 1;
				var dy = rx + ry - fullSize.X - 1;
				var cell = new MPos(dx / 2, dy).ToCPos(map);
				var name = kv.Value.ToLowerInvariant();

				if (ReplaceActors.ContainsKey(name))
				{
					name = ReplaceActors[name];
				}

				var ar = new ActorReference(name);
				ar.Add(new LocationInit(cell));
				ar.Add(new OwnerInit("Neutral"));

				if (!map.Rules.Actors.ContainsKey(name))
					Console.WriteLine("Ignoring unknown actor type: `{0}`".F(name));
				else
					map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));
			}
		}
Esempio n. 11
0
        void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List <Pair <MPos, Color> > destinationBuffer)
        {
            var tileSet = map.Rules.TileSet;
            var color   = tileSet[tileSet.GetTerrainIndex(TerrainType)].Color;

            for (var i = 0; i < map.MapSize.X; i++)
            {
                for (var j = 0; j < map.MapSize.Y; j++)
                {
                    var cell = new MPos(i, j);
                    if (map.Resources[cell].Type == ResourceType)
                    {
                        destinationBuffer.Add(new Pair <MPos, Color>(cell, color));
                    }
                }
            }
        }
Esempio n. 12
0
 public EditorActorPreview Add(ActorReference reference)
 {
     return(Add(NextActorName(), reference));
 }
Esempio n. 13
0
        void ReadTrees(IniFile file)
        {
            var terrain = file.GetSection("TERRAIN", true);
            if (terrain == null)
                return;

            foreach (var kv in terrain)
            {
                var loc = Exts.ParseIntegerInvariant(kv.Key);
                var treeActor = ParseTreeActor(kv.Value);

                var ar = new ActorReference(treeActor)
                {
                    new LocationInit(ParseActorLocation(treeActor, loc)),
                    new OwnerInit("Neutral")
                };

                var actorCount = Map.ActorDefinitions.Count;
                Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
            }
        }
Esempio n. 14
0
        void LoadWaypoints(IniSection waypointSection)
        {
            var actorCount = Map.ActorDefinitions.Count;
            var wps = waypointSection
                .Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0)
                .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
                    LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), MapSize)));

            // Add waypoint actors skipping duplicate entries
            foreach (var kv in wps.DistinctBy(location => location.Second))
            {
                if (!singlePlayer && kv.First <= 7)
                {
                    var ar = new ActorReference("mpspawn")
                    {
                        new LocationInit((CPos)kv.Second),
                        new OwnerInit("Neutral")
                    };

                    Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
                    spawnCount++;
                }
                else
                {
                    var ar = new ActorReference("waypoint")
                    {
                        new LocationInit((CPos)kv.Second),
                        new OwnerInit("Neutral")
                    };

                    SaveWaypoint(kv.First, ar);
                }
            }
        }
Esempio n. 15
0
 public virtual void SaveWaypoint(int waypointNumber, ActorReference waypointReference)
 {
     var waypointName = "waypoint" + waypointNumber;
     Map.ActorDefinitions.Add(new MiniYamlNode(waypointName, waypointReference.Save()));
 }
Esempio n. 16
0
        static void ReadOverlay(Map map, IniFile file, int2 fullSize)
        {
            var overlaySection = file.GetSection("OverlayPack");
            var overlayCompressed = Convert.FromBase64String(overlaySection.Aggregate(string.Empty, (a, b) => a + b.Value));
            var overlayPack = new byte[1 << 18];
            var temp = new byte[1 << 18];
            UnpackLCW(overlayCompressed, overlayPack, temp);

            var overlayDataSection = file.GetSection("OverlayDataPack");
            var overlayDataCompressed = Convert.FromBase64String(overlayDataSection.Aggregate(string.Empty, (a, b) => a + b.Value));
            var overlayDataPack = new byte[1 << 18];
            UnpackLCW(overlayDataCompressed, overlayDataPack, temp);

            for (var y = 0; y < fullSize.Y; y++)
            {
                for (var x = fullSize.X * 2 - 2; x >= 0; x--)
                {
                    var dx = (ushort)x;
                    var dy = (ushort)(y * 2 + x % 2);

                    var uv = new MPos(dx / 2, dy);
                    var rx = (ushort)((dx + dy) / 2 + 1);
                    var ry = (ushort)(dy - rx + fullSize.X + 1);

                    if (!map.Resources.Contains(uv))
                        continue;

                    var idx = rx + 512 * ry;
                    var overlayType = overlayPack[idx];
                    if (overlayType == 0xFF)
                        continue;

                    string actorType;
                    if (OverlayToActor.TryGetValue(overlayType, out actorType))
                    {
                        var ar = new ActorReference(actorType)
                        {
                            new LocationInit(uv.ToCPos(map)),
                            new OwnerInit("Neutral")
                        };

                        map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));
                        continue;
                    }

                    var resourceType = ResourceFromOverlay
                        .Where(kv => kv.Value.Contains(overlayType))
                        .Select(kv => kv.Key)
                        .FirstOrDefault();

                    if (resourceType != 0)
                    {
                        map.Resources[uv] = new ResourceTile(resourceType, overlayDataPack[idx]);
                        continue;
                    }

                    Console.WriteLine("{0} unknown overlay {1}", uv, overlayType);
                }
            }
        }
Esempio n. 17
0
 public T CreateActorProxy <T>(ActorReference actorReference) where T : IActor =>
 CreateActorProxy <T>(actorReference.ServiceUri, actorReference.ActorId, actorReference.ListenerName);
		static void ReadOverlay(Map map, IniFile file, int2 fullSize)
		{
			var overlaySection = file.GetSection("OverlayPack");
			var overlayCompressed = Convert.FromBase64String(overlaySection.Aggregate(string.Empty, (a, b) => a + b.Value));
			var overlayPack = new byte[1 << 18];
			var temp = new byte[1 << 18];
			UnpackLCW(overlayCompressed, overlayPack, temp);

			var overlayDataSection = file.GetSection("OverlayDataPack");
			var overlayDataCompressed = Convert.FromBase64String(overlayDataSection.Aggregate(string.Empty, (a, b) => a + b.Value));
			var overlayDataPack = new byte[1 << 18];
			UnpackLCW(overlayDataCompressed, overlayDataPack, temp);

			var overlayIndex = new CellLayer<int>(map);
			overlayIndex.Clear(0xFF);

			for (var y = 0; y < fullSize.Y; y++)
			{
				for (var x = fullSize.X * 2 - 2; x >= 0; x--)
				{
					var dx = (ushort)x;
					var dy = (ushort)(y * 2 + x % 2);

					var uv = new MPos(dx / 2, dy);
					var rx = (ushort)((dx + dy) / 2 + 1);
					var ry = (ushort)(dy - rx + fullSize.X + 1);

					if (!map.Resources.Contains(uv))
						continue;

					overlayIndex[uv] = rx + 512 * ry;
				}
			}

			foreach (var cell in map.AllCells)
			{
				var overlayType = overlayPack[overlayIndex[cell]];
				if (overlayType == 0xFF)
					continue;

				string actorType;
				if (OverlayToActor.TryGetValue(overlayType, out actorType))
				{
					var shape = new Size(1, 1);
					if (OverlayShapes.TryGetValue(overlayType, out shape))
					{
						// Only import the top-left cell of multi-celled overlays
						var aboveType = overlayPack[overlayIndex[cell - new CVec(1, 0)]];
						if (shape.Width > 1 && aboveType != 0xFF)
						{
							string a;
							if (OverlayToActor.TryGetValue(aboveType, out a) && a == actorType)
								continue;
						}

						var leftType = overlayPack[overlayIndex[cell - new CVec(0, 1)]];
						if (shape.Height > 1 && leftType != 0xFF)
						{
							string a;
							if (OverlayToActor.TryGetValue(leftType, out a) && a == actorType)
								continue;
						}
					}

					var ar = new ActorReference(actorType)
					{
						new LocationInit(cell),
						new OwnerInit("Neutral")
					};

					DamageState damageState;
					if (OverlayToHealth.TryGetValue(overlayType, out damageState))
					{
						var health = 100;
						if (damageState == DamageState.Critical)
							health = 25;
						else if (damageState == DamageState.Heavy)
							health = 50;
						else if (damageState == DamageState.Medium)
							health = 75;

						if (health != 100)
							ar.Add(new HealthInit(health));
					}

					map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));

					continue;
				}

				var resourceType = ResourceFromOverlay
					.Where(kv => kv.Value.Contains(overlayType))
						.Select(kv => kv.Key)
						.FirstOrDefault();

				if (resourceType != 0)
				{
					map.Resources[cell] = new ResourceTile(resourceType, overlayDataPack[overlayIndex[cell]]);
					continue;
				}

				Console.WriteLine("{0} unknown overlay {1}", cell, overlayType);
			}
		}
Esempio n. 19
0
 public ActorPreviewInitializer(ActorInfo actor, WorldRenderer worldRenderer, TypeDictionary dict)
 {
     Actor         = actor;
     WorldRenderer = worldRenderer;
     reference     = new ActorReference(actor.Name, dict);
 }
Esempio n. 20
0
        public void LoadActors(IniFile file, string section, List<string> players, int mapSize, Map map)
        {
            foreach (var s in file.GetSection(section, true))
            {
                // Structures: num=owner,type,health,location,turret-facing,trigger
                // Units: num=owner,type,health,location,facing,action,trigger
                // Infantry: num=owner,type,health,location,subcell,action,facing,trigger
                try
                {
                    var parts = s.Value.Split(',');
                    if (parts[0] == "")
                        parts[0] = "Neutral";

                    if (!players.Contains(parts[0]))
                        players.Add(parts[0]);

                    var loc = Exts.ParseIntegerInvariant(parts[3]);
                    var health = Exts.ParseIntegerInvariant(parts[2]) * 100 / 256;
                    var facing = (section == "INFANTRY") ? Exts.ParseIntegerInvariant(parts[6]) : Exts.ParseIntegerInvariant(parts[4]);

                    var actorType = parts[1].ToLowerInvariant();

                    var actor = new ActorReference(actorType) {
                        new LocationInit(ParseActorLocation(actorType, loc)),
                        new OwnerInit(parts[0]),
                    };

                    var initDict = actor.InitDict;
                    if (health != 100)
                        initDict.Add(new HealthInit(health));
                    if (facing != 0)
                        initDict.Add(new FacingInit(255 - facing));

                    if (section == "INFANTRY")
                        actor.Add(new SubCellInit(Exts.ParseIntegerInvariant(parts[4])));

                    var actorCount = map.ActorDefinitions.Count;

                    if (!map.Rules.Actors.ContainsKey(parts[1].ToLowerInvariant()))
                        Console.WriteLine("Ignoring unknown actor type: `{0}`".F(parts[1].ToLowerInvariant()));
                    else
                        map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, actor.Save()));
                }
                catch (Exception)
                {
                    Console.WriteLine("Malformed actor definition: `{0}`".F(s));
                }
            }
        }
Esempio n. 21
0
 public ActorPreviewInitializer(ActorReference actor, WorldRenderer worldRenderer)
 {
     Actor         = worldRenderer.World.Map.Rules.Actors[actor.Type];
     reference     = actor;
     WorldRenderer = worldRenderer;
 }
Esempio n. 22
0
        void FillMap()
        {
            while (stream.Position < stream.Length)
            {
                var tileInfo = stream.ReadUInt16();
                var tileSpecialInfo = stream.ReadUInt16();
                var tile = GetTile(tileInfo);

                var locationOnMap = GetCurrentTilePositionOnMap();

                map.MapTiles.Value[locationOnMap] = tile;

                // Spice
                if (tileSpecialInfo == 1)
                    map.MapResources.Value[locationOnMap] = new ResourceTile(1, 1);
                if (tileSpecialInfo == 2)
                    map.MapResources.Value[locationOnMap] = new ResourceTile(1, 2);

                // Actors
                if (actorDataByActorCode.ContainsKey(tileSpecialInfo))
                {
                    var kvp = actorDataByActorCode[tileSpecialInfo];
                    if (!rules.Actors.ContainsKey(kvp.First.ToLower()))
                        throw new InvalidOperationException("Actor with name {0} could not be found in the rules YAML file!".F(kvp.First));

                    var a = new ActorReference(kvp.First)
                    {
                        new LocationInit(locationOnMap),
                        new OwnerInit(kvp.Second)
                    };
                    map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, a.Save()));
                }
            }
        }
 /// <summary>
 /// Gets <see cref="ActorId"/> for the actor./>
 /// </summary>
 /// <typeparam name="TIActor">Actor interface type.</typeparam>
 /// <param name="actor">Actor object to get ActorId for.</param>
 /// <returns><see cref="ActorId"/> for the actor.</returns>
 public static ActorId GetActorId<TIActor>(this TIActor actor)
     where TIActor : IActor
 {
     var r = ActorReference.Get(actor);
     return r.ActorId;
 }
Esempio n. 24
0
        public void Run(Action <string> emitError, Action <string> emitWarning, ModData modData, Map map)
        {
            var players         = new MapPlayers(map.PlayerDefinitions).Players;
            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["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 <MPStartLocationsInfo>())
            {
                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.InitDict.Get <LocationInit>().Value(null));
                }

                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.InitDict.GetOrDefault <OwnerInit>();
                if (ownerInit == null)
                {
                    emitError("Actor {0} is not owned by any player.".F(kv.Key));
                }
                else
                {
                    var ownerName = ownerInit.PlayerName;
                    if (!playerNames.Contains(ownerName))
                    {
                        emitError("Actor {0} is owned by unknown player {1}.".F(kv.Key, ownerName));
                    }

                    RequiresSpecificOwnersInfo info;
                    if (actorsWithRequiredOwner.TryGetValue(kv.Value.Value, out info))
                    {
                        if (!info.ValidOwnerNames.Contains(ownerName))
                        {
                            emitError("Actor {0} owner {1} is not one of ValidOwnerNames: {2}".F(kv.Key, ownerName, info.ValidOwnerNames.JoinWith(", ")));
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Gets <see cref="ActorReference"/> for the actor.
 /// </summary>
 /// <param name="actor">Actor object to get ActorReference for.</param>
 /// <returns><see cref="ActorReference"/> for the actor.</returns>
 public static ActorReference GetActorReference(this IActor actor)
 {
     return ActorReference.Get(actor);
 }
 public override void SaveWaypoint(int waypointNumber, ActorReference waypointReference)
 {
     var waypointName = "waypoint" + waypointNumber;
     if (waypointNumber == 25)
         waypointName = "DefaultFlareLocation";
     else if (waypointNumber == 26)
         waypointName = "DefaultCameraPosition";
     else if (waypointNumber == 27)
         waypointName = "DefaultChinookTarget";
     Map.ActorDefinitions.Add(new MiniYamlNode(waypointName, waypointReference.Save()));
 }
Esempio n. 27
0
        void LoadActors()
        {
            for (var a = 0; a < numberOfActors; a++)
            {
                var id   = stream.ReadInt32();
                var type = stream.ReadInt32();
                var x    = (int)Math.Round((float)stream.ReadInt32() / map.Grid.TileSize.Width);
                var y    = (int)Math.Round((float)stream.ReadInt32() / map.Grid.TileSize.Height);

                var invalidLocation = false;
                if (x < 0 || x > mapSize.Width || y < 0 || y > mapSize.Height)
                {
                    Console.WriteLine("Invalid coordinates {0},{1} for actor type {2}.".F(x, y, type));
                    invalidLocation = true;
                }

                stream.Seek(4, SeekOrigin.Current);
                var numberOfProperties = stream.ReadInt32();
                stream.Seek(4, SeekOrigin.Current);
                if (numberOfProperties > 0)
                {
                    for (var p = 0; p < numberOfProperties; p++)
                    {
                        var key   = stream.ReadASCII(128);
                        var value = stream.ReadInt32();
                        Console.WriteLine(key + ": " + value);
                    }
                }

                if (!ActorMap.ContainsKey(type))
                {
                    Console.WriteLine("Ignoring unknown actor type: `{0}` @ {1},{2}".F(type, x, y));
                    continue;
                }

                if (invalidLocation)
                {
                    continue;
                }

                var actorInfo = ActorMap[type];
                var actorType = actorInfo.ActorType.ToLowerInvariant();
                var actor     = new ActorReference(actorType)
                {
                    new LocationInit(new CPos(x + MapCordonWidth, y + MapCordonWidth)),
                };

                if (actorInfo.Color == Color.White)
                {
                    actor.Add(new OwnerInit("Neutral"));
                }
                if (actorInfo.Color == Color.Green)
                {
                    actor.Add(new OwnerInit("Ants"));
                }
                if (actorInfo.Color == Color.Blue)
                {
                    actor.Add(new OwnerInit("Beetles"));
                }
                if (actorInfo.Color == Color.Red)
                {
                    actor.Add(new OwnerInit("Spiders"));
                }
                if (actorInfo.Color == Color.Yellow)
                {
                    actor.Add(new OwnerInit("Wasps"));
                }
                if (actorInfo.Color == Color.Black)
                {
                    actor.Add(new OwnerInit("Creeps"));
                }

                AddPlayer(actorInfo.Color);

                var actorCount = map.ActorDefinitions.Count;

                if (!map.Rules.Actors.ContainsKey(actorType))
                {
                    Console.WriteLine("Ignoring unknown actor type: `{0}`".F(actorType));
                }
                else
                {
                    map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, actor.Save()));
                }
            }
        }
Esempio n. 28
0
        public void LoadActors(IniFile file, string section, List <string> players, int mapSize, Map map)
        {
            foreach (var s in file.GetSection(section, true))
            {
                // Structures: num=owner,type,health,location,turret-facing,trigger
                // Units: num=owner,type,health,location,facing,action,trigger
                // Infantry: num=owner,type,health,location,subcell,action,facing,trigger
                try
                {
                    var parts = s.Value.Split(',');
                    if (parts[0] == "")
                    {
                        parts[0] = "Neutral";
                    }

                    if (!players.Contains(parts[0]))
                    {
                        players.Add(parts[0]);
                    }

                    var loc    = Exts.ParseIntegerInvariant(parts[3]);
                    var health = Exts.ParseIntegerInvariant(parts[2]) * 100 / 256;
                    var facing = (section == "INFANTRY") ? Exts.ParseIntegerInvariant(parts[6]) : Exts.ParseIntegerInvariant(parts[4]);

                    var actorType = parts[1].ToLowerInvariant();

                    var actor = new ActorReference(actorType)
                    {
                        new LocationInit(ParseActorLocation(actorType, loc)),
                        new OwnerInit(parts[0]),
                    };

                    if (health != 100)
                    {
                        actor.Add(new HealthInit(health));
                    }
                    if (facing != 0)
                    {
                        actor.Add(new FacingInit(new WAngle(1024 - 4 * facing)));
                    }

                    if (section == "INFANTRY")
                    {
                        actor.Add(new SubCellInit((SubCell)Exts.ParseByte(parts[4])));
                    }

                    var actorCount = map.ActorDefinitions.Count;

                    if (!map.Rules.Actors.ContainsKey(parts[1].ToLowerInvariant()))
                    {
                        Console.WriteLine("Ignoring unknown actor type: `{0}`".F(parts[1].ToLowerInvariant()));
                    }
                    else
                    {
                        map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, actor.Save()));
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("Malformed actor definition: `{0}`".F(s));
                }
            }
        }
Esempio n. 29
0
        public void ConvertIniMap(string iniFile)
        {
            var file            = new IniFile(FileSystem.Open(iniFile));
            var basic           = file.GetSection("Basic");
            var map             = file.GetSection("Map");
            var legacyMapFormat = (IniMapFormat)int.Parse(basic.GetValue("NewINIFormat", "0"));
            var XOffset         = int.Parse(map.GetValue("X", "0"));
            var YOffset         = int.Parse(map.GetValue("Y", "0"));
            var Width           = int.Parse(map.GetValue("Width", "0"));
            var Height          = int.Parse(map.GetValue("Height", "0"));

            MapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64;

            Map.Title      = basic.GetValue("Name", "(null)");
            Map.Author     = "Westwood Studios";
            Map.Tileset    = Truncate(map.GetValue("Theater", "TEMPERAT"), 8);
            Map.MapSize.X  = MapSize;
            Map.MapSize.Y  = MapSize;
            Map.Bounds     = Rectangle.FromLTRB(XOffset, YOffset, XOffset + Width, YOffset + Height);
            Map.Selectable = true;

            Map.Smudges      = Lazy.New(() => new List <SmudgeReference>());
            Map.Actors       = Lazy.New(() => new Dictionary <string, ActorReference>());
            Map.MapResources = Lazy.New(() => new TileReference <byte, byte> [MapSize, MapSize]);
            Map.MapTiles     = Lazy.New(() => new TileReference <ushort, byte> [MapSize, MapSize]);

            if (legacyMapFormat == IniMapFormat.RedAlert)
            {
                UnpackRATileData(ReadPackedSection(file.GetSection("MapPack")));
                UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack")));
                ReadRATrees(file);
            }
            else             // CNC
            {
                UnpackCncTileData(FileSystem.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin"));
                ReadCncOverlay(file);
                ReadCncTrees(file);
            }

            LoadActors(file, "STRUCTURES");
            LoadActors(file, "UNITS");
            LoadActors(file, "INFANTRY");
            LoadSmudges(file, "SMUDGE");

            foreach (var p in Players)
            {
                LoadPlayer(file, p, (legacyMapFormat == IniMapFormat.RedAlert));
            }

            var wps = file.GetSection("Waypoints")
                      .Where(kv => int.Parse(kv.Value) > 0)
                      .Select(kv => Pair.New(int.Parse(kv.Key),
                                             LocationFromMapOffset(int.Parse(kv.Value), MapSize)))
                      .ToArray();


            // Add waypoint actors
            foreach (var kv in wps)
            {
                var a = new ActorReference("mpspawn");
                a.Add(new LocationInit((CPos)kv.Second));
                a.Add(new OwnerInit("Neutral"));
                Map.Actors.Value.Add("spawn" + kv.First, a);
            }
        }
Esempio n. 30
0
        public bool HandleMouseInput(MouseInput mi)
        {
            // Exclusively uses left and right mouse buttons, but nothing else
            if (mi.Button != MouseButton.Left && mi.Button != MouseButton.Right)
            {
                return(false);
            }

            if (mi.Button == MouseButton.Right)
            {
                if (mi.Event == MouseInputEvent.Up)
                {
                    editorWidget.ClearBrush();
                    return(true);
                }

                return(false);
            }

            var cell = worldRenderer.Viewport.ViewToWorld(mi.Location);

            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
            {
                // Check the actor is inside the map
                if (!footprint.All(c => world.Map.Tiles.Contains(cell + locationOffset + c)))
                {
                    return(true);
                }

                var newActorReference = new ActorReference(Actor.Name);
                newActorReference.Add(new OwnerInit(owner.Name));

                cell += locationOffset;
                newActorReference.Add(new LocationInit(cell));

                var ios = Actor.TraitInfoOrDefault <IOccupySpaceInfo>();
                if (ios != null && ios.SharesCell)
                {
                    var subcell = editorLayer.FreeSubCellAt(cell);
                    if (subcell != SubCell.Invalid)
                    {
                        newActorReference.Add(new SubCellInit(subcell));
                    }
                }

                var initDict = newActorReference.InitDict;

                if (Actor.HasTraitInfo <IFacingInfo>())
                {
                    initDict.Add(new FacingInit(facing));
                }

                if (Actor.HasTraitInfo <TurretedInfo>())
                {
                    initDict.Add(new TurretFacingInit(facing));
                }

                editorLayer.Add(newActorReference);
            }

            return(true);
        }
Esempio n. 31
0
        void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List <Pair <MPos, Color> > destinationBuffer)
        {
            var tileSet = map.Rules.TileSet;

            Color color;

            if (!string.IsNullOrEmpty(Terrain))
            {
                color = tileSet[tileSet.GetTerrainIndex(Terrain)].Color;
            }
            else if (Color != default(Color))
            {
                color = Color;
            }
            else
            {
                var owner      = map.PlayerDefinitions.Where(p => s.InitDict.Get <OwnerInit>().PlayerName == p.Value.Nodes.First(k => k.Key == "Name").Value.Value).First();
                var colorValue = owner.Value.Nodes.Where(n => n.Key == "Color");
                var ownerColor = colorValue.Any() ? colorValue.First().Value.Value : "FFFFFF";
                Color.TryParse(ownerColor, out color);
            }

            var ios   = ai.TraitInfo <IOccupySpaceInfo>();
            var cells = ios.OccupiedCells(ai, s.InitDict.Get <LocationInit>().Value(null));

            foreach (var cell in cells)
            {
                destinationBuffer.Add(new Pair <MPos, Color>(cell.Key.ToMPos(map), color));
            }
        }
Esempio n. 32
0
 void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List <(MPos, Color)> destinationBuffer)
Esempio n. 33
0
        public EditorActorPreview(WorldRenderer worldRenderer, string id, ActorReference actor, PlayerReference owner)
        {
            ID                 = id;
            this.actor         = actor;
            this.Owner         = owner;
            this.worldRenderer = worldRenderer;

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

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

            var world = worldRenderer.World;

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

            CenterPosition = PreviewPosition(world, actor.InitDict);

            var location = actor.InitDict.Get <LocationInit>().Value(worldRenderer.World);
            var ios      = Info.TraitInfoOrDefault <IOccupySpaceInfo>();

            var subCellInit = actor.InitDict.GetOrDefault <SubCellInit>();
            var subCell     = subCellInit != null?subCellInit.Value(worldRenderer.World) : SubCell.Any;

            if (ios != null)
            {
                Footprint = ios.OccupiedCells(Info, location, subCell);
            }
            else
            {
                var footprint = new Dictionary <CPos, SubCell>()
                {
                    { location, SubCell.FullCell }
                };
                Footprint = new ReadOnlyDictionary <CPos, SubCell>(footprint);
            }

            var tooltip = Info.TraitInfoOrDefault <EditorOnlyTooltipInfo>() as TooltipInfoBase ?? Info.TraitInfoOrDefault <TooltipInfo>();

            Tooltip = (tooltip == null ? " < " + Info.Name + " >" : tooltip.Name) + "\n" + owner.Name + " (" + owner.Faction + ")"
                      + "\nID: " + ID + "\nType: " + 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.Render(worldRenderer, CenterPosition))
                    .Select(rr => rr.PrepareRender(worldRenderer));

            if (r.Any())
            {
                Bounds = r.First().ScreenBounds(worldRenderer);
                foreach (var rr in r.Skip(1))
                {
                    Bounds = Rectangle.Union(Bounds, rr.ScreenBounds(worldRenderer));
                }
            }
        }
Esempio n. 34
0
        void LoadActors(IniFile file, string section)
        {
            foreach (var s in file.GetSection(section, true))
            {
                //Structures: num=owner,type,health,location,turret-facing,trigger
                //Units: num=owner,type,health,location,facing,action,trigger
                //Infantry: num=owner,type,health,location,subcell,action,facing,trigger
                var parts = s.Value.Split(',');
                var loc = int.Parse(parts[3]);
                if (parts[0] == "")
                    parts[0] = "Neutral";

                if (!Players.Contains(parts[0]))
                    Players.Add(parts[0]);

                var stance = ActorStance.Stance.None;
                switch(parts[5])
                {
                    case "Area Guard":
                    case "Guard":
                        stance = ActorStance.Stance.Guard;
                    break;
                    case "Defend Base":
                        stance = ActorStance.Stance.Defend;
                    break;
                    case "Hunt":
                    case "Rampage":
                    case "Attack Base":
                    case "Attack Units":
                    case "Attack Civil.":
                    case "Attack Tarcom":
                        stance = ActorStance.Stance.Hunt;
                    break;
                    case "Retreat":
                    case "Return":
                        stance = ActorStance.Stance.Retreat;
                    break;
                    // do we care about `Harvest' and `Sticky'?
                }

                var actor = new ActorReference(parts[1].ToLowerInvariant())
                {
                    new LocationInit(new int2(loc % MapSize, loc / MapSize)),
                    new OwnerInit(parts[0]),
                    new HealthInit(float.Parse(parts[2])/256),
                    new FacingInit((section == "INFANTRY") ? int.Parse(parts[6]) : int.Parse(parts[4])),
                    new ActorStanceInit(stance),
                };

                if (section == "INFANTRY")
                    actor.Add(new SubcellInit(int.Parse(parts[4])));

                Map.Actors.Add("Actor" + ActorCount++,actor);

            }
        }
        void ReadOverlay(IniFile file)
        {
            var overlay = file.GetSection("OVERLAY", true);
            if (overlay == null)
                return;

            foreach (var kv in overlay)
            {
                var loc = Exts.ParseIntegerInvariant(kv.Key);
                var cell = new CPos(loc % MapSize, loc / MapSize);

                var res = Pair.New((byte)0, (byte)0);
                var type = kv.Value.ToLowerInvariant();
                if (overlayResourceMapping.ContainsKey(type))
                    res = overlayResourceMapping[type];

                Map.Resources[cell] = new ResourceTile(res.First, res.Second);
                if (overlayActors.Contains(type))
                {
                    var ar = new ActorReference(type)
                    {
                        new LocationInit(cell),
                        new OwnerInit("Neutral")
                    };

                    var actorCount = Map.ActorDefinitions.Count;
                    Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
                }
            }
        }
		static void ReadWaypoints(Map map, IniFile file, int2 fullSize)
		{
			var waypointsSection = file.GetSection("Waypoints", true);
			foreach (var kv in waypointsSection)
			{
				var pos = int.Parse(kv.Value);
				var ry = pos / 1000;
				var rx = pos - ry * 1000;
				var dx = rx - ry + fullSize.X - 1;
				var dy = rx + ry - fullSize.X - 1;
				var cell = new MPos(dx / 2, dy).ToCPos(map);

				int wpindex;
				var ar = new ActorReference((!int.TryParse(kv.Key, out wpindex) || wpindex > 7) ? "waypoint" : "mpspawn");
				ar.Add(new LocationInit(cell));
				ar.Add(new OwnerInit("Neutral"));

				map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));
			}
		}
Esempio n. 37
0
        EditorActorPreview Add(string id, ActorReference reference, bool initialSetup = false)
        {
            var owner = Players.Players[reference.InitDict.Get<OwnerInit>().PlayerName];

            var preview = new EditorActorPreview(worldRenderer, id, reference, owner);
            previews.Add(preview);
            screenMap.Add(preview, preview.Bounds);

            foreach (var kv in preview.Footprint)
            {
                List<EditorActorPreview> list;
                if (!cellMap.TryGetValue(kv.Key, out list))
                {
                    list = new List<EditorActorPreview>();
                    cellMap.Add(kv.Key, list);
                }

                list.Add(preview);
            }

            if (!initialSetup)
            {
                UpdateNeighbours(preview.Footprint);

                if (reference.Type == "mpspawn")
                    SyncMultiplayerCount();
            }

            return preview;
        }
		static void ReadActors(Map map, IniFile file, string type, int2 fullSize)
		{
			var structuresSection = file.GetSection(type, true);
			foreach (var kv in structuresSection)
			{
				var isDeployed = false;
				var entries = kv.Value.Split(',');

				var name = entries[1].ToLowerInvariant();

				if (DeployableActors.ContainsKey(name))
				{
					name = DeployableActors[name];
					isDeployed = true;
				}

				if (ReplaceActors.ContainsKey(name))
				{
					name = ReplaceActors[name];
				}

				var health = short.Parse(entries[2]);
				var rx = int.Parse(entries[3]);
				var ry = int.Parse(entries[4]);
				var facing = (byte)(byte.Parse(entries[5]) + 96);

				var dx = rx - ry + fullSize.X - 1;
				var dy = rx + ry - fullSize.X - 1;
				var cell = new MPos(dx / 2, dy).ToCPos(map);

				var ar = new ActorReference(name)
				{
					new LocationInit(cell),
					new OwnerInit("Neutral"),
					new HealthInit(100 * health / 256),
					new FacingInit(facing),
				};

				if (isDeployed)
					ar.Add(new DeployStateInit(DeployState.Deployed));

				if (!map.Rules.Actors.ContainsKey(name))
					Console.WriteLine("Ignoring unknown actor type: `{0}`".F(name));
				else
					map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));
			}
		}
Esempio n. 39
0
 public static CPos Location(this ActorReference ar)
 {
     return((CPos)ar.InitDict.Get <LocationInit>().value);
 }
Esempio n. 40
0
		ColorPalette GetPaletteForActor(ActorReference ar)
		{
			var ownerInit = ar.InitDict.GetOrDefault<OwnerInit>();
			if (ownerInit == null)
				return null;

			return GetPaletteForPlayer(ownerInit.PlayerName);
		}
Esempio n. 41
0
        public void Run(Action <string> emitError, Action <string> emitWarning, Map map)
        {
            var players = new MapPlayers(map.PlayerDefinitions).Players;

            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 && (player.Enemies.Any() || player.Allies.Any()))
                {
                    emitWarning("The player {0} owning the world should not have any allies or enemies.".F(player.Name));
                }
            }

            var worldActor = map.Rules.Actors["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 <MPStartLocationsInfo>())
            {
                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.InitDict.Get <LocationInit>().Value(null));
                }

                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.");
                }
            }

            foreach (var kv in map.ActorDefinitions)
            {
                var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                var ownerInit      = actorReference.InitDict.GetOrDefault <OwnerInit>();
                if (ownerInit == null)
                {
                    emitError("Actor {0} is not owned by any player.".F(kv.Key));
                }
                else
                {
                    var ownerName = ownerInit.PlayerName;
                    if (!playerNames.Contains(ownerName))
                    {
                        emitError("Actor {0} is owned by unknown player {1}.".F(kv.Key, ownerName));
                    }
                    else if (kv.Value.Value == "mpspawn" && !players[ownerName].OwnsWorld)
                    {
                        emitError("Actor {0} needs to be owned by the player that owns the world. ".F(kv.Key) +
                                  "Use the `Spawn` and `LockSpawn` player properties to force players onto a particular spawn instead.");
                    }
                }
            }
        }
Esempio n. 42
0
 public EditorActorPreview Add(ActorReference reference)
 {
     return Add(NextActorName(), reference);
 }
Esempio n. 43
0
        /// <summary>
        /// Registers an Actor as a subscriber for messages.
        /// </summary>
        /// <param name="actor">Reference to the actor to register.</param>
        /// <param name="messageTypeName">Full type name of message object.</param>
        public async Task RegisterSubscriberAsync(ActorReference actor, string messageTypeName)
        {
            var actorReference = new ActorReferenceWrapper(actor);

            await RegisterSubscriberAsync(actorReference, messageTypeName);
        }
Esempio n. 44
0
        /// <summary>
        /// Unregisters an Actor as a subscriber for messages.
        /// </summary>
        /// <param name="actor">Reference to the actor to unsubscribe.</param>
        /// <param name="messageTypeName">Full type name of message object.</param>
        /// <param name="flushQueue">Publish any remaining messages.</param>
        public async Task UnregisterSubscriberAsync(ActorReference actor, string messageTypeName, bool flushQueue)
        {
            var actorReference = new ActorReferenceWrapper(actor);

            await UnregisterSubscriberAsync(actorReference, messageTypeName);
        }
Esempio n. 45
0
        enum IniMapFormat { RedAlert = 3 }         // otherwise, cnc (2 variants exist, we don't care to differentiate)

        public void ConvertIniMap(string iniFile)
        {
            using (var stream = GlobalFileSystem.Open(iniFile))
            {
                var file            = new IniFile(stream);
                var basic           = file.GetSection("Basic");
                var mapSection      = file.GetSection("Map");
                var legacyMapFormat = (IniMapFormat)Exts.ParseIntegerInvariant(basic.GetValue("NewINIFormat", "0"));
                var offsetX         = Exts.ParseIntegerInvariant(mapSection.GetValue("X", "0"));
                var offsetY         = Exts.ParseIntegerInvariant(mapSection.GetValue("Y", "0"));
                var width           = Exts.ParseIntegerInvariant(mapSection.GetValue("Width", "0"));
                var height          = Exts.ParseIntegerInvariant(mapSection.GetValue("Height", "0"));
                mapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64;

                var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8);
                map = new Map(rules.TileSets[tileset], mapSize, mapSize)
                {
                    Title  = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile)),
                    Author = "Westwood Studios"
                };

                var tl = new MPos(offsetX, offsetY);
                var br = new MPos(offsetX + width - 1, offsetY + height - 1);
                map.SetBounds(tl, br);

                if (legacyMapFormat == IniMapFormat.RedAlert)
                {
                    UnpackRATileData(ReadPackedSection(file.GetSection("MapPack")));
                    UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack")));
                    ReadRATrees(file);
                }
                else
                {
                    // CnC
                    using (var s = GlobalFileSystem.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin"))
                        UnpackCncTileData(s);
                    ReadCncOverlay(file);
                    ReadCncTrees(file);
                }

                LoadVideos(file, "BASIC");
                LoadActors(file, "STRUCTURES");
                LoadActors(file, "UNITS");
                LoadActors(file, "INFANTRY");
                LoadActors(file, "SHIPS");
                LoadSmudges(file, "SMUDGE");

                var wps = file.GetSection("Waypoints")
                          .Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0)
                          .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
                                                 LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize)));

                // Add waypoint actors
                foreach (var kv in wps)
                {
                    if (kv.First <= 7)
                    {
                        var ar = new ActorReference("mpspawn")
                        {
                            new LocationInit((CPos)kv.Second),
                            new OwnerInit("Neutral")
                        };

                        map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
                    }
                    else
                    {
                        var ar = new ActorReference("waypoint")
                        {
                            new LocationInit((CPos)kv.Second),
                            new OwnerInit("Neutral")
                        };

                        map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save()));
                    }
                }

                // Create default player definitions only if there are no players to import
                mapPlayers = new MapPlayers(map.Rules, (players.Count == 0) ? map.SpawnPoints.Value.Length : 0);
                foreach (var p in players)
                {
                    LoadPlayer(file, p, legacyMapFormat == IniMapFormat.RedAlert);
                }
                map.PlayerDefinitions = mapPlayers.ToMiniYaml();
            }
        }
        void UnpackOverlayData(MemoryStream ms)
        {
            for (var j = 0; j < MapSize; j++)
            {
                for (var i = 0; i < MapSize; i++)
                {
                    var o = ms.ReadUInt8();
                    var res = Pair.New((byte)0, (byte)0);

                    if (o != 255 && overlayResourceMapping.ContainsKey(redAlertOverlayNames[o]))
                        res = overlayResourceMapping[redAlertOverlayNames[o]];

                    var cell = new CPos(i, j);
                    Map.Resources[cell] = new ResourceTile(res.First, res.Second);

                    if (o != 255 && overlayActors.Contains(redAlertOverlayNames[o]))
                    {
                        var ar = new ActorReference(redAlertOverlayNames[o])
                        {
                            new LocationInit(cell),
                            new OwnerInit("Neutral")
                        };

                        var actorCount = Map.ActorDefinitions.Count;
                        Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
                    }
                }
            }
        }
Esempio n. 47
0
        static void ReadOverlay(Map map, IniFile file, int2 fullSize)
        {
            var overlaySection    = file.GetSection("OverlayPack");
            var overlayCompressed = Convert.FromBase64String(string.Concat(overlaySection.Select(kvp => kvp.Value)));
            var overlayPack       = new byte[1 << 18];
            var temp = new byte[1 << 18];

            UnpackLCW(overlayCompressed, overlayPack, temp);

            var overlayDataSection    = file.GetSection("OverlayDataPack");
            var overlayDataCompressed = Convert.FromBase64String(string.Concat(overlayDataSection.Select(kvp => kvp.Value)));
            var overlayDataPack       = new byte[1 << 18];

            UnpackLCW(overlayDataCompressed, overlayDataPack, temp);

            var overlayIndex = new CellLayer <int>(map);

            overlayIndex.Clear(0xFF);

            for (var y = 0; y < fullSize.Y; y++)
            {
                for (var x = fullSize.X * 2 - 2; x >= 0; x--)
                {
                    var dx = (ushort)x;
                    var dy = (ushort)(y * 2 + x % 2);

                    var uv = new MPos(dx / 2, dy);
                    var rx = (ushort)((dx + dy) / 2 + 1);
                    var ry = (ushort)(dy - rx + fullSize.X + 1);

                    if (!map.Resources.Contains(uv))
                    {
                        continue;
                    }

                    overlayIndex[uv] = rx + 512 * ry;
                }
            }

            foreach (var cell in map.AllCells)
            {
                var overlayType = overlayPack[overlayIndex[cell]];
                if (overlayType == 0xFF)
                {
                    continue;
                }

                if (OverlayToActor.TryGetValue(overlayType, out var actorType))
                {
                    if (string.IsNullOrEmpty(actorType))
                    {
                        continue;
                    }

                    var shape = new Size(1, 1);
                    if (OverlayShapes.TryGetValue(overlayType, out shape))
                    {
                        // Only import the top-left cell of multi-celled overlays
                        var aboveType = overlayPack[overlayIndex[cell - new CVec(1, 0)]];
                        if (shape.Width > 1 && aboveType != 0xFF)
                        {
                            if (OverlayToActor.TryGetValue(aboveType, out var a) && a == actorType)
                            {
                                continue;
                            }
                        }

                        var leftType = overlayPack[overlayIndex[cell - new CVec(0, 1)]];
                        if (shape.Height > 1 && leftType != 0xFF)
                        {
                            if (OverlayToActor.TryGetValue(leftType, out var a) && a == actorType)
                            {
                                continue;
                            }
                        }
                    }

                    // Fix position of vein hole actors
                    var location = cell;
                    if (actorType == "veinhole")
                    {
                        location -= new CVec(1, 1);
                    }

                    var ar = new ActorReference(actorType)
                    {
                        new LocationInit(location),
                        new OwnerInit("Neutral")
                    };

                    if (OverlayToHealth.TryGetValue(overlayType, out var damageState))
                    {
                        var health = 100;
                        if (damageState == DamageState.Critical)
                        {
                            health = 25;
                        }
                        else if (damageState == DamageState.Heavy)
                        {
                            health = 50;
                        }
                        else if (damageState == DamageState.Medium)
                        {
                            health = 75;
                        }

                        if (health != 100)
                        {
                            ar.Add(new HealthInit(health));
                        }
                    }

                    map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, ar.Save()));

                    continue;
                }

                // TS maps encode the non-harvestable border tiles as overlay
                // Only convert to vein resources if the overlay data specifies non-border frames
                if (overlayType == 0x7E)
                {
                    var frame = overlayDataPack[overlayIndex[cell]];
                    if (frame < 48 || frame > 60)
                    {
                        continue;
                    }

                    // Pick half or full density based on the frame
                    map.Resources[cell] = new ResourceTile(3, (byte)(frame == 52 ? 1 : 2));
                    continue;
                }

                var resourceType = ResourceFromOverlay
                                   .Where(kv => kv.Value.Contains(overlayType))
                                   .Select(kv => kv.Key)
                                   .FirstOrDefault();

                if (resourceType != 0)
                {
                    map.Resources[cell] = new ResourceTile(resourceType, overlayDataPack[overlayIndex[cell]]);
                    continue;
                }

                Console.WriteLine("{0} unknown overlay {1}", cell, overlayType);
            }
        }