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); }
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); }
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)); } } }
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())); } }
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); }
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())); } }
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)); } } }
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())); } }
public void AddInit <T>(T init) where T : ActorInit { reference.Add(init); GeneratePreviews(); }
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); } }
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); }
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); } }
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); } } }
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); } }
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 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); } }
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())); } } }
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())); } }
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)); } } }
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())); } } }
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)); } } }