/// <summary> /// Default constructor /// </summary> public Game(ContentManager content, ReportProgressDelegate reporter = null) { ProgressReporter = reporter; ProgressReporter?.Invoke(0, "Loading Prefabs..."); Content = content; var newMap = Content.Load <TiledMap>($"Maps/Prefabs"); // Load tilesets foreach (var tileset in newMap.Tilesets) { Tilesets.Add(tileset); } foreach (var i in Tilesets) { int?anyLid = i.Tiles.FirstOrDefault(j => j.Properties.ContainsKey("name") && j.Properties["name"] == "BaseAny")?.LocalTileIdentifier; if (anyLid != null) { BaseAnyTile = i.FirstGlobalIdentifier + anyLid.Value; } int?roadLid = i.Tiles.FirstOrDefault(j => j.Properties.ContainsKey("name") && j.Properties["name"] == "BaseRoad")?.LocalTileIdentifier; if (roadLid != null) { BaseRoadTile = i.FirstGlobalIdentifier + roadLid.Value; } int?sidewalkLid = i.Tiles.FirstOrDefault(j => j.Properties.ContainsKey("name") && j.Properties["name"] == "BaseSidewalk")?.LocalTileIdentifier; if (sidewalkLid != null) { BaseSidewalkTile = i.FirstGlobalIdentifier + sidewalkLid.Value; } int?wallLid = i.Tiles.FirstOrDefault(j => j.Properties.ContainsKey("name") && j.Properties["name"] == "BaseWall")?.LocalTileIdentifier; if (wallLid != null) { BaseWallTile = i.FirstGlobalIdentifier + wallLid.Value; } foreach (var j in i.Tiles) { TileByGid.Add(j.LocalTileIdentifier + i.FirstGlobalIdentifier, j); } } PrefabMap = newMap; GlobalMap = new MapTile[MetaTileWidth * MetaGlobalWidth, MetaTileHeight *MetaGlobalHeight]; for (int ix = 0; ix < MapWidth; ++ix) { for (int iy = 0; iy < MapHeight; ++iy) { var walkable = true; GlobalMap[ix, iy] = new MapTile(Tilesets, BaseAnyTile); } } Player = new Player(GlobalMap, this); Actors.Add(Player); // Generate metamap ProgressReporter?.Invoke(10, "Building road network..."); GenerateMetamap(); PlayerStart = new XY(3 + MetaTileWidth * Metamap.GetLength(0) / 2, 3 + MetaTileHeight * Metamap.GetLength(1) / 2); ProgressReporter?.Invoke(20, "Generating map..."); GenerateMap(); ProgressReporter?.Invoke(90, "Placing mobs..."); GenerateMobs(); Player.Location = PlayerStart; }
/// <summary> /// Runs the model ingest & merge procedure. /// </summary> /// <param name="progressAction">The action to take on progress</param> /// <param name="cancellationPending">The indicator of a pending cancel</param> public void RunModelMerge(ReportProgressDelegate progressAction = null, Func <bool> cancellationPending = null) { var candidateInstances = Models.SelectMany(m => m.Instances).OfType <IIfcProduct>(); long totalCount = Models.Select(m => m.Instances.Count).Sum(); long currentCount = 0; int recentPercentage = 0; Builder.Wrap(s => { Dictionary <IIfcProduct, XbimMatrix3D> t2Inv = new Dictionary <IIfcProduct, XbimMatrix3D>(); progressAction?.Invoke(0, $"Start injection into ${s.FileName}"); foreach (var i in candidateInstances) { ++currentCount; if (cancellationPending?.Invoke() ?? false) { Logger?.LogInformation($"Canceling model ingest of {s.FileName}"); // Don't apply changes return(false); } if (CopyExpressType.Contains(i.XLabel().LocalName)) { var newProduct = s.InsertCopy(i, HandleMapOf(i), PropertyTransform, true, false); if (i.ObjectPlacement is IIfcGridPlacement gp) { // Since grids are products, they were to be embedded into the model too Logger?.LogWarning($"Can't transfer grid placement #{gp.EntityLabel}. Replacing #{newProduct.EntityLabel} of {i.ExpressType} with local placement."); } // Get original aggregated transformation var t1 = PlacementOf(i); // Get container transformation var container = FindContainer(i); XbimMatrix3D t2; if (t2Inv.TryGetValue(container, out t2)) { // Compute inv of container local placement t2 = PlacementOf(container); t2.Invert(); t2Inv.Add(container, t2); } // New placement based on given global transformation var c2 = t2 * t1; var placement = s.NewLocalPlacement(c2, true); // Relate to product and container newProduct.ObjectPlacement = placement; s.NewContains(container).RelatedElements.Add(newProduct); } int percentage = (int)Math.Ceiling(100.0 * currentCount / totalCount); if (recentPercentage < percentage) { progressAction?.Invoke(recentPercentage = percentage, null); } } progressAction?.Invoke(100, $"Finalized injection into ${s.FileName}"); // Apply changes return(true); }); }