Example #1
0
        //Executes one turtle step
        private void MoveTurtle(int length, RenderTarget2D target)
        {
            Vector2 newPos = now.currentPosition + (length * GeometryHelper.AngleToVector(GeometryHelper.DegToRad(now.angle)));

            GraphicsHelper.DrawSquareFromVector(spriteBatch, lineTexture, now.currentPosition, newPos, currentColor, length);
            now.currentPosition = newPos;
        }
Example #2
0
        //Check for collisions on one axis (X or Y) at a time and resolve them
        private int TerrainCollisionsXY(bool doCollisionX, Tile nextTile = null)
        {
            int  result = 0;
            Tile tile   = map.GetTileForX((int)position.X);

            if (nextTile != null)
            {
                tile = nextTile;
            }

            if (tile == null)
            {
                return(result);
            }

            Vector2   entityTilePos = map.GlobalToTileCoordinates(position, tile.Index);
            Rectangle bounds        = new Rectangle((int)entityTilePos.X, (int)entityTilePos.Y, Width, Height);

            //todo: add a condition when player is on tile edge - check next/prev tiles edge line

            int wblocks = tile.Coords.Width / Block.Width;
            int hblocks = tile.Coords.Height / Block.Height;

            //Math.Min(sth, block count in that dimension-1) limits the indexes for searching adjacent blocks. If entity gets out of bounds, it'll be considered as being on the last tile in that dimension
            int leftBlockX  = Math.Min((int)Math.Floor(entityTilePos.X / Block.Width), wblocks - 1); //get the X coordinate for neighbouring blocks on the left
            int rightBlockX = Math.Min(leftBlockX + (int)Math.Ceiling((double)Width / Block.Width), wblocks - 1);

            if (leftBlockX < 0)
            {
                leftBlockX = 0;
            }

            //Just to make sure we really don't collide, in case the entity is smaller than one block, extend the checking range
            if (rightBlockX <= leftBlockX)
            {
                rightBlockX = leftBlockX + 1;
            }

            if (rightBlockX >= wblocks)
            {
                rightBlockX = wblocks - 1;
            }

            int topBlockY    = Math.Max(Math.Min((int)Math.Floor(entityTilePos.Y / Block.Height), hblocks - 1), 0); //Math.Max so that we don't check for blocks above the top edge (there are none)
            int bottomBlockY = Math.Min(topBlockY + (int)Math.Ceiling((double)Height / Block.Height) + 1, hblocks - 1);

            //Just to make sure we really don't collide, in case the entity is smaller than one block, again...
            if (bottomBlockY == topBlockY)
            {
                ++bottomBlockY;
            }

            if (bottomBlockY >= hblocks)
            {
                bottomBlockY = hblocks - 1;
            }

            //We don't believe we're grounded until we are proved wrong, prevents doublejumping
            isOnGround = false;

            //Loops through all blocks in selected range and checks for possible collisions. If found, moves the entity out of them
            for (int y = topBlockY; y <= bottomBlockY; ++y)
            {
                for (int x = leftBlockX; x <= rightBlockX; ++x)
                {
                    if (tile.Blocks[x, y] != null)
                    {
                        Rectangle otherElement = new Rectangle(x * Block.Width, y * Block.Height, Block.Width, Block.Height);

                        Vector2 depth = GeometryHelper.GetIntersectionDepth(bounds, otherElement);
                        if (depth != Vector2.Zero)
                        {
                            //In the first call, we check for X-axis collisions
                            if (doCollisionX)
                            {
                                position = new Vector2(Position.X + depth.X, Position.Y);
                                bounds   = BoundingRectangle;
                                result   = (int)depth.X;
                            }

                            //In the second call, we do the Y-axis
                            else
                            {
                                //We hit a box underneath us, we're grounded
                                if ((bounds.Top < otherElement.Top) && (bounds.Bottom > otherElement.Top))
                                {
                                    isOnGround = true;
                                    position   = new Vector2(Position.X, Position.Y + depth.Y);
                                    bounds     = BoundingRectangle;
                                }

                                //We hit a box above us, we're jumping
                                else if ((bounds.Bottom > otherElement.Bottom + 1) && (bounds.Top < otherElement.Bottom))
                                {
                                    position = new Vector2(Position.X, Position.Y + depth.Y);
                                    jumpTime = MaxJumpTime; //we reached the apex of our jump
                                    bounds   = BoundingRectangle;
                                }
                            }
                        }
                    }
                }
            }

            if (position.X < 0)
            {
                position.X = 0;
            }
            else if (position.X + Width > map.Width)
            {
                position.X = map.Width - Width;
            }

            if (rightBlockX == wblocks - 1 && CurrentTile < map.TileCount && nextTile == null)
            {
                var next = map.GetTileByIndex(CurrentTile + 1);
                if (next != null)
                {
                    result = TerrainCollisionsXY(doCollisionX, next);
                }
            }
            else if (leftBlockX == 0 && CurrentTile > 0 && nextTile == null && IsPlayer)
            {
                var next = map.GetTileByIndex(CurrentTile - 1);
                if (next != null)
                {
                    result = TerrainCollisionsXY(doCollisionX, next);
                }
            }

            oldBottom = bounds.Bottom;
            return(result);
        }
Example #3
0
        //Checks how much of the quest is currently completed
        public void CheckCompletion()
        {
            int percent = 0;

            if (Type == QuestType.KillTargets)
            {
                int deadCount = 0;
                //it doesn't matter how they die. If they're dead we got 'em.
                Name = BaseName;
                foreach (Entity e in Targets)
                {
                    if (!e.Alive)
                    {
                        ++deadCount;
                    }

                    Name += e.Name + (!e.Alive ? "*" : "") + ", "; //A star marks a completed part of the quest
                }
                Name = Name.Remove(Name.Length - 2);

                percent = (int)((float)deadCount / Targets.Count * 100);
            }

            else if (Type == QuestType.FetchIitems)
            {
                //hackish way of detecting whether items are placed where they need to be
                int finishedItems = 0;
                Name = BaseName;

                foreach (Item i in RequiredItems)
                {
                    //check whether the item is where it's supposed to be
                    var  dest = DestinationBlocks[0].Coords;
                    var  pos  = i.Position;
                    bool ok   = false;

                    if (i.IsPlaced && pos.X >= dest.Left && pos.Y >= dest.Top && pos.X + i.Width <= dest.Right && pos.Y + i.Height <= dest.Bottom)
                    {
                        ++finishedItems;
                        ok = true;
                    }


                    Name += i.Properties.Name + (ok ? "*" : "") + ", ";
                }
                Name = Name.Remove(Name.Length - 2);
                Name = (Name + " to a green area in tile " + map.GetTileForX(DestinationBlocks[0].Coords.X).Index.ToString());

                percent = (int)((float)finishedItems / RequiredItems.Count * 100);
            }

            else if (Type == QuestType.ReachBlock)
            {
                Name = BaseName;
                //for each point, check whether we've reached it
                foreach (Zone zone in DestinationBlocks)
                {
                    bool ok = false;

                    var block         = zone.Coords;
                    var newPlayerRect = map.TileToGlobalCoordinates(map.Player.BoundingRectangle, map.GetTileByIndex(map.Player.CurrentTile));
                    if (GeometryHelper.GetIntersectionDepth(block, newPlayerRect) != Vector2.Zero)
                    {
                        if (!reachedBlocks.Contains(block)) //We only need to reach it once for it to count towards reachedPoints
                        {
                            reachedBlocks.Add(block);
                            zone.Deactivate();
                        }
                    }

                    if (reachedBlocks.Contains(zone.Coords))
                    {
                        ok = true;
                    }

                    Name += map.GetTileForX(zone.Coords.X).Index + (ok ? "*" : "") + ", ";
                }
                Name = Name.Remove(Name.Length - 2);

                percent = (int)((float)reachedBlocks.Count / DestinationBlocks.Count * 100);
            }

            //Set the display value
            if (percent == 100)
            {
                Progress  = "Done";
                Completed = true;
            }

            else
            {
                Progress = percent.ToString() + "%";
            }
        }