Add() 공개 메소드

public Add ( Server.Point3D p ) : void
p Server.Point3D
리턴 void
예제 #1
0
        public bool LineOfSight(Point3D org, Point3D dest)
        {
            if (this == Map.Internal)
            {
                return(false);
            }

            if (!org.InRange(dest, MaxLOSDistance))
            {
                return(false);
            }

            Point3D end = dest;

            if (org.X > dest.X || (org.X == dest.X && org.Y > dest.Y) || (org.X == dest.X && org.Y == dest.Y && org.Z > dest.Z))
            {
                Point3D swap = org;
                org  = dest;
                dest = swap;
            }

            double      rise, run, zslp;
            double      sq3d;
            double      x, y, z;
            int         xd, yd, zd;
            int         ix, iy, iz;
            int         height;
            bool        found;
            Point3D     p;
            Point3DList path = m_PathList;
            TileFlag    flags;

            if (org == dest)
            {
                return(true);
            }

            if (path.Count > 0)
            {
                path.Clear();
            }

            xd   = dest.X - org.X;
            yd   = dest.Y - org.Y;
            zd   = dest.Z - org.Z;
            zslp = Math.Sqrt(xd * xd + yd * yd);
            if (zd != 0)
            {
                sq3d = Math.Sqrt(zslp * zslp + zd * zd);
            }
            else
            {
                sq3d = zslp;
            }

            rise = ((float)yd) / sq3d;
            run  = ((float)xd) / sq3d;
            zslp = ((float)zd) / sq3d;

            y = org.Y;
            z = org.Z;
            x = org.X;
            while (Utility.NumberBetween(x, dest.X, org.X, 0.5) && Utility.NumberBetween(y, dest.Y, org.Y, 0.5) && Utility.NumberBetween(z, dest.Z, org.Z, 0.5))
            {
                ix = (int)Math.Round(x);
                iy = (int)Math.Round(y);
                iz = (int)Math.Round(z);
                if (path.Count > 0)
                {
                    p = path.Last;

                    if (p.X != ix || p.Y != iy || p.Z != iz)
                    {
                        path.Add(ix, iy, iz);
                    }
                }
                else
                {
                    path.Add(ix, iy, iz);
                }
                x += run;
                y += rise;
                z += zslp;
            }

            if (path.Count == 0)
            {
                return(true);                // should never happen, but to be safe.
            }
            p = path.Last;

            if (p != dest)
            {
                path.Add(dest);
            }

            Point3D pTop = org, pBottom = dest;

            Utility.FixPoints(ref pTop, ref pBottom);

            int pathCount = path.Count;

            for (int i = 0; i < pathCount; ++i)
            {
                Point3D point = path[i];

                Tile landTile = Tiles.GetLandTile(point.X, point.Y);
                int  landZ = 0, landAvg = 0, landTop = 0;
                GetAverageZ(point.X, point.Y, ref landZ, ref landAvg, ref landTop);

                if (landZ <= point.Z && landTop >= point.Z && (point.X != end.X || point.Y != end.Y || landZ > end.Z || landTop < end.Z) && !landTile.Ignored)
                {
                    return(false);
                }

                Tile[] statics = Tiles.GetStaticTiles(point.X, point.Y, true);

                bool contains = false;
                int  ltID     = landTile.ID;

                for (int j = 0; !contains && j < InvalidLandTiles.Length; ++j)
                {
                    contains = (ltID == InvalidLandTiles[j]);
                }

                if (contains && statics.Length == 0)
                {
                    foreach (Item item in GetItemsInRange(point, 0))
                    {
                        if (item.Visible)
                        {
                            contains = false;
                        }

                        if (!contains)
                        {
                            break;
                        }
                    }

                    if (contains)
                    {
                        return(false);
                    }
                }

                for (int j = 0; j < statics.Length; ++j)
                {
                    Tile t = statics[j];

                    ItemData id = TileData.ItemTable[t.ID & TileData.MaxItemValue];

                    flags  = id.Flags;
                    height = id.CalcHeight;

                    if (t.Z <= point.Z && t.Z + height >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0)
                    {
                        if (point.X == end.X && point.Y == end.Y && t.Z <= end.Z && t.Z + height >= end.Z)
                        {
                            continue;
                        }

                        return(false);
                    }
                }
            }

            Rectangle2D rect = new Rectangle2D(pTop.X, pTop.Y, (pBottom.X - pTop.X) + 1, (pBottom.Y - pTop.Y) + 1);

            foreach (Item i in GetItemsInBounds(rect))
            {
                if (!i.Visible)
                {
                    continue;
                }

                if (i is BaseMulti || i.ItemID > TileData.MaxItemValue)
                {
                    continue;
                }

                ItemData id = i.ItemData;
                flags = id.Flags;

                if ((flags & (TileFlag.Window | TileFlag.NoShoot)) == 0)
                {
                    continue;
                }

                height = id.CalcHeight;

                found = false;

                int count = path.Count;

                for (int j = 0; j < count; ++j)
                {
                    Point3D point = path[j];
                    Point3D loc   = i.Location;

                    if (loc.X == point.X && loc.Y == point.Y &&
                        loc.Z <= point.Z && loc.Z + height >= point.Z)
                    {
                        if (loc.X == end.X && loc.Y == end.Y && loc.Z <= end.Z && loc.Z + height >= end.Z)
                        {
                            continue;
                        }

                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    continue;
                }

                return(false);
            }

            return(true);
        }
예제 #2
0
파일: Map.cs 프로젝트: phpjunkie420/RunUO
		public bool LineOfSight( Point3D org, Point3D dest )
		{
			if( this == Map.Internal )
				return false;

			if( !Utility.InRange( org, dest, m_MaxLOSDistance ) )
				return false;

			Point3D start = org;
			Point3D end = dest;

			if( org.X > dest.X || (org.X == dest.X && org.Y > dest.Y) || (org.X == dest.X && org.Y == dest.Y && org.Z > dest.Z) )
			{
				Point3D swap = org;
				org = dest;
				dest = swap;
			}

			double rise, run, zslp;
			double sq3d;
			double x, y, z;
			int xd, yd, zd;
			int ix, iy, iz;
			int height;
			bool found;
			Point3D p;
			Point3DList path = m_PathList;
			TileFlag flags;

			if( org == dest )
				return true;

			if( path.Count > 0 )
				path.Clear();

			xd = dest.m_X - org.m_X;
			yd = dest.m_Y - org.m_Y;
			zd = dest.m_Z - org.m_Z;
			zslp = Math.Sqrt( xd * xd + yd * yd );
			if( zd != 0 )
				sq3d = Math.Sqrt( zslp * zslp + zd * zd );
			else
				sq3d = zslp;

			rise = ((float)yd) / sq3d;
			run = ((float)xd) / sq3d;
			zslp = ((float)zd) / sq3d;

			y = org.m_Y;
			z = org.m_Z;
			x = org.m_X;
			while( Utility.NumberBetween( x, dest.m_X, org.m_X, 0.5 ) && Utility.NumberBetween( y, dest.m_Y, org.m_Y, 0.5 ) && Utility.NumberBetween( z, dest.m_Z, org.m_Z, 0.5 ) )
			{
				ix = (int)Math.Round( x );
				iy = (int)Math.Round( y );
				iz = (int)Math.Round( z );
				if( path.Count > 0 )
				{
					p = path.Last;

					if( p.m_X != ix || p.m_Y != iy || p.m_Z != iz )
						path.Add( ix, iy, iz );
				}
				else
				{
					path.Add( ix, iy, iz );
				}
				x += run;
				y += rise;
				z += zslp;
			}

			if( path.Count == 0 )
				return true;//<--should never happen, but to be safe.

			p = path.Last;

			if( p != dest )
				path.Add( dest );

			Point3D pTop = org, pBottom = dest;
			Utility.FixPoints( ref pTop, ref pBottom );

			int pathCount = path.Count;

			for( int i = 0; i < pathCount; ++i )
			{
				Point3D point = path[i];

				LandTile landTile = Tiles.GetLandTile( point.X, point.Y );
				int landZ = 0, landAvg = 0, landTop = 0;
				GetAverageZ( point.m_X, point.m_Y, ref landZ, ref landAvg, ref landTop );

				if( landZ <= point.m_Z && landTop >= point.m_Z && (point.m_X != end.m_X || point.m_Y != end.m_Y || landZ > end.m_Z || landTop < end.m_Z) && !landTile.Ignored )
					return false;

				/* --Do land tiles need to be checked?  There is never land between two people, always statics.--
				LandTile landTile = Tiles.GetLandTile( point.X, point.Y );
				if ( landTile.Z-1 >= point.Z && landTile.Z+1 <= point.Z && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Impassable) != 0 )
					return false;
				*/

				StaticTile[] statics = Tiles.GetStaticTiles( point.m_X, point.m_Y, true );

				bool contains = false;
				int ltID = landTile.ID;

				for( int j = 0; !contains && j < m_InvalidLandTiles.Length; ++j )
					contains = (ltID == m_InvalidLandTiles[j]);

				if( contains && statics.Length == 0 )
				{
					IPooledEnumerable eable = GetItemsInRange( point, 0 );

					foreach( Item item in eable )
					{
						if( item.Visible )
							contains = false;

						if( !contains )
							break;
					}

					eable.Free();

					if( contains )
						return false;
				}

				for( int j = 0; j < statics.Length; ++j )
				{
					StaticTile t = statics[j];

					ItemData id = TileData.ItemTable[t.ID & TileData.MaxItemValue];

					flags = id.Flags;
					height = id.CalcHeight;

					if( t.Z <= point.Z && t.Z + height >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0 )
					{
						if( point.m_X == end.m_X && point.m_Y == end.m_Y && t.Z <= end.m_Z && t.Z + height >= end.m_Z )
							continue;

						return false;
					}

					/*if ( t.Z <= point.Z && t.Z+height >= point.Z && (flags&TileFlag.Window)==0 && (flags&TileFlag.NoShoot)!=0
						&& ( (flags&TileFlag.Wall)!=0 || (flags&TileFlag.Roof)!=0 || (((flags&TileFlag.Surface)!=0 && zd != 0)) ) )*/
					/*{
						//Console.WriteLine( "LoS: Blocked by Static \"{0}\" Z:{1} T:{3} P:{2} F:x{4:X}", TileData.ItemTable[t.ID&TileData.MaxItemValue].Name, t.Z, point, t.Z+height, flags );
						//Console.WriteLine( "if ( {0} && {1} && {2} && ( {3} || {4} || {5} || ({6} && {7} && {8}) ) )", t.Z <= point.Z, t.Z+height >= point.Z, (flags&TileFlag.Window)==0, (flags&TileFlag.Impassable)!=0, (flags&TileFlag.Wall)!=0, (flags&TileFlag.Roof)!=0, (flags&TileFlag.Surface)!=0, t.Z != dest.Z, zd != 0 ) ;
						return false;
					}*/
				}
			}

			Rectangle2D rect = new Rectangle2D( pTop.m_X, pTop.m_Y, (pBottom.m_X - pTop.m_X) + 1, (pBottom.m_Y - pTop.m_Y) + 1 );

			IPooledEnumerable area = GetItemsInBounds( rect );

			foreach( Item i in area )
			{
				if( !i.Visible )
					continue;

				if( i is BaseMulti || i.ItemID > TileData.MaxItemValue )
					continue;

				ItemData id = i.ItemData;
				flags = id.Flags;

				if( (flags & (TileFlag.Window | TileFlag.NoShoot)) == 0 )
					continue;

				height = id.CalcHeight;

				found = false;

				int count = path.Count;

				for( int j = 0; j < count; ++j )
				{
					Point3D point = path[j];
					Point3D loc = i.Location;

					//if ( t.Z <= point.Z && t.Z+height >= point.Z && ( height != 0 || ( t.Z == dest.Z && zd != 0 ) ) )
					if( loc.m_X == point.m_X && loc.m_Y == point.m_Y &&
						loc.m_Z <= point.m_Z && loc.m_Z + height >= point.m_Z )
					{
						if( loc.m_X == end.m_X && loc.m_Y == end.m_Y && loc.m_Z <= end.m_Z && loc.m_Z + height >= end.m_Z )
							continue;

						found = true;
						break;
					}
				}

				if( !found )
					continue;

				area.Free();
				return false;

				/*if ( (flags & (TileFlag.Impassable | TileFlag.Surface | TileFlag.Roof)) != 0 )

				//flags = TileData.ItemTable[i.ItemID&TileData.MaxItemValue].Flags;
				//if ( (flags&TileFlag.Window)==0 && (flags&TileFlag.NoShoot)!=0 && ( (flags&TileFlag.Wall)!=0 || (flags&TileFlag.Roof)!=0 || (((flags&TileFlag.Surface)!=0 && zd != 0)) ) )
				{
					//height = TileData.ItemTable[i.ItemID&TileData.MaxItemValue].Height;
					//Console.WriteLine( "LoS: Blocked by ITEM \"{0}\" P:{1} T:{2} F:x{3:X}", TileData.ItemTable[i.ItemID&TileData.MaxItemValue].Name, i.Location, i.Location.Z+height, flags );
					area.Free();
					return false;
				}*/
			}

			area.Free();

			return true;
		}
예제 #3
0
        public override void DoDamageBoat(BaseGalleon galleon)
        {
            if (galleon == null)
                return;

            m_HasPushed = false;
            IPoint2D pnt = galleon;

            if(Combatant != null && galleon.Contains(Combatant))
                pnt = Combatant;

            Direction dir = Utility.GetDirection(this, pnt);
            Point3DList path = new Point3DList();

            for (int i = 0; i < DamageRange; i++)
            {
                int x = 0, y = 0;
                switch ((int)dir)
                {
                    case (int)Direction.Running:
                    case (int)Direction.North: { y -= i; break; }
                    case 129:
                    case (int)Direction.Right: { y -= i; x += i; break; }
                    case 130:
                    case (int)Direction.East: { x += i; break; }
                    case 131:
                    case (int)Direction.Down: { x += i; y += i; break; }
                    case 132:
                    case (int)Direction.South: { y += i; break; }
                    case 133:
                    case (int)Direction.Left: { y += i; x -= i; break; }
                    case 134:
                    case (int)Direction.West: { x -= i; break; }
                    case (int)Direction.ValueMask:
                    case (int)Direction.Up: { x -= i; y -= i; break; }
                }

                path.Add(this.X + x, this.Y + y, this.Z);
            }

            new EffectsTimer(this, path, dir, DamageRange);
        }