Exemplo n.º 1
0
    public static void CreateStair(StairInfo Stair)
    {
        MapGrid UpStair   = GetMG(Stair.Up);
        MapGrid DownStair = GetMG(Stair.Down);

        if (UpStair != null && DownStair != null)
        {
            MapStair stair = new MapStair();
            stair.Init();
            stair.SetStair(Stair.Up, Stair.Down);

            if (UpStair.Type == GridType.GRID_HOLE)
            {
                UpStair.Type = GridType.GRID_HOLESTAIR;
            }
            else
            {
                UpStair.Type = GridType.GRID_STAIR;
            }
            if (DownStair.Type == GridType.GRID_HOLE)
            {
                DownStair.Type = GridType.GRID_HOLESTAIR;
            }
            else
            {
                DownStair.Type = GridType.GRID_STAIR;
            }
            UpStair.Down = DownStair;
            DownStair.Up = UpStair;
            MapStair.AddStair(stair);
            SetNNearestUpPort(DownStair, UpStair);
            SetNNearestDownPort(UpStair, DownStair, false);
            //这个需要调整。
            //MapGrid m = GetMG(Stair.Down.Layer,Stair.Up.Unit);
            //if(m != null)
            //{
            //	DownStair.UpHaveHole = true;
            //}

            //foreach(Int2 HolePos in Stair.m_NearHole )
            //{
            //	CreateHole(HolePos);
            //}
        }
    }
Exemplo n.º 2
0
    /// <summary>
    /// 获取防守方楼梯 pos 指楼梯下节点数据
    /// </summary>
    public static void GetStairInfo(ref List <StairInfo> lStair)
    {
        if (lStair == null)
        {
            lStair = new List <StairInfo>();
        }
        lStair.Clear();

        foreach (BuildInfo stairBuild in m_DefenseBuild.Values)
        {
            if (stairBuild == null)
            {
                continue;
            }

            if (stairBuild.m_RoomType != RoomType.Stair)
            {
                continue;
            }

            StairInfo stair = new StairInfo(new Int2(stairBuild.m_cx, stairBuild.m_cy));
            lStair.Add(stair);
        }
    }
		private List<StairInfo> CreateStraightStairSectorsFromLines(List<Linedef> selectedlinedefs)
		{
            List<StairInfo> stairinfo = new List<StairInfo>();
			uint numsteps = stairsectorbuilderform.NumberOfSectors;
			uint depth = stairsectorbuilderform.SectorDepth;
            int spacing = stairsectorbuilderform.Spacing;
			List<Linedef> sourceld = new List<Linedef>(selectedlinedefs);
            StairInfo si = new StairInfo();

			GetConnectedLines(ref selectedlinedefs, -1);

            // Build an independend set of steps from each selected line
			if (!stairsectorbuilderform.SingleSectors.Checked)
			{
				Vector2D direction = new Vector2D();
				Vector2D v1, v2;

                // Go through each selected line
				for (int k = 0; k < sourceld.Count; k++)
				{
                    List<List<Vector2D>> sisecs = new List<List<Vector2D>>();

                    // Get the direction to build the stair to. "Flip" the vector depending on the selected build direction modifier
                    direction = sourceld[k].Line.GetPerpendicular().GetNormal() * (stairsectorbuilderform.SideFront ? -1 : 1);

					for (int i = 0; i < numsteps; i++)
					{
						List<DrawnVertex> vertices = new List<DrawnVertex>();
						Vector2D v3, v4;
						List<Vector2D> newsec = new List<Vector2D>();

                        // Compute the position of the vertices that form the line opposite the source line
                        v1 = sourceld[k].Start.Position + direction * depth * i;
                        v2 = sourceld[k].End.Position + direction * depth * i;
						v3 = v1 + direction * depth;
                        v4 = v2 + direction * depth;

                        // Apply spacing to each vertex
                        if (spacing > 0)
                        {
                            v1 += (direction * spacing) * i;
                            v2 += (direction * spacing) * i;
                            v3 += (direction * spacing) * i;
                            v4 += (direction * spacing) * i;

                        }

                        // v1 is added twice so it will actually draw a complete sector
						newsec.Add(v1);
						newsec.Add(v3);
						newsec.Add(v4);
						newsec.Add(v2);
						newsec.Add(v1);

						sisecs.Add(newsec);
					}

					GetSetTextureAndHeightInfo(sourceld[k], out si);

                    si.sectors = sisecs;

                    stairinfo.Add(si);
				}
			}
			else if(stairsectorbuilderform.SingleSectors.Checked)
			{
				Vector2D direction = new Vector2D();
				Vector2D globaldirection = new Vector2D();
				
				foreach (ConnectedLinedefs cld in connectedlinedefs)
				{
					List<Vector2D> connectedvertices = new List<Vector2D>();
					List<Vector2D> connecteddirections = new List<Vector2D>();
					List<Vector2D> blacklist = new List<Vector2D>();
					List<double> connectedlength = new List<double>();
                    List<List<Vector2D>> sisecs = new List<List<Vector2D>>();
					bool closed = false;

					globaldirection = Vector2D.FromAngle(cld.firstlinedef.Angle + Angle2D.DegToRad(stairsectorbuilderform.SideFront ? -90.0f : 90.0f));

					if (cld.sector >= 0)
					{
						closed = true;
					}
					else if (cld.linedefs.Count > 2) // to be closed there have to be at least 3 lines
					{
						// if (connectedvertices[0] == cld.firstlinedef.End.Position && connectedvertices[connectedvertices.Count - 1] == cld.firstlinedef.Start.Position)
						if (cld.linedefs[0].Start.Position == cld.linedefs[cld.linedefs.Count - 1].End.Position)
						{
							closed = true;

							/*
							if (stairsectorbuilderform.RemoveRedundantVertices.Checked == true && cld.linedefs[0].Angle == cld.linedefs[cld.linedefs.Count - 1].Angle)
							{
								connectedvertices.RemoveAt(connectedvertices.Count - 2);
							}
							*/
						}
					}

					for(int i=0; i < cld.linedefs.Count; i++)
					{
						if (cld.sector >= 0)
						{
							if (cld.linedefs[i].Front.Sector.Index == cld.sector)
							{
								if (!connectedvertices.Contains(cld.linedefs[i].End.Position) && !blacklist.Contains(cld.linedefs[i].End.Position))
									connectedvertices.Add(cld.linedefs[i].End.Position);

								if (!connectedvertices.Contains(cld.linedefs[i].Start.Position) && !blacklist.Contains(cld.linedefs[i].Start.Position))
									connectedvertices.Add(cld.linedefs[i].Start.Position);

							}
							else
							{
								if (!connectedvertices.Contains(cld.linedefs[i].Start.Position))
									connectedvertices.Add(cld.linedefs[i].Start.Position);

								if (!connectedvertices.Contains(cld.linedefs[i].End.Position))
									connectedvertices.Add(cld.linedefs[i].End.Position);
							}
						}
						else
						{
							if (!connectedvertices.Contains(cld.linedefs[i].Start.Position) && !blacklist.Contains(cld.linedefs[i].Start.Position))
								connectedvertices.Add(cld.linedefs[i].Start.Position);

							if (!connectedvertices.Contains(cld.linedefs[i].End.Position) && !blacklist.Contains(cld.linedefs[i].End.Position))
								connectedvertices.Add(cld.linedefs[i].End.Position);

							
							if (stairsectorbuilderform.RemoveRedundantVertices.Checked == true)
							{
								if (i == 0)
								{
									if (closed == true && cld.linedefs[0].Angle == cld.linedefs[cld.linedefs.Count - 1].Angle)
									{
										connectedvertices.Remove(cld.linedefs[0].Start.Position);
										blacklist.Add(cld.linedefs[0].Start.Position);
									}
								}
								else if(i > 0)
								{
									if (cld.linedefs[i].Angle == cld.linedefs[i - 1].Angle)
									{
										connectedvertices.Remove(cld.linedefs[i].Start.Position);
										blacklist.Add(cld.linedefs[i].Start.Position);
									}
								}
							}
						}
					}

					// CLOSE CHECK WAS HERE
				
					for (int i = 0; i < connectedvertices.Count; i++)
					{
						if (i == 0 && closed == false)
						{
							connecteddirections.Add(Vector2D.FromAngle(Vector2D.GetAngle(connectedvertices[0], connectedvertices[1]) - Angle2D.DegToRad(stairsectorbuilderform.SideFront ? -90.0f : 90.0f)));
							connectedlength.Add(depth);
						}
						else if (i == connectedvertices.Count - 1 && closed == false)
						{
							connecteddirections.Add(Vector2D.FromAngle(Vector2D.GetAngle(connectedvertices[i], connectedvertices[i - 1]) + Angle2D.DegToRad(stairsectorbuilderform.SideFront ? -90.0f : 90.0f)));
							connectedlength.Add(depth);
						}
						else
						{
							Vector2D v1;
							Vector2D v2;

							if (closed == true && i == 0)
							{
								v1 = new Line2D(connectedvertices[1], connectedvertices[0]).GetPerpendicular();
								v2 = new Line2D(connectedvertices[0], connectedvertices[connectedvertices.Count - 1]).GetPerpendicular();
							}
							else if(closed == true && i == connectedvertices.Count - 1)
							{
								v1 = new Line2D(connectedvertices[0], connectedvertices[i]).GetPerpendicular();
								v2 = new Line2D(connectedvertices[i], connectedvertices[i - 1]).GetPerpendicular();
							}
							else
							{
								v1 = new Line2D(connectedvertices[i + 1], connectedvertices[i]).GetPerpendicular();
								v2 = new Line2D(connectedvertices[i], connectedvertices[i - 1]).GetPerpendicular();
							}

							double a = (v1.GetNormal() + v2.GetNormal()).GetAngle();
							double b = a - v1.GetNormal().GetAngle();

							double opl = Math.Tan(b) * (double)depth;
							double distance = Math.Sqrt(depth * depth + opl * opl);
							Vector2D v3 = Vector2D.FromAngle((float)a);

							connecteddirections.Add(Vector2D.FromAngle(v3.GetAngle() + Angle2D.DegToRad(stairsectorbuilderform.SideFront ? 0.0f : 180.0f)));
							connectedlength.Add(distance);
						}
					}

					for (int i = 0; i < numsteps; i++)
					{
						List<Vector2D> newsec = new List<Vector2D>();
						float length;

						if (closed == false)
						{
							for (int k = 0; k < connectedvertices.Count; k++)
							{
								if (!stairsectorbuilderform.SingleDirection.Checked)
								{
									direction = connecteddirections[k];
									length = (float)connectedlength[k];
								}
								else
								{
									direction = globaldirection;
									length = depth;
								}

                                newsec.Add(connectedvertices[k] + direction * length * i + (direction * spacing) * i);
							}
						}

						for (int k = connectedvertices.Count - 1; k >= 0; k--)
						{
							if (!stairsectorbuilderform.SingleDirection.Checked)
							{
								direction = connecteddirections[k];
								length = (float)connectedlength[k];
							}
							else
							{
								direction = globaldirection;
								length = depth;
							}

                            newsec.Add(connectedvertices[k] + direction * length * (i + 1) + (direction * spacing) * i);
						}

						if(closed == false)
                            newsec.Add(connectedvertices[0] + direction * depth * i + (direction * spacing) * i);
						else
							newsec.Add(newsec[0]);

						// If the steps are drawn on the back side the vertices are in counter-clockwise
						// order, so reverse their order
						if (!stairsectorbuilderform.SideFront) newsec.Reverse();

						sisecs.Add(newsec);
					}

					GetSetTextureAndHeightInfo(cld.firstlinedef, out si);

                    si.sectors = sisecs;

                    stairinfo.Add(si);
				}
			}

			stairsectorbuilderform.StepMultiplier = 1;

			return stairinfo;
		}
		// Creates stair sectors from two Catmull Rom splines
        private List<StairInfo> CreateCatmullRomStairSectors()
		{
			List<List<Vector2D>> secs = new List<List<Vector2D>>();
			List<Vector2D> newsec;
			List<Vector2D> innervertices, outervertices;
			int innervertexmultiplier = stairsectorbuilderform.InnerVertexMultiplier;
			int outervertexmultiplier = stairsectorbuilderform.OuterVertexMultiplier;
			int numsteps = (int)stairsectorbuilderform.NumberOfSectors;
			List<List<Vector2D>> sisecs = new List<List<Vector2D>>();

            List<StairInfo> stairinfo = new List<StairInfo>();
            StairInfo si = new StairInfo();

			secs.Clear();

			foreach(CatmullRomSplineGroup crsg in catmullromsplinegroups)
			{
				// Generate the vertices for both the inner and outer spline
				innervertices = GenerateCatmullRom(crsg.splines[INNER_SPLINE], numsteps * innervertexmultiplier);
				outervertices = GenerateCatmullRom(crsg.splines[OUTER_SPLINE], numsteps * outervertexmultiplier);

				// Create the data to build complete sectors from the splines
				for (int i = 0; i < numsteps; i++)
				{
					newsec = new List<Vector2D>();

					// Depending on the outer and innter vertex multipliers more
					// vertices from the splines have to be added to the new sector
					for (int k = 0; k <= outervertexmultiplier; k++)
					{
						newsec.Add(outervertices[i * outervertexmultiplier + k]);
					}

					for (int k = 0; k <= innervertexmultiplier; k++)
					{
						newsec.Add(innervertices[(numsteps - 1 - i) * innervertexmultiplier + k]);
					}

					// Don't forget the add the first vertex again, to actually have
					// a whole sector
					newsec.Add(outervertices[i * outervertexmultiplier]);

					sisecs.Add(newsec);
				}
			}

			GetSetTextureAndHeightInfo(catmullromsplinegroups[0].sourcelinedef, out si);

			si.sectors = sisecs;

			stairinfo.Add(si);

			return stairinfo;
		}
		// Creates sectors for a curved stair
        private List<StairInfo> CreateCurvedStairSectors()
		{
			List<List<Vector2D>> secs = new List<List<Vector2D>>();
			List<Vector2D> newsec;
			List<DrawnVertex> dvl = new List<DrawnVertex>();
			List<Vector2D> innervertices, outervertices;
			Line2D innerline, outerline;
			float innerangle, outerangle;
			int innervertexmultiplier = stairsectorbuilderform.InnerVertexMultiplier;
			int outervertexmultiplier = stairsectorbuilderform.OuterVertexMultiplier;
			bool clockwise;
			int numsteps = (int)stairsectorbuilderform.NumberOfSectors;
			uint depth = stairsectorbuilderform.SectorDepth;
			List<Linedef> sourceld = new List<Linedef>();
            List<StairInfo> stairinfo = new List<StairInfo>();
            StairInfo si = new StairInfo();
            List<List<Vector2D>> sisecs = new List<List<Vector2D>>();

			secs.Clear();

			if (General.Map.Map.GetSelectedLinedefs(true).Count <= 0)
			{
				return null;
			}

			// Add all selected linedefs to a source linedef list
			foreach (Linedef ld in General.Map.Map.GetSelectedLinedefs(true))
			{
				sourceld.Add(ld);
			}

			// Go through all source linedefs
			for (int l1 = 0; l1 < sourceld.Count - 1; l1++)
			{
				// A curve will always be made in the order the lines were selected
				int l2 = l1 + 1;
				Vector2D s1, s2, e1, e2;
				float distance = 128;
				bool fixedcurve = true;

				s1 = stairsectorbuilderform.Flipping == 1 ? sourceld[l1].End.Position : sourceld[l1].Start.Position;
				e1 = stairsectorbuilderform.Flipping == 1 ? sourceld[l1].Start.Position : sourceld[l1].End.Position;
				s2 = stairsectorbuilderform.Flipping == 2 ? sourceld[l2].End.Position : sourceld[l2].Start.Position;
				e2 = stairsectorbuilderform.Flipping == 2 ? sourceld[l2].Start.Position : sourceld[l2].End.Position;

				if (Vector2D.Distance(s1, s2) < Vector2D.Distance(e1, e2))
				{
					clockwise = true;
					innerline = new Line2D(s2, s1);
					outerline = new Line2D(e1, e2);
				}
				else // Counter clockwise
				{
					clockwise = false;
					innerline = new Line2D(e1, e2);
					outerline = new Line2D(s2, s1);
				}

				// Compute the angle of the inner and outer line
				if (sourceld[l1].Angle == sourceld[l2].Angle && !(stairsectorbuilderform.Flipping == 1) && !(stairsectorbuilderform.Flipping == 2))
				{
					innerangle = 1;
					outerangle = 1;
					distance = 0;
					fixedcurve = false;
				}
				else
				{
					if (clockwise)
					{
						innerangle = outerangle = sourceld[l1].Angle - sourceld[l2].Angle;
						if (innerangle < 0.0f) innerangle += Angle2D.PI2;
						if (outerangle < 0.0f) outerangle += Angle2D.PI2;
					}
					else
					{
						innerangle = outerangle = sourceld[l2].Angle - sourceld[l1].Angle;
						if (innerangle < 0.0f) innerangle += Angle2D.PI2;
						if (outerangle < 0.0f) outerangle += Angle2D.PI2;
					}

					if (stairsectorbuilderform.Flipping != 0)
					{
						if (sourceld[l1].Angle == sourceld[l2].Angle)
						{
							if (stairsectorbuilderform.Flipping == 1)
							{
								innerangle = Math.Abs(innerangle - Angle2D.PI);
								outerangle = Math.Abs(outerangle - Angle2D.PI);
							}
							else if (stairsectorbuilderform.Flipping == 2)
							{
								innerangle -= Angle2D.PI;
								outerangle -= Angle2D.PI;
							}
						}
						else
						{
							innerangle = Math.Abs(innerangle - Angle2D.PI2);
							outerangle = Math.Abs(outerangle - Angle2D.PI2);
						}
					}
				}

				// Generate the vertices on the curve, and add the start and end vertices of the inner line to the list
				innervertices = GenerateCurve(innerline, numsteps * innervertexmultiplier - 1, innerangle, false, distance, fixedcurve);
				innervertices.Insert(0, innerline.v1);
				innervertices.Add(innerline.v2);

				// Generate the vertices on the curve, and add the start and end vertices of the outer line to the list
				outervertices = GenerateCurve(outerline, numsteps * outervertexmultiplier - 1, outerangle, true, distance, fixedcurve);
				outervertices.Insert(0, outerline.v1);
				outervertices.Add(outerline.v2);

                // If the vertices were created in counter-clockwise order turn them into clockwise order
                if (!clockwise)
                {
                    List<Vector2D> tmpvertices;
                    int tmpmultiplier;

                    tmpvertices = innervertices;
                    tmpmultiplier = innervertexmultiplier;

                    innervertices = outervertices;
                    outervertices = tmpvertices;

                    innervertexmultiplier = outervertexmultiplier;
                    outervertexmultiplier = tmpmultiplier;
                }

				// Create the sectors from the created vertices
			    for (int i = 0; i < numsteps; i++)
			    {
					newsec = new List<Vector2D>();

					// Depending on the outer and innter vertex multipliers more
					// vertices from the curve have to be added to the new sector
                    for (int k = 0; k <= outervertexmultiplier; k++)
                    {
                        newsec.Add(outervertices[i * outervertexmultiplier + k]);
                    }

					// Depending on the outer and innter vertex multipliers more
					// vertices from the curve have to be added to the new sector
                    for (int k = 0; k <= innervertexmultiplier; k++)
                    {
                        newsec.Add(innervertices[(numsteps - 1 - i) * innervertexmultiplier + k]);
                    }

					// Don't forget the add the first vertex again, to actually have
					// a whole sector
                    newsec.Add(outervertices[i * outervertexmultiplier]);

					sisecs.Add(newsec);
			    }
			}

			GetSetTextureAndHeightInfo(sourceld[0], out si);

            si.sectors = sisecs;

            stairinfo.Add(si);

			stairsectorbuilderform.StepMultiplier = sourceld.Count - 1;

			return stairinfo;
		}
		// Remember info for floor and ceiling height. The info is retrieved
		// from either front or back of the source line, depending in what
		// direction the it should build
		// Also set the upper/lower textures to use if they aren't already
		private void GetSetTextureAndHeightInfo(Linedef ld, out StairInfo siout)
		{
			StairInfo si = new StairInfo();
			Sidedef primary;
			Sidedef secondary;

			GetSetBaseHeights(ld);

			if (stairsectorbuilderform.SideFront)
			{
				if (ld.Front == null)
				{
					primary = ld.Back;
					secondary = ld.Front;
				}
				else
				{
					primary = ld.Front;
					secondary = ld.Back;
				}
			}
			else
			{
				if (ld.Back == null)
				{
					primary = ld.Front;
					secondary = ld.Back;
				}
				else
				{
					primary = ld.Back;
					secondary = ld.Front;
				}
			}

			si.ceilingheight = (primary != null) ? primary.Sector.CeilHeight : 128;
			si.floorheight = (primary != null) ? primary.Sector.FloorHeight : 0;

			if (stairsectorbuilderform.UpperTextureTexture == "")
				stairsectorbuilderform.UpperTextureTexture = (primary == null) ? General.Settings.DefaultTexture : ((secondary == null) ? primary.MiddleTexture : primary.HighTexture);

			if (stairsectorbuilderform.LowerTextureTexture == "")
				stairsectorbuilderform.LowerTextureTexture = (primary == null) ? General.Settings.DefaultTexture : ((secondary == null) ? primary.MiddleTexture : primary.LowTexture);

			siout = si;
		}