Example #1
0
        //--------------------------------------------------------------------------
        internal VisibilityMatrix( VisibilityMatrix v )
        {
            m_Range = v.m_Range;

            m_Shadows = new uint[v.m_Shadows.Length,1];

            for( int i=0; i<v.m_Shadows.Length; i++ )
            {
            m_Shadows[i,0] = v.m_Shadows[i,0];
            }
        }
Example #2
0
        //--------------------------------------------------------------------------
        //  Add supplemental (non-static/non-land) items into the obstruction matrix;
        //  this is very cheap in comparison to the cost of processing land and statics
        //--------------------------------------------------------------------------
        public void ProcessMatrixItems( Point3D beholder, VisibilityMatrix v )
        {
            // double  start = DateTime.Now.Ticks / 10000000.0;
            // for(int i=0; i<100000; i++)
            // {
            int                 eyelevel = beholder.Z + 12;

            foreach ( Item item in m_map.GetItemsInRange( new Point3D( beholder.X, beholder.Y, 0 ), 15 ))
            {
            //  cutpoint optimization; if the cell is in shadow, don't bother with
            //  any more tests; such a test would be irrelevant:

            if( !v.IsVisible( beholder, item.Location.X, item.Location.Y ))
            {
                int xOffset = item.Location.X - beholder.X;
                int yOffset = item.Location.Y - beholder.Y;

                // this check solves the diagonal problem mentioned in the
                // previous function comments; we don't "cut" for the diagonals.

                if( Math.Abs( xOffset - yOffset ) <= 1) continue;
            }

            if( ItemBlocksVis( item, eyelevel, beholder ) )
                v.ProcessObstructionAt( beholder, item.Location.X, item.Location.Y );
            }
            //}
            // double  stop = DateTime.Now.Ticks / 10000000.0;
            // double  elapsed = stop - start;
            // Console.WriteLine( "ProcessMatrixItems: " + elapsed );
        }
Example #3
0
        //--------------------------------------------------------------------------
        //  Test the Player's visibility matrix to see if they can see things at the
        //   target point. This is the main part of our LOS "can see" function.
        //--------------------------------------------------------------------------
        public bool Visible( Point3D beholder, Point3D beheld )
        {
            //----------------------------------------------------------------------
            //  The center of the visibility matrix, which is always the anchor
            //  point of the player mobile, is cell [range+1-1,range+1-1]. E.g.,
            //  to calculate where the player mobile is in the 37x37 matrix, use
            //  18+1-1 = 18. 0-17,0-17 are leftwards and upwards, 18,18 is the middle,
            //  and 19-36,19-36 are rightwards and downwards.
            //----------------------------------------------------------------------
            bool    visible = false;
            //double  start = DateTime.Now.Ticks / 10000000.0;
            //for(int i=0; i<500; i++)
            //{
            int key = beholder.X * m_map.Width * m_map.Height + beholder.Y * m_map.Height + beholder.Z;

            //----------------------------------------------------------------------
            //  First see if we have a matrix in the cache:
            //----------------------------------------------------------------------

            VisibilityMatrix baseMatrix = m_cache.Hit( key );

            //----------------------------------------------------------------------
            //  If we don't, create it and put it in the cache:
            //----------------------------------------------------------------------

            if( baseMatrix == null )
            {
            baseMatrix = CreateBaseMatrix( beholder );

            m_cache.Store( key, baseMatrix );
            }

            //----------------------------------------------------------------------
            //  Rapidly create a clone of the matric fetched from the cache for
            //  temporary use (this copy is implemented by cheap memcpy in the
            //  CLR, don't wory much about it)
            //----------------------------------------------------------------------

            VisibilityMatrix v = new VisibilityMatrix( baseMatrix );

            //----------------------------------------------------------------------
            //  Add in the obstructions from items into the cache
            //----------------------------------------------------------------------

            ProcessMatrixItems( beholder, v );

            //----------------------------------------------------------------------
            //  Now finally do the test for visibility:
            //----------------------------------------------------------------------

            visible = v.IsVisible( beholder, beheld.X, beheld.Y );

            //}
            // double  stop = DateTime.Now.Ticks / 10000000.0;
            // double  elapsed = stop - start;
            // Console.WriteLine( "VisibleTime: " + elapsed );
            return visible;
        }
Example #4
0
        //--------------------------------------------------------------------------
        //  Create the base matrix; this is the "cacheable" portion of the matrix,
        //  the stuff like land and statics that never really change.
        //--------------------------------------------------------------------------
        public VisibilityMatrix CreateBaseMatrix( Point3D beholder )
        {
            VisibilityMatrix v = new VisibilityMatrix( 15 );
            // VisibilityMatrix v = null;
            // for performance testing--leave in
            // double  start = DateTime.Now.Ticks / 10000000.0;
            // for(int i=0; i<500; i++)
            // {
            int                 eyelevel = beholder.Z + 12;

            //        v = new VisibilityMatrix( 15 );

            //----------------------------------------------------------------------
            //  This is a spiral search pattern from center; the reason we do this
            //  is that starting from the center allows us to benefit from
            //  not having to load up data relating tiles and so forth further out
            //  if x,y cursor is in the shadow of a prior obstruction...
            //----------------------------------------------------------------------

            int locX = beholder.X;
            int locY = beholder.Y;

            for( int j = 0; j < m_SpiralPattern.Length; j++)
            {
            int xOffset = m_SpiralPattern[j][0];
            int yOffset = m_SpiralPattern[j][1];

            int x       = locX + xOffset;
            int y       = locY + yOffset;

            //------------------------------------------------------------------
            //  the spiral pattern could make us walk off the edge of the
            //  map; break out of that here:
            //------------------------------------------------------------------

            if( x < 0 || x > m_map.Width || y < 0 || y > m_map.Height )
                goto cutpoint;

            //------------------------------------------------------------------
            //  Here we optimize by skipping the pulling up of tiles in the
            //  event we are in a shadow; it turns out that in certain diagonal
            //  'L' cases (corners), this doesn't work perfectly, hence the check
            //  for matching abs. x/y offsets ... we don't cut point those.
            //------------------------------------------------------------------

            if  (
                    !v.IsVisible( beholder, x, y )
                    &&
                    Math.Abs( xOffset - yOffset ) <= 1
                )
                goto cutpoint;

            //------------------------------------------------------------------
            //  Now process statics:
            //------------------------------------------------------------------

            StaticTile[] staticTiles = m_map.Tiles.GetStaticTiles( x, y, true );

            foreach (StaticTile staticTile in staticTiles)
            {
                if( TileBlocksVis( staticTile, eyelevel, x, y, beholder ) )
                {
                    v.ProcessObstructionAt( beholder, x, y );
                    goto cutpoint; // further obstructions irrelevant
                }
            }

            //------------------------------------------------------------------
            //  Now process land:
            //------------------------------------------------------------------

            LandTile landTile = m_map.Tiles.GetLandTile( x, y );

            if( LandBlocksVis( landTile, x, y, eyelevel+5, beholder ) )
            {
                v.ProcessObstructionAt( beholder, x, y );
                goto cutpoint; // further obstructions irrelevant
            }

            //------------------------------------------------------------------
            //  Now process "invalid" tiles (the black areas in dungeons):
            //------------------------------------------------------------------

            if( IsVizBlockingInvalidLand( landTile, staticTiles, x, y ) )
            {
                v.ProcessObstructionAt( beholder, x, y );
                goto cutpoint; // further obstructions irrelevant
            }

            //------------------------------------------------------------------
            //  Items left deliberately out here (that's a follow up stage)
            //------------------------------------------------------------------

            //------------------------------------------------------------------
            cutpoint:;  // sorry about the evil goto; please leave this alone for now
            // think of it this way; this is like a destionation for "continue",
            // where code can be if needed.
            //------------------------------------------------------------------
            }
            //}
            // double  stop = DateTime.Now.Ticks / 10000000.0;
            // double  elapsed = stop - start;
            // Console.WriteLine( "CreateBaseMatrixInternalTime: " + elapsed );
            return v;
        }