1 /*
2 * Portions of this file are copyright Rebirth contributors and licensed as
3 * described in COPYING.txt.
4 * Portions of this file are copyright Parallax Software and licensed
5 * according to the Parallax license below.
6 * See COPYING.txt for license details.
7
8 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
10 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
16 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
18 */
19
20 /*
21 *
22 * Functions for building parts of mines.
23 *
24 */
25
26 #include <string.h>
27 #include "editor/editor.h"
28 #include "editor/esegment.h"
29 #include "gamesave.h"
30 #include "kdefs.h"
31 #include "compiler-range_for.h"
32
33 // ---------- Create a bridge segment between current segment/side and marked segment/side ----------
CreateBridge()34 int CreateBridge()
35 {
36 if (!Markedsegp) {
37 editor_status("No marked side.");
38 return 0;
39 }
40
41 if (!med_form_bridge_segment(Cursegp,Curside,Markedsegp,Markedside)) {
42 Update_flags |= UF_WORLD_CHANGED;
43 mine_changed = 1;
44 autosave_mine(mine_filename);
45 diagnostic_message("Bridge segment formed.");
46 undo_status[Autosave_count] = "Bridge segment UNDONE.";
47 warn_if_concave_segments();
48 }
49 return 1;
50 }
51
52
53
54 // ---------- Form a joint between current segment:side and marked segment:side, modifying marked segment ----------
FormJoint()55 int FormJoint()
56 {
57 if (!Markedsegp)
58 diagnostic_message("Marked segment not set -- unable to form joint.");
59 else {
60 if (!med_form_joint(Cursegp,Curside,Markedsegp,Markedside)) {
61 Update_flags |= UF_WORLD_CHANGED;
62 mine_changed = 1;
63 autosave_mine(mine_filename);
64 diagnostic_message("Joint formed.");
65 undo_status[Autosave_count] = "Joint undone.";
66 warn_if_concave_segments();
67 }
68 }
69
70 return 1;
71
72 }
73
74 // ---------- Create a bridge segment between current segment:side adjacent segment:side ----------
CreateAdjacentJoint()75 int CreateAdjacentJoint()
76 {
77 int adj_side;
78 imsegptridx_t adj_sp = segment_none;
79
80 if (med_find_adjacent_segment_side(Cursegp, Curside, adj_sp, &adj_side)) {
81 if (Cursegp->children[Curside] != adj_sp) {
82 med_form_joint(Cursegp,Curside,adj_sp,adj_side);
83 Update_flags |= UF_WORLD_CHANGED;
84 mine_changed = 1;
85 autosave_mine(mine_filename);
86 diagnostic_message("Joint segment formed.");
87 undo_status[Autosave_count] = "Joint segment undone.";
88 warn_if_concave_segments();
89 } else
90 editor_status("Attempted to form joint through connected side -- joint segment not formed (you bozo).");
91 } else
92 editor_status("Could not find adjacent segment -- joint segment not formed.");
93
94 return 1;
95 }
96
97 // ---------- Create a bridge segment between current segment:side adjacent segment:side ----------
CreateSloppyAdjacentJoint()98 int CreateSloppyAdjacentJoint()
99 {
100 int adj_side;
101 imsegptridx_t adj_sp = segment_none;
102
103 save_level(
104 #if defined(DXX_BUILD_DESCENT_II)
105 LevelSharedSegmentState.DestructibleLights,
106 #endif
107 "SLOPPY.LVL");
108
109 if (med_find_closest_threshold_segment_side(Cursegp, Curside, adj_sp, &adj_side, 20*F1_0)) {
110 if (Cursegp->children[Curside] != adj_sp) {
111 if (!med_form_joint(Cursegp,Curside,adj_sp,adj_side))
112 {
113 Update_flags |= UF_WORLD_CHANGED;
114 mine_changed = 1;
115 autosave_mine(mine_filename);
116 diagnostic_message("Sloppy Joint segment formed.");
117 undo_status[Autosave_count] = "Sloppy Joint segment undone.";
118 warn_if_concave_segments();
119 }
120 else editor_status("Could not form sloppy joint.\n");
121 } else
122 editor_status("Attempted to form sloppy joint through connected side -- joint segment not formed.");
123 } else
124 editor_status("Could not find close threshold segment -- joint segment not formed.");
125
126 return 1;
127 }
128
129
130 // -------------- Create all sloppy joints within CurrentGroup ------------------
CreateSloppyAdjacentJointsGroup()131 int CreateSloppyAdjacentJointsGroup()
132 {
133 int adj_side;
134 int done_been_a_change = 0;
135 range_for(const auto &gs, GroupList[current_group].segments)
136 {
137 auto segp = vmsegptridx(gs);
138
139 for (int sidenum=0; sidenum < MAX_SIDES_PER_SEGMENT; sidenum++)
140 if (!IS_CHILD(segp->children[sidenum]))
141 {
142 imsegptridx_t adj_sp = segment_none;
143 if (med_find_closest_threshold_segment_side(segp, sidenum, adj_sp, &adj_side, 5*F1_0)) {
144 if (adj_sp->group == segp->group) {
145 if (segp->children[sidenum] != adj_sp)
146 if (!med_form_joint(segp, sidenum, adj_sp,adj_side))
147 done_been_a_change = 1;
148 }
149 }
150 }
151 }
152
153 if (done_been_a_change) {
154 Update_flags |= UF_WORLD_CHANGED;
155 mine_changed = 1;
156 autosave_mine(mine_filename);
157 diagnostic_message("Sloppy Joint segment formed.");
158 undo_status[Autosave_count] = "Sloppy Joint segment undone.";
159 warn_if_concave_segments();
160 }
161
162 return 1;
163 }
164
165
166 // ---------- Create a bridge segment between current segment and all adjacent segment:side ----------
CreateAdjacentJointsSegment()167 int CreateAdjacentJointsSegment()
168 {
169 auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
170 int adj_side;
171
172 auto &Vertex_active = LevelSharedVertexState.get_vertex_active();
173 med_combine_duplicate_vertices(Vertex_active);
174
175 for (int s=0; s<MAX_SIDES_PER_SEGMENT; s++) {
176 imsegptridx_t adj_sp = segment_none;
177 if (med_find_adjacent_segment_side(Cursegp, s, adj_sp, &adj_side))
178 if (Cursegp->children[s] != adj_sp)
179 {
180 med_form_joint(Cursegp,s,adj_sp,adj_side);
181 Update_flags |= UF_WORLD_CHANGED;
182 mine_changed = 1;
183 autosave_mine(mine_filename);
184 diagnostic_message("Adjacent Joint segment formed.");
185 undo_status[Autosave_count] = "Adjacent Joint segment UNDONE.";
186 warn_if_concave_segments();
187 }
188 }
189
190 return 1;
191 }
192
193 // ---------- Create a bridge segment between all segment:side and all adjacent segment:side ----------
CreateAdjacentJointsAll()194 int CreateAdjacentJointsAll()
195 {
196 auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
197 int adj_side;
198
199 auto &Vertex_active = LevelSharedVertexState.get_vertex_active();
200 med_combine_duplicate_vertices(Vertex_active);
201
202 range_for (const auto &&segp, vmsegptridx)
203 {
204 for (int s=0; s<MAX_SIDES_PER_SEGMENT; s++)
205 {
206 imsegptridx_t adj_sp = segment_none;
207 if (med_find_adjacent_segment_side(segp, s, adj_sp, &adj_side))
208 if (segp->children[s] != adj_sp)
209 med_form_joint(segp,s,adj_sp,adj_side);
210 }
211 }
212
213 Update_flags |= UF_WORLD_CHANGED;
214 mine_changed = 1;
215 autosave_mine(mine_filename);
216 diagnostic_message("All Adjacent Joint segments formed.");
217 undo_status[Autosave_count] = "All Adjacent Joint segments UNDONE.";
218 warn_if_concave_segments();
219 return 1;
220 }
221
222
223