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); //} } }
/// <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; }