Esempio n. 1
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)
            {
                editorWidget.ClearBrush();
                return(true);
            }

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

            if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down && world.Map.Contains(cell))
            {
                var newActorReference = new ActorReference(Actor.Name);
                newActorReference.Add(new OwnerInit(owner.Name));

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

                var ios = Actor.Traits.GetOrDefault <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.Traits.Contains <IFacingInfo>())
                {
                    initDict.Add(new FacingInit(facing));
                }

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

                editorLayer.Add(newActorReference);
            }

            return(true);
        }
Esempio n. 2
0
        public int SetActor(WorldRenderer wr, ActorInfo actor, PlayerReference owner)
        {
            var ios          = actor.TraitInfoOrDefault <IOccupySpaceInfo>();
            var buildingInfo = ios as BuildingInfo;

            actorCenterOffset = buildingInfo != null?buildingInfo.CenterOffset(world) : WVec.Zero;

            actorSharesCell = ios != null && ios.SharesCell;
            actorSubCell    = SubCell.Invalid;

            // Enforce first entry of ValidOwnerNames as owner if the actor has RequiresSpecificOwners
            var ownerName         = owner.Name;
            var specificOwnerInfo = actor.TraitInfoOrDefault <RequiresSpecificOwnersInfo>();

            if (specificOwnerInfo != null && !specificOwnerInfo.ValidOwnerNames.Contains(ownerName))
            {
                ownerName = specificOwnerInfo.ValidOwnerNames.First();
            }

            var reference = new ActorReference(actor.Name);

            reference.Add(new OwnerInit(ownerName));
            reference.Add(new FactionInit(owner.Faction));

            var worldPx = wr.Viewport.ViewToWorldPx(Viewport.LastMousePos) - wr.ScreenPxOffset(actorCenterOffset);
            var cell    = wr.Viewport.ViewToWorld(wr.Viewport.WorldToViewPx(worldPx));

            reference.Add(new LocationInit(cell));
            if (ios != null && ios.SharesCell)
            {
                actorSubCell = editorLayer.FreeSubCellAt(cell);
                if (actorSubCell != SubCell.Invalid)
                {
                    reference.Add(new SubCellInit(actorSubCell));
                }
            }

            if (actor.HasTraitInfo <IFacingInfo>())
            {
                reference.Add(new FacingInit(info.PreviewFacing));
            }

            Type            = EditorCursorType.Actor;
            Actor           = new EditorActorPreview(wr, null, reference, owner);
            TerrainTemplate = null;
            Resource        = null;

            return(++CurrentToken);
        }
Esempio n. 3
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
                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 actor = new ActorReference(parts[1].ToLowerInvariant())
                    {
                        new LocationInit(new CPos(loc % mapSize, loc / mapSize)),
                        new OwnerInit(parts[0]),
                    };

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

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

                    if (!rules.Actors.ContainsKey(parts[1].ToLowerInvariant()))
                    {
                        errorHandler("Ignoring unknown actor type: `{0}`".F(parts[1].ToLowerInvariant()));
                    }
                    else
                    {
                        map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, actor.Save()));
                    }
                }
                catch (Exception)
                {
                    errorHandler("Malformed actor definition: `{0}`".F(s));
                }
            }
        }
Esempio n. 4
0
		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;
				}

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

				if (health != 256)
					ar.Add(new HealthInit(100 * health / 256));

				if (facing != 96)
					ar.Add(new FacingInit(WAngle.FromFacing(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. 5
0
        public void Do()
        {
            var ownerName         = owner.Name;
            var specificOwnerInfo = actor.TraitInfoOrDefault <RequiresSpecificOwnersInfo>();

            if (specificOwnerInfo != null && !specificOwnerInfo.ValidOwnerNames.Contains(ownerName))
            {
                ownerName = specificOwnerInfo.ValidOwnerNames.First();
            }

            var newActorReference = new ActorReference(actor.Name);

            newActorReference.Add(new OwnerInit(ownerName));

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

            editorActorPreview = editorLayer.Add(newActorReference);

            Text = "Added {0} ({1})".F(editorActorPreview.Info.Name, editorActorPreview.ID);
        }
Esempio n. 6
0
		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. 7
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

                try
                {
                    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 actor = new ActorReference(parts[1].ToLowerInvariant())
                    {
                        new LocationInit(new int2(loc % MapSize, loc / MapSize)),
                        new OwnerInit(parts[0]),
                        new HealthInit(float.Parse(parts[2], NumberFormatInfo.InvariantInfo) / 256),
                        new FacingInit((section == "INFANTRY") ? int.Parse(parts[6]) : int.Parse(parts[4])),
                    };

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

                    if (!Rules.Info.ContainsKey(parts[1].ToLowerInvariant()))
                    {
                        errorHandler("Ignoring unknown actor type: `{0}`".F(parts[1].ToLowerInvariant()));
                    }
                    else
                    {
                        Map.Actors.Value.Add("Actor" + ActorCount++, actor);
                    }
                }
                catch (Exception)
                {
                    errorHandler("Malformed actor definition: `{0}`".F(s));
                }
            }
        }
Esempio n. 8
0
		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();

				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. 9
0
 public void AddInit <T>(T init) where T : ActorInit
 {
     reference.Add(init);
     GeneratePreviews();
 }
Esempio n. 10
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(kv.Second));
                a.Add(new OwnerInit("Neutral"));
                Map.Actors.Value.Add("spawn" + kv.First, a);
            }
        }
Esempio n. 11
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;
        }
        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 - worldRenderer.ScreenPxOffset(centerOffset));

            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 + c)))
                {
                    return(true);
                }

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

                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. 13
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);
            }
        }
Esempio n. 14
0
        enum IniMapFormat { RedAlert = 3 }         // otherwise, cnc (2 variants exist, we don't care to differentiate)

        public void ConvertIniMap(string iniFile)
        {
            var file            = new IniFile(GlobalFileSystem.Open(iniFile));
            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 size = new Size(mapSize, mapSize);

            var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8);

            map            = Map.FromTileset(rules.TileSets[tileset]);
            map.Title      = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile));
            map.Author     = "Westwood Studios";
            map.MapSize.X  = mapSize;
            map.MapSize.Y  = mapSize;
            map.Bounds     = Rectangle.FromLTRB(offsetX, offsetY, offsetX + width, offsetY + height);
            map.Selectable = true;

            map.Smudges      = Exts.Lazy(() => new List <SmudgeReference>());
            map.Actors       = Exts.Lazy(() => new Dictionary <string, ActorReference>());
            map.MapResources = Exts.Lazy(() => new CellLayer <ResourceTile>(TileShape.Rectangle, size));
            map.MapTiles     = Exts.Lazy(() => new CellLayer <TerrainTile>(TileShape.Rectangle, size));

            map.Options = new MapOptions();

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

            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 => Exts.ParseIntegerInvariant(kv.Value) > 0)
                      .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key),
                                             LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize)))
                      .ToArray();

            // Add waypoint actors
            foreach (var kv in wps)
            {
                if (kv.First <= 7)
                {
                    var a = new ActorReference("mpspawn");
                    a.Add(new LocationInit((CPos)kv.Second));
                    a.Add(new OwnerInit("Neutral"));
                    map.Actors.Value.Add("Actor" + map.Actors.Value.Count.ToString(), a);
                }
                else
                {
                    var a = new ActorReference("waypoint");
                    a.Add(new LocationInit((CPos)kv.Second));
                    a.Add(new OwnerInit("Neutral"));
                    map.Actors.Value.Add("waypoint" + kv.First, a);
                }
            }
        }
Esempio n. 15
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;
                }

                if (OverlayToActor.TryGetValue(overlayType, out var 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)
                        {
                            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;
                            }
                        }
                    }

                    var ar = new ActorReference(actorType)
                    {
                        new LocationInit(cell),
                        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;
                }

                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. 16
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);
        }
		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()));
			}
		}
		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()));
			}
		}
		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. 20
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. 21
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);

            }
        }
		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. 23
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(255 - 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. 24
0
        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)(224 - byte.Parse(entries[type == "Infantry" ? 7 : 5]));

                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(CreepActors.Contains(entries[1]) ? "Creeps" : "Neutral")
                };

                if (type == "Infantry")
                {
                    var subcell = 0;
                    switch (byte.Parse(entries[5]))
                    {
                    case 2: subcell = 3; break;

                    case 3: subcell = 1; break;

                    case 4: subcell = 2; break;
                    }

                    if (subcell != 0)
                    {
                        ar.Add(new SubCellInit((SubCell)subcell));
                    }
                }

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

                ar.Add(new FacingInit(WAngle.FromFacing(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. 25
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));
                }
            }
        }