Пример #1
0
        /// <summary>
        /// Set all walls and ledges that are not on the same z index as some entity to ignore it.
        /// Passed from entity MessageHub subscription and is fired when EntityTracker detects that an entity has changed z index.
        /// </summary>
        /// <param name="msg"></param>
        private void _HandleEntityChangedZIndex(EntityChangedZIndexMessage msg)
        {
            RID entityRID = msg.GetEntityRID();
            int zIndex    = msg.GetZIndex();

            GD.PrintS("requested that entity with id: " + entityRID.GetId() + " be moved to collide with segments on z index: " + zIndex);

            foreach (TileMap tileMap in this._tileMapToWallSB2Ds.Keys)
            {
                if (tileMap.ZIndex == zIndex)
                {
                    Physics2DServer.BodyRemoveCollisionException(this._tileMapToWallSB2Ds[tileMap], entityRID);
                }
                else
                {
                    Physics2DServer.BodyAddCollisionException(this._tileMapToWallSB2Ds[tileMap], entityRID);
                }
            }
            foreach (TileMap tileMap in this._tileMapToLedgeSB2Ds.Keys)
            {
                if (tileMap.ZIndex == zIndex)
                {
                    Physics2DServer.BodyRemoveCollisionException(this._tileMapToLedgeSB2Ds[tileMap], entityRID);
                    GD.PrintS("removed collision with sb2d with id: " + this._tileMapToLedgeSB2Ds[tileMap].GetId());
                }
                else
                {
                    Physics2DServer.BodyAddCollisionException(this._tileMapToLedgeSB2Ds[tileMap], entityRID);
                }
            }
        }
Пример #2
0
 /// <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;
 }
Пример #3
0
        /// <summary>
        /// Free all RIDs stored.
        /// </summary>
        private void _FreeRIDs()
        {
            var allRIDs = new List <RID>();

            allRIDs.AddRange(this._tileMapToFloorArea2Ds.Values);
            allRIDs.AddRange(this._tileMapToWallSB2Ds.Values);
            allRIDs.AddRange(this._tileMapToLedgeSB2Ds.Values);
            foreach (List <ConvexPolygonShape2D> polygons in this._floorArea2DToPolygons.Values)
            {
                allRIDs.AddRange(polygons.ConvertAll(x => x.GetRid()));
            }

            foreach (List <SegmentShape2D> segments in this._wallSB2DToSegments.Values)
            {
                allRIDs.AddRange(segments.ConvertAll(x => x.GetRid()));
            }

            foreach (List <SegmentShape2D> segments in this._ledgeSB2DToSegments.Values)
            {
                allRIDs.AddRange(segments.ConvertAll(x => x.GetRid()));
            }

            foreach (RID rid in allRIDs)
            {
                Physics2DServer.FreeRid(rid);
            }
        }
Пример #4
0
    public override void _PhysicsProcess(float delta)
    {
        // If we aren't falling from the sky, make sure we aren't below the viewport
        // Purge the leaf if we are
        // Otherwise, just the skip the rest of the method
        if (!IsSkyFalling)
        {
            if (Body.GlobalPosition.y >= GetViewport().Size.y + 50)
            {
                QueueFree();
            }

            return;
        }

        // The leaf has arrived into position, stop it from moving anymore and set it to true position
        if (Body.Position.DistanceTo(Vector2.Zero) <= 5)
        {
            Body.LinearVelocity = Vector2.Zero;
            Body.GravityScale   = 0;

            var transform = (Transform2D)Physics2DServer.BodyGetState(Body.GetRid(), Physics2DServer.BodyState.Transform);
            transform.origin = new Vector2(0, 0) + GlobalPosition;
            Physics2DServer.BodySetState(Body.GetRid(), Physics2DServer.BodyState.Transform, transform);

            IsSkyFalling = false;

            EmitSignal("SkyLeafDropped");
        }
    }
Пример #5
0
    public Godot.Collections.Dictionary Attack(int x, int y)
    {
        var spaceRid   = GetWorld2d().Space;
        var spaceState = Physics2DServer.SpaceGetDirectState(spaceRid);

        // check the spot to move to
        var result = spaceState.IntersectRay(new Vector2(x * gridSize + 1, y * gridSize + 1), new Vector2(x * 16 + 2, y * 16 + 2));

        return(result);
    }
    public Godot.Collections.Dictionary MoveGridBase(int x, int y)
    {
        var spaceRid   = GetWorld2d().Space;
        var spaceState = Physics2DServer.SpaceGetDirectState(spaceRid);

        // check the spot to move to
        var result = spaceState.IntersectRay(new Vector2(x * gridSize + 1, y * gridSize + 1), new Vector2(x * 16 + 2, y * 16 + 2));

        if (result.Count == 0)         // if there is no one there
        {
            newPosition  = new Vector2(x * gridSize, y * gridSize);
            gridPosition = new Vector2(x, y);
        }
        return(result);
    }
Пример #7
0
        public static Vector2 SimpleRayCast(CanvasItem spaceNode, Vector2 from, Vector2 to, out bool success)
        {
            Physics2DDirectSpaceState physicsState = Physics2DServer.SpaceGetDirectState(spaceNode.GetWorld2d().Space);
            Dictionary result = physicsState.IntersectRay(from, to, GodotUtility.MakeGDArray(spaceNode));

            if (result.ContainsKey("position"))
            {
                success = true;
                return((Vector2)result["position"]);
            }
            else
            {
                success = false;
                return(new Vector2());
            }
        }
Пример #8
0
        /// <summary>
        /// Constructs a dictionary that maps a TileMap to a Physics2DServer-created StaticBody2D (RID).
        /// Is used for both the walls and ledges dictionaries.
        /// </summary>
        /// <param name="tileMaps">List of TileMaps.</param>
        /// <param name="worldSpace">RID of the World Space.</param>
        /// <returns>A Dictionary that maps TileMaps to an RID of a StaticBody2D.</returns>
        public static Dictionary<TileMap, RID> ConstructTileMapCollisionMap(this TileMapList tileMaps, RID worldSpace)
        {
            if (tileMaps is null) throw new ArgumentNullException(nameof(tileMaps));

            var tileMapToSB2Ds = new Dictionary<TileMap, RID>();
            foreach (TileMap tileMap in tileMaps.Values)
            {
                RID edgeSB2D = Physics2DServer.BodyCreate();
                Physics2DServer.BodySetMode(edgeSB2D, Physics2DServer.BodyMode.Static);
                Physics2DServer.BodySetSpace(edgeSB2D, worldSpace);
                Physics2DServer.BodySetState(edgeSB2D, Physics2DServer.BodyState.Transform, Transform2D.Identity);
                Physics2DServer.BodySetCollisionLayer(edgeSB2D, LayersFuncs.GetLayersValue(Terrain));
                Physics2DServer.BodySetCollisionMask(edgeSB2D, LayersFuncs.GetLayersValue(PlayerEntity, NpcEntity));
                tileMapToSB2Ds.Add(tileMap, edgeSB2D);
            }
            return tileMapToSB2Ds;
        }
Пример #9
0
        /// <summary>
        /// Creates a FloorArea2D for each TileMap.
        /// </summary>
        /// <param name="tileMaps"></param>
        /// <param name="worldSpace"></param>
        /// <returns></returns>
        public static Dictionary <TileMap, RID> ConstructTileMapFloorMap(this TileMapList tileMaps, RID worldSpace)
        {
            if (tileMaps is null)
            {
                throw new ArgumentNullException(nameof(tileMaps));
            }

            var tileMapToFloorArea2D = new Dictionary <TileMap, RID>();

            foreach (TileMap tileMap in tileMaps.Values)
            {
                RID area2d = Physics2DServer.AreaCreate();
                Physics2DServer.AreaSetSpace(area2d, worldSpace);
                tileMapToFloorArea2D[tileMap] = area2d;
            }
            return(tileMapToFloorArea2D);
        }
Пример #10
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);
        }
Пример #11
0
    public Godot.Collections.Dictionary AttackColumn(int x, int y, bool up)
    {
        var spaceRid   = GetWorld2d().Space;
        var spaceState = Physics2DServer.SpaceGetDirectState(spaceRid);
        var rayStart   = new Vector2(16 * x + 8, 16 * y + 8);
        // check the spot to move to
        var rayEnd = new Vector2(0, 0);

        if (up)
        {
            rayEnd = new Vector2(16 * x + 8, 8);
        }
        else
        {
            rayEnd = new Vector2(16 * x + 8, 16 * 20 + 8);
        }
        var result = spaceState.IntersectRay(rayStart, rayEnd);

        return(result);
    }
Пример #12
0
        public static RayCastHitInfo RayCastObject(CanvasItem spaceNode, Vector2 from, Vector2 to, out bool success)
        {
            Physics2DDirectSpaceState physicsState = Physics2DServer.SpaceGetDirectState(spaceNode.GetWorld2d().Space);
            Dictionary result = physicsState.IntersectRay(from, to, GodotUtility.MakeGDArray(spaceNode));

            if (result.ContainsKey("position"))
            {
                success = true;
                RayCastHitInfo info = new RayCastHitInfo();
                info.position = (Vector2)result["position"];
                if (result.ContainsKey("collider"))
                {
                    info.collider = (Godot.Object)result["collider"];
                }
                return(info);
            }
            else
            {
                success = false;
                return(null);
            }
        }
Пример #13
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");
        }