/// <summary>
 /// Creates and returns a dictionary that maps a TileMap's StaticBody2D's RID to said TileMap's walls or ledges.
 /// </summary>
 /// <param name="tileMaps">List of TileMaps.</param>
 /// <param name="tileMapToSB2Ds">Map of TileMap to its SB2D, whether its origin was a wall or ledge.</param>
 /// <param name="perimData">Data of all perimeters of all TileMaps.</param>
 /// <param name="ledgeData">Data of all ledges of all TileMaps.</param>
 /// <param name="option">Whether this function is being used to construct segments for walls or ledges.</param>
 /// <returns>A dictionary that maps a TileMap's SB2D RID to said TileMap's walls.</returns>
 public static Dictionary<RID, List<SegmentShape2D>> ConstructSB2DSegments(this TileMapList tileMaps,
                                                                           Dictionary<TileMap, RID> tileMapToSB2Ds,
                                                                           PerimeterData perimData,
                                                                           LedgeData ledgeData,
                                                                           StaticBodyOrigin option)
 {
     if (tileMaps is null) throw new ArgumentNullException(nameof(tileMaps));
     if (tileMapToSB2Ds is null) throw new ArgumentNullException(nameof(tileMapToSB2Ds));
     if (perimData is null) throw new ArgumentNullException(nameof(perimData));
     if (ledgeData is null) throw new ArgumentNullException(nameof(ledgeData));
     
     var sb2dToSegments = new Dictionary<RID, List<SegmentShape2D>>();
     foreach (TileMap tileMap in tileMaps.Values)
     {
         RID wall = tileMapToSB2Ds[tileMap];
         List<SegmentShape2D> segments = (option == StaticBodyOrigin.Wall) ?
                                               _GetWallSegments(tileMaps, tileMap, perimData) :
                                               _GetLedgeSegments(tileMaps, tileMap, ledgeData);
         sb2dToSegments.Add(wall, segments);
         foreach (SegmentShape2D segment in segments)
         {
             Physics2DServer.BodyAddShape(wall, segment.GetRid());
         }
     }
     return sb2dToSegments;
 }
Esempio n. 2
0
                       LedgeData ledgeData) BuildTileNodes(IEnumerable <Node> worldChildren)
        {
            if (worldChildren is null)
            {
                throw new ArgumentNullException(nameof(worldChildren));
            }

            TileMapList tileMaps  = _FillTilemapsArray(worldChildren);
            var         perimData = new PerimeterData(tileMaps);
            var         ledgeData = new LedgeData(perimData, tileMaps);

            return(tileMaps, perimData, ledgeData);
        }
Esempio n. 3
0
        ConstructFloorPartitions(this TileMapList tileMaps, Dictionary <TileMap, RID> tileMapToFloorArea2Ds,
                                 PerimeterData perimData)
        {
            if (tileMaps is null)
            {
                throw new ArgumentNullException(nameof(tileMaps));
            }
            if (tileMapToFloorArea2Ds is null)
            {
                throw new ArgumentNullException(nameof(tileMapToFloorArea2Ds));
            }
            if (perimData is null)
            {
                throw new ArgumentNullException(nameof(perimData));
            }

            var floorArea2DToPolygons = new Dictionary <RID, List <ConvexPolygonShape2D> >();

            foreach (TileMap tileMap in tileMaps.Values)
            {
                RID area2dRID = tileMapToFloorArea2Ds[tileMap];
                floorArea2DToPolygons[area2dRID] = new List <ConvexPolygonShape2D>();
                Physics2DServer.AreaSetCollisionLayer(area2dRID, LayersFuncs.GetLayersValue(Terrain));
                Physics2DServer.AreaSetCollisionMask(area2dRID, LayersFuncs.GetLayersValue(PlayerEntity, NpcEntity));

                int maxTileGroups = perimData.GetMaxTileGroup(tileMap);
                for (int tileGroup = 0; tileGroup < maxTileGroups; tileGroup++)
                {
                    int maxHoleGroups = perimData.GetMaxHoleGroup(tileMap, tileGroup);
                    var allPerims     = new List <Vector2> [maxHoleGroups];
                    for (int holeGroup = 0; holeGroup < maxHoleGroups; holeGroup++)
                    { //put all perims (outer and hole) from one tile group into a single array of lists (gods help me) for partitioning
                        EdgeCollection <TileEdge> edgeColl = perimData.GetEdgeCollection(tileMap, tileGroup, holeGroup);
                        allPerims[holeGroup] = new List <Vector2>(edgeColl.GetSimplifiedPerim());
                    }
                    List <ConvexPolygonShape2D> partitionedRectangles = _PartitionPolygonToRectangles(allPerims);
                    foreach (ConvexPolygonShape2D shape in partitionedRectangles)
                    {
                        Physics2DServer.AreaAddShape(area2dRID, shape.GetRid());
                        GD.PrintS("added shape " + shape.GetRid().GetId() + " to area: " + area2dRID.GetId());
                    }
                    floorArea2DToPolygons[area2dRID].AddRange(partitionedRectangles);
                }
            }
            return(floorArea2DToPolygons);
        }
Esempio n. 4
0
        /// <summary>
        /// Should be called whenever loaded world changes.
        /// Resets all wall and ledge physics bodies and prepares new ones to be filled by TileController.
        /// </summary>
        /// <param name="tileMaps">List of TileMaps which are guaranteed to have a unique Z index.</param>
        /// <param name="perimData">Data of all perimeters of all TileMaps.</param>
        /// <param name="ledgeData">Data of all ledges of all TileMaps.</param>
        /// <param name="worldSpace">Current world space.</param>
        public void LoadWorld(TileMapList tileMaps, PerimeterData perimData, LedgeData ledgeData, RID worldSpace)
        {
            if (tileMaps == null)
            {
                throw new ArgumentNullException(nameof(tileMaps), "Attempted to load world with no tilemaps.");
            }

            this._tileMapToFloorArea2Ds = tileMaps.ConstructTileMapFloorMap(worldSpace);
            this._tileMapToWallSB2Ds    = tileMaps.ConstructTileMapCollisionMap(worldSpace);
            this._tileMapToLedgeSB2Ds   = tileMaps.ConstructTileMapCollisionMap(worldSpace);
            this._floorArea2DToPolygons = tileMaps.ConstructFloorPartitions(this._tileMapToFloorArea2Ds, perimData);
            this._wallSB2DToSegments    = tileMaps.ConstructSB2DSegments(this._tileMapToWallSB2Ds, perimData, ledgeData,
                                                                         CollisionConstructor.StaticBodyOrigin.Wall);
            this._ledgeSB2DToSegments = tileMaps.ConstructSB2DSegments(this._tileMapToLedgeSB2Ds, perimData, ledgeData,
                                                                       CollisionConstructor.StaticBodyOrigin.Ledge);

            this._toEntityHub.Publish(new FloorsConstructedMessage(this, this._tileMapToFloorArea2Ds));
            foreach (TileMap tileMap in tileMaps.Values)
            {
                GD.PrintS("TileMapToFloorArea2Ds RID for tilemap with zIndex " + tileMap.ZIndex + ": " + this._tileMapToFloorArea2Ds[tileMap].GetId());
                //GD.PrintS("TileMapToWallSB2Ds RID for tilemap with zIndex " + tileMap.ZIndex + ": " +  this.tileMapToWallSB2Ds[tileMap].GetId());
                //GD.PrintS("TileMapToLedgeSB2Ds RID for tilemap with zIndex " + tileMap.ZIndex + ": " +  this.tileMapToLedgeSB2Ds[tileMap].GetId());

                RID floorRID = this._tileMapToFloorArea2Ds[tileMap];
                RID wallRID  = this._tileMapToWallSB2Ds[tileMap];
                RID ledgeRID = this._tileMapToLedgeSB2Ds[tileMap];
                GD.PrintS("floorArea2DToPolygons count: " + this._floorArea2DToPolygons[floorRID].Count);
                GD.PrintS("wallSB2DToSegments count: " + this._wallSB2DToSegments[wallRID].Count);
                GD.PrintS("ledgeSB2DToSegments count: " + this._ledgeSB2DToSegments[ledgeRID].Count);

                this._area2DMonitors[floorRID.GetId()] = new Area2DMonitor(floorRID, tileMap.ZIndex, this._floorArea2DToPolygons[floorRID], this._toEntityHub);
                Physics2DServer.AreaSetMonitorCallback(floorRID, this._area2DMonitors[floorRID.GetId()], nameof(Area2DMonitor.OnAreaCallback));
            }
            this._toEntityHub.Publish(new AreaMonitorsSetupMessage(this));
            GD.PrintS("published areamonitor msg");
        }
        ///////////////////////////
        ///////////////////////////
        ////PRIVATE FUNCS BELOW////
        ///////////////////////////
        ///////////////////////////

        /// <summary>
        /// For a given TileMap, gets its walls as a list of SegmentShape2Ds by getting perimData's EdgeCollections for the
        /// TileMap directly above the given TileMap.
        /// </summary>
        /// <param name="tileMaps">TileMapList of TileMaps.</param>
        /// <param name="thisTileMap">The TileMap that this function is getting walls for.</param>
        /// <param name="perimData">Data of all perimeters of all TileMaps in the currently loaded world.</param>
        /// <returns>A List of SegmentShape2Ds that contain every segment that make up every wall in thisTileMap.</returns>
        private static List<SegmentShape2D> _GetWallSegments(TileMapList tileMaps, TileMap thisTileMap, PerimeterData perimData)
        {
            var allSegments = new List<SegmentShape2D>();
            if (thisTileMap == tileMaps.Last()) return allSegments; //there are never walls on the highest TileMap

            int nextIndex = thisTileMap.ZIndex + 1;
            TileMap nextTileMap = tileMaps[nextIndex];
            int maxTileGroups = perimData.GetMaxTileGroup(nextTileMap);
            for (int tileGroup = 0; tileGroup < maxTileGroups; tileGroup++)
            {
                int maxHoleGroups = perimData.GetMaxHoleGroup(nextTileMap, tileGroup);
                for (int holeGroup = 0; holeGroup < maxHoleGroups; holeGroup++)
                {
                    EdgeCollection<TileEdge> wallColl = perimData.GetEdgeCollection(nextTileMap, tileGroup, holeGroup);
                    IEnumerable<SegmentShape2D> thisWallSegments = _ShiftSegmentsDown(_EdgeCollToSegments(wallColl));
                    allSegments.AddRange(thisWallSegments);
                }
            }
            return allSegments;
        }
Esempio n. 6
0
 public LedgeData(PerimeterData perimData, TileMapList tileMaps)
 {
     (this._ledgeCollMap, this._ledgeGroupMap, this._holeGroupMap, this._tileGroupMap) = tileMaps.BuildLedges(perimData);
     (this._ledgeCollMap, this._ledgeGroupMap) = tileMaps.SuperimposeLedges(this._ledgeCollMap, this._ledgeGroupMap,
                                                                            this._holeGroupMap, this._tileGroupMap);
 }
Esempio n. 7
0
                       Dictionary <HoleGroupKey, int>, Dictionary <TileGroupKey, int>) BuildLedges(this TileMapList tileMaps,
                                                                                                   PerimeterData perimData)
        {
            if (tileMaps is null)
            {
                throw new ArgumentNullException(nameof(tileMaps));
            }
            if (perimData is null)
            {
                throw new ArgumentNullException(nameof(perimData));
            }

            var ledgeCollMap  = new Dictionary <LedgeCollKey, EdgeCollection <TileEdge> >();
            var ledgeGroupMap = new Dictionary <LedgeGroupKey, int>();
            var holeGroupMap  = new Dictionary <HoleGroupKey, int>();
            var tileGroupMap  = new Dictionary <TileGroupKey, int>();

            foreach (TileMap tileMap in tileMaps.Values)
            {
                int maxTileGroups = perimData.GetMaxTileGroup(tileMap);
                tileGroupMap.Add(new TileGroupKey(tileMap), maxTileGroups);
                for (int tileGroup = 0; tileGroup < maxTileGroups; tileGroup++)
                {
                    int maxHoleGroups = perimData.GetMaxHoleGroup(tileMap, tileGroup);
                    holeGroupMap.Add(new HoleGroupKey(tileMap, tileGroup), maxHoleGroups);
                    for (int holeGroup = 0; holeGroup < maxHoleGroups; holeGroup++)
                    {
                        EdgeCollection <TileEdge> thisPerim = perimData.GetEdgeCollection(tileMap, tileGroup, holeGroup);
                        (ledgeCollMap, ledgeGroupMap) = _FillLedges(ledgeCollMap, ledgeGroupMap, tileMaps,
                                                                    tileMap, thisPerim, tileGroup, holeGroup);
                    }
                }
            }

            return(ledgeCollMap, ledgeGroupMap, holeGroupMap, tileGroupMap);
        }