1 /*
2  *	s_split.cc
3  *	Split sectors
4  *	AYM 1998-02-03
5  */
6 
7 
8 /*
9 This file is part of Yadex.
10 
11 Yadex incorporates code from DEU 5.21 that was put in the public domain in
12 1994 by Rapha�l Quinet and Brendon Wyber.
13 
14 The rest of Yadex is Copyright � 1997-2003 Andr� Majorel and others.
15 
16 This program is free software; you can redistribute it and/or modify it under
17 the terms of the GNU General Public License as published by the Free Software
18 Foundation; either version 2 of the License, or (at your option) any later
19 version.
20 
21 This program is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
23 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
24 
25 You should have received a copy of the GNU General Public License along with
26 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
27 Place, Suite 330, Boston, MA 02111-1307, USA.
28 */
29 
30 
31 #include "yadex.h"
32 #include "dialog.h"
33 #include "levels.h"
34 #include "objects.h"
35 #include "objid.h"
36 #include "s_linedefs.h"
37 #include "selectn.h"
38 #include "x_hover.h"
39 
40 
41 /*
42    split a sector in two, adding a new linedef between the two vertices
43 */
44 
SplitSector(int vertex1,int vertex2)45 void SplitSector (int vertex1, int vertex2) /* SWAP! */
46 {
47 SelPtr llist;
48 int    curv, s, l, sd;
49 char   msg1[80], msg2[80];
50 
51 /* AYM 1998-08-09 : FIXME : I'm afraid this test is not relevant
52    if the sector contains subsectors. I should ask Jim (Flynn),
53    he did something about that in DETH. */
54 /* Check if there is a sector between the two vertices (in the middle) */
55 Objid o;
56 GetCurObject (o, OBJ_SECTORS,
57 	      (Vertices[vertex1].x + Vertices[vertex2].x) / 2,
58 	      (Vertices[vertex1].y + Vertices[vertex2].y) / 2);
59 s = o.num;
60 if (s < 0)
61    {
62    Beep ();
63    sprintf (msg1, "There is no sector between vertex #%d and vertex #%d",
64      vertex1, vertex2);
65    Notify (-1, -1, msg1, NULL);
66    return;
67    }
68 
69 /* Check if there is a closed path from <vertex1> to <vertex2>,
70    along the edge of sector <s>. To make it faster, I scan only
71    the set of linedefs that face sector <s>. */
72 ObjectsNeeded (OBJ_LINEDEFS, OBJ_SIDEDEFS, 0);
73 obj_no_t *ld_numbers;
74 int nlinedefs = linedefs_of_sector (s, ld_numbers);
75 if (nlinedefs < 1)  // Can't happen
76    {
77    nf_bug ("SplitSector: no linedef for sector %d\n", s);
78    return;
79    }
80 llist = NULL;
81 curv = vertex1;
82 while (curv != vertex2)
83    {
84    printf ("%d\n", curv);
85    int n;
86    for (n = 0; n < nlinedefs; n++)
87       {
88       if (IsSelected (llist, ld_numbers[n]))
89 	 continue;  // Already been there
90       const LDPtr ld = LineDefs + ld_numbers[n];
91       if (ld->start == curv
92 	  && is_sidedef (ld->sidedef1) && SideDefs[ld->sidedef1].sector == s)
93          {
94 	 curv = ld->end;
95 	 SelectObject (&llist, ld_numbers[n]);
96 	 break;
97          }
98       if (ld->end == curv
99 	  && is_sidedef (ld->sidedef2) && SideDefs[ld->sidedef2].sector == s)
100 	 {
101 	 curv = ld->start;
102 	 SelectObject (&llist, ld_numbers[n]);
103 	 break;
104          }
105       }
106    if (n >= nlinedefs)
107       {
108       Beep ();
109       sprintf (msg1, "Cannot find a closed path from vertex #%d to vertex #%d",
110         vertex1, vertex2);
111       if (curv == vertex1)
112 	 sprintf (msg2, "There is no sidedef starting from vertex #%d"
113 	   " on sector #%d", vertex1, s);
114       else
115 	 sprintf (msg2, "Check if sector #%d is closed"
116 	   " (cannot go past vertex #%d)", s, curv);
117       Notify (-1, -1, msg1, msg2);
118       ForgetSelection (&llist);
119       delete[] ld_numbers;
120       return;
121       }
122    if (curv == vertex1)
123       {
124       Beep ();
125       sprintf (msg1, "Vertex #%d is not on the same sector (#%d)"
126         " as vertex #%d", vertex2, s, vertex1);
127       Notify (-1, -1, msg1, NULL);
128       ForgetSelection (&llist);
129       delete[] ld_numbers;
130       return;
131       }
132    }
133 delete[] ld_numbers;
134 /* now, the list of linedefs for the new sector is in llist */
135 
136 /* add the new sector, linedef and sidedefs */
137 InsertObject (OBJ_SECTORS, s, 0, 0);
138 InsertObject (OBJ_LINEDEFS, -1, 0, 0);
139 LineDefs[NumLineDefs - 1].start = vertex1;
140 LineDefs[NumLineDefs - 1].end = vertex2;
141 LineDefs[NumLineDefs - 1].flags = 4;
142 InsertObject (OBJ_SIDEDEFS, -1, 0, 0);
143 SideDefs[NumSideDefs - 1].sector = s;
144 strncpy (SideDefs[NumSideDefs - 1].tex3, "-", WAD_TEX_NAME);
145 InsertObject (OBJ_SIDEDEFS, -1, 0, 0);
146 strncpy (SideDefs[NumSideDefs - 1].tex3, "-", WAD_TEX_NAME);
147 ObjectsNeeded (OBJ_LINEDEFS, OBJ_SIDEDEFS, 0);
148 LineDefs[NumLineDefs - 1].sidedef1 = NumSideDefs - 2;
149 LineDefs[NumLineDefs - 1].sidedef2 = NumSideDefs - 1;
150 
151 /* bind all linedefs in llist to the new sector */
152 while (llist)
153 {
154    sd = LineDefs[llist->objnum].sidedef1;
155    if (sd < 0 || SideDefs[sd].sector != s)
156       sd = LineDefs[llist->objnum].sidedef2;
157    SideDefs[sd].sector = NumSectors - 1;
158    UnSelectObject (&llist, llist->objnum);
159 }
160 
161 /* second check... useful for sectors within sectors */
162 ObjectsNeeded (OBJ_LINEDEFS, OBJ_SIDEDEFS, 0);
163 for (l = 0; l < NumLineDefs; l++)
164 {
165    sd = LineDefs[l].sidedef1;
166    if (sd >= 0 && SideDefs[sd].sector == s)
167    {
168       curv = GetOppositeSector (l, 1);
169       ObjectsNeeded (OBJ_LINEDEFS, OBJ_SIDEDEFS, 0);
170       if (curv == NumSectors - 1)
171 	 SideDefs[sd].sector = NumSectors - 1;
172    }
173    sd = LineDefs[l].sidedef2;
174    if (sd >= 0 && SideDefs[sd].sector == s)
175    {
176       curv = GetOppositeSector (l, 0);
177       ObjectsNeeded (OBJ_LINEDEFS, OBJ_SIDEDEFS, 0);
178       if (curv == NumSectors - 1)
179 	 SideDefs[sd].sector = NumSectors - 1;
180    }
181 }
182 
183 MadeChanges = 1;
184 MadeMapChanges = 1;
185 }
186 
187 
188 
189 /*
190    split two linedefs, then split the sector and add a new linedef between the new vertices
191 */
192 
SplitLineDefsAndSector(int linedef1,int linedef2)193 void SplitLineDefsAndSector (int linedef1, int linedef2) /* SWAP! */
194 {
195 SelPtr llist;
196 int    s1, s2, s3, s4;
197 char   msg[80];
198 
199 /* check if the two linedefs are adjacent to the same sector */
200 ObjectsNeeded (OBJ_LINEDEFS, 0);
201 s1 = LineDefs[linedef1].sidedef1;
202 s2 = LineDefs[linedef1].sidedef2;
203 s3 = LineDefs[linedef2].sidedef1;
204 s4 = LineDefs[linedef2].sidedef2;
205 ObjectsNeeded (OBJ_SIDEDEFS, 0);
206 if (s1 >= 0)
207    s1 = SideDefs[s1].sector;
208 if (s2 >= 0)
209    s2 = SideDefs[s2].sector;
210 if (s3 >= 0)
211    s3 = SideDefs[s3].sector;
212 if (s4 >= 0)
213    s4 = SideDefs[s4].sector;
214 if ((s1 < 0 || (s1 != s3 && s1 != s4)) && (s2 < 0 || (s2 != s3 && s2 != s4)))
215 {
216    Beep ();
217    sprintf (msg, "Linedefs #%d and #%d are not adjacent to the same sector",
218      linedef1, linedef2);
219    Notify (-1, -1, msg, NULL);
220    return;
221 }
222 /* split the two linedefs and create two new vertices */
223 llist = NULL;
224 SelectObject (&llist, linedef1);
225 SelectObject (&llist, linedef2);
226 SplitLineDefs (llist);
227 ForgetSelection (&llist);
228 /* split the sector and create a linedef between the two vertices */
229 SplitSector (NumVertices - 1, NumVertices - 2);
230 }
231 
232 
233 
234