]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/DShape.cpp
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / contrib / bobtoolz / DShape.cpp
1 /*
2    BobToolz plugin for GtkRadiant
3    Copyright (C) 2001 Gordon Biggans
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 // DShape.cpp: implementation of the DShape class.
21 //
22 //////////////////////////////////////////////////////////////////////
23
24 #include "StdAfx.h"
25 #include "DShape.h"
26
27 //#include "dialogs-gtk.h"
28
29 #include "misc.h"
30 #include "shapes.h"
31
32 //////////////////////////////////////////////////////////////////////
33 // Construction/Destruction
34 //////////////////////////////////////////////////////////////////////
35
36 bool bFacesAll[6] = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE};
37
38 DShape::DShape(){
39         m_nNextBrush = 0;
40 }
41
42 DShape::~DShape(){
43
44 }
45
46 void DShape::BuildRegularPrism( vec3_t min, vec3_t max, int nSides, bool bAlignTop ){
47         vec3_t vc[MAX_POLYGON_FACES + 2], vd[MAX_POLYGON_FACES + 2];
48
49         vec3_t radius;
50         vec3_t origin;
51
52         VectorSubtract( max, min, radius );
53         VectorScale( radius, 0.5f, radius );
54         // calc 3d radius and origin
55         VectorAdd( max, min, origin );
56         VectorScale( origin, 0.5f, origin );
57
58         float phase = 0.0f;
59
60         if ( bAlignTop ) {
61                 phase = -( Q_PI / nSides );
62                 VectorScale( radius, static_cast< float >( 1 / cos( phase ) ), radius );
63         }
64
65         //----- Build Polygon Vertices -----
66
67         int i;
68         for ( i = 0; i < nSides; i++ )
69         {
70                 VectorCopy( origin, vc[i] );
71                 VectorCopy( origin, vd[i] );
72
73                 vc[i][2] = min[2];
74                 vd[i][2] = max[2];
75
76                 vc[i][0] += radius[0] * sinf( ( 2 * Q_PI * i / nSides ) + phase );
77                 vc[i][1] += radius[1] * cosf( ( 2 * Q_PI * i / nSides ) + phase );
78
79                 vd[i][0] = vc[i][0];
80                 vd[i][1] = vc[i][1];
81         }
82
83         VectorCopy( vc[0], vc[nSides] );
84         VectorCopy( vd[0], vd[nSides] );
85         VectorCopy( vc[1], vc[nSides + 1] );
86         VectorCopy( vd[1], vd[nSides + 1] );
87
88         //----------------------------------
89
90         DBrush* pB = m_Container.GetWorldSpawn()->NewBrush( m_nNextBrush++ );
91
92         for ( i = 1; i <= nSides; i++ )
93                 pB->AddFace( vc[i - 1], vc[i], vd[i], GetCurrentTexture(), FALSE );
94
95         pB->AddFace( vc[2], vc[1], vc[0], "textures/common/caulk", FALSE );
96         pB->AddFace( vd[0], vd[1], vd[2], "textures/common/caulk", FALSE );
97 }
98
99 void DShape::Commit(){
100         m_Container.GetWorldSpawn()->FixBrushes( FALSE );
101         m_Container.BuildInRadiant( TRUE );
102 }
103
104 void DShape::BuildInversePrism( vec3_t min, vec3_t max, int nSides, bool bAlignTop ){
105         vec3_t va[MAX_POLYGON_FACES + 1], vb[MAX_POLYGON_FACES + 1];
106         vec3_t radius;
107         vec3_t origin;
108
109         VectorSubtract( max, min, radius );
110         VectorScale( radius, 0.5f, radius );
111         // calc 3d radius and origin
112         VectorAdd( max, min, origin );
113         VectorScale( origin, 0.5f, origin );
114
115         float phase = 0.0f;
116
117         if ( bAlignTop ) {
118                 phase = -( Q_PI / nSides );
119                 VectorScale( radius, static_cast< float >( 1 / cos( phase ) ), radius );
120         }
121
122         //----- Build Polygon Vertices -----
123
124         int i;
125         for ( i = 0; i < nSides; i++ )
126         {
127                 VectorCopy( origin, va[i] );
128                 VectorCopy( origin, vb[i] );
129
130                 va[i][2] = min[2];
131                 vb[i][2] = max[2];
132
133                 va[i][0] += radius[0] * sinf( ( 2 * Q_PI * i / nSides ) + phase );
134                 va[i][1] += radius[1] * cosf( ( 2 * Q_PI * i / nSides ) + phase );
135
136                 vb[i][0] = va[i][0];
137                 vb[i][1] = va[i][1];
138         }
139
140         VectorCopy( va[0], va[nSides] );
141         VectorCopy( vb[0], vb[nSides] );
142
143         //----------------------------------
144
145         for ( i = 1; i <= nSides; i++ )
146         {
147                 DBrush* pB = GetBoundingCube( min, max, "textures/common/caulk" );
148
149                 vec3_t top, bottom;
150                 VectorCopy( va[i - 1], top );
151                 VectorCopy( va[i], bottom );
152
153                 if ( va[i - 1][1] > va[i][1] ) {
154                         top[0] += 5;
155                         bottom[0] += 5;
156                 }
157                 else    // flip direction of plane on crossover
158                 {
159                         top[0] -= 5;
160                         bottom[0] -= 5;
161                 }
162
163                 if ( top[1] != bottom[1] ) { // internal line is flat already if true
164                         pB->AddFace( va[i - 1], top, vb[i - 1], "textures/common/caulk", FALSE );
165                         pB->AddFace( va[i], vb[i], bottom, "textures/common/caulk", FALSE );
166                 }   // add cut-off planes
167
168                 pB->AddFace( va[i - 1], vb[i - 1], vb[i], GetCurrentTexture(), FALSE );
169                 // add internal polygon plane
170         }
171 }
172
173 void DShape::BuildBorderedPrism( vec3_t min, vec3_t max, int nSides, int nBorder, bool bAlignTop ){
174         vec3_t va[MAX_POLYGON_FACES + 2], vb[MAX_POLYGON_FACES + 2];
175         vec3_t vc[MAX_POLYGON_FACES + 2], vd[MAX_POLYGON_FACES + 2];
176
177         vec3_t radius;
178         vec3_t origin;
179
180         VectorSubtract( max, min, radius );
181         VectorScale( radius, 0.5f, radius );
182         // calc 3d radius and origin
183         VectorAdd( max, min, origin );
184         VectorScale( origin, 0.5f, origin );
185
186         if ( nBorder >= Min( radius[0], radius[1] ) ) {
187 //              DoMessageBox("Border is too large", "Error", MB_OK);
188                 return;
189         }
190
191         float phase = 0.0f;
192
193         if ( bAlignTop ) {
194                 phase = -( Q_PI / nSides );
195                 VectorScale( radius, static_cast< float >( 1 / cos( phase ) ), radius );
196         }
197
198         //----- Build Polygon Vertices -----
199
200         int i;
201         for ( i = 0; i < nSides; i++ )
202         {
203                 VectorCopy( origin, va[i] );
204                 VectorCopy( origin, vb[i] );
205                 VectorCopy( origin, vc[i] );
206                 VectorCopy( origin, vd[i] );
207
208                 va[i][2] = min[2];
209                 vb[i][2] = max[2];
210
211                 va[i][0] += ( radius[0] - nBorder ) * sinf( ( 2 * Q_PI * i / nSides ) + phase );
212                 va[i][1] += ( radius[1] - nBorder ) * cosf( ( 2 * Q_PI * i / nSides ) + phase );
213
214                 vb[i][0] = va[i][0];
215                 vb[i][1] = va[i][1];
216
217
218
219                 vc[i][2] = min[2];
220                 vd[i][2] = max[2];
221
222                 vc[i][0] += radius[0] * sinf( ( 2 * Q_PI * i / nSides ) + phase );
223                 vc[i][1] += radius[1] * cosf( ( 2 * Q_PI * i / nSides ) + phase );
224
225                 vd[i][0] = vc[i][0];
226                 vd[i][1] = vc[i][1];
227         }
228
229         VectorCopy( va[0], va[nSides] );
230         VectorCopy( vb[0], vb[nSides] );
231         VectorCopy( va[1], va[nSides + 1] );
232         VectorCopy( vb[1], vb[nSides + 1] );
233
234         VectorCopy( vc[0], vc[nSides] );
235         VectorCopy( vd[0], vd[nSides] );
236         VectorCopy( vc[1], vc[nSides + 1] );
237         VectorCopy( vd[1], vd[nSides + 1] );
238
239         //----------------------------------
240
241         for ( i = 1; i <= nSides; i++ )
242         {
243                 DBrush* pB = GetBoundingCube( min, max, "textures/common/caulk" );
244
245                 pB->AddFace( origin, vc[i - 1], vd[i - 1], "textures/common/caulk", FALSE );
246                 pB->AddFace( origin, vd[i], vc[i], "textures/common/caulk", FALSE );
247
248                 pB->AddFace( vc[i - 1], vc[i], vd[i], GetCurrentTexture(), FALSE );
249                 pB->AddFace( vb[i], va[i], va[i - 1], GetCurrentTexture(), FALSE );
250         }
251 }
252
253 DBrush* DShape::GetBoundingCube_Ext( vec3_t min, vec3_t max, const char *textureName, bool* bUseFaces, bool detail ){
254         DBrush* pB = new DBrush;
255         //----- Build Outer Bounds ---------
256
257         vec3_t v1, v2, v3, v5, v6, v7;
258         VectorCopy( min, v1 );
259         VectorCopy( min, v2 );
260         VectorCopy( min, v3 );
261         VectorCopy( max, v5 );
262         VectorCopy( max, v6 );
263         VectorCopy( max, v7 );
264
265         v2[0] = max[0];
266         v3[1] = max[1];
267
268         v6[0] = min[0];
269         v7[1] = min[1];
270
271         //----------------------------------
272
273         //----- Add Six Cube Faces ---------
274
275         if ( bUseFaces[0] ) {
276                 pB->AddFace( v1, v2, v3, textureName, detail );
277         }
278         if ( bUseFaces[1] ) {
279                 pB->AddFace( v1, v3, v6, textureName, detail );
280         }
281         if ( bUseFaces[2] ) {
282                 pB->AddFace( v1, v7, v2, textureName, detail );
283         }
284
285         if ( bUseFaces[3] ) {
286                 pB->AddFace( v5, v6, v3, textureName, detail );
287         }
288         if ( bUseFaces[4] ) {
289                 pB->AddFace( v5, v2, v7, textureName, detail );
290         }
291         if ( bUseFaces[5] ) {
292                 pB->AddFace( v5, v7, v6, textureName, detail );
293         }
294
295         //----------------------------------
296
297         return pB;
298 }
299
300 DBrush* DShape::GetBoundingCube( vec3_t min, vec3_t max, const char *textureName, DEntity* ent, bool* bUseFaces ){
301         DBrush* pB;
302         if ( ent == NULL ) {
303                 pB = m_Container.GetWorldSpawn()->NewBrush( m_nNextBrush++ );
304         }
305         else{
306                 pB = ent->NewBrush( m_nNextBrush++ );
307         }
308
309         //----- Build Outer Bounds ---------
310
311         vec3_t v1, v2, v3, v5, v6, v7;
312         VectorCopy( min, v1 );
313         VectorCopy( min, v2 );
314         VectorCopy( min, v3 );
315         VectorCopy( max, v5 );
316         VectorCopy( max, v6 );
317         VectorCopy( max, v7 );
318
319         v2[0] = max[0];
320         v3[1] = max[1];
321
322         v6[0] = min[0];
323         v7[1] = min[1];
324
325         //----------------------------------
326
327         //----- Add Six Cube Faces ---------
328
329         if ( bUseFaces[0] ) {
330                 pB->AddFace( v1, v2, v3, textureName, FALSE );
331         }
332         if ( bUseFaces[1] ) {
333                 pB->AddFace( v1, v3, v6, textureName, FALSE );
334         }
335         if ( bUseFaces[2] ) {
336                 pB->AddFace( v1, v7, v2, textureName, FALSE );
337         }
338
339         if ( bUseFaces[3] ) {
340                 pB->AddFace( v5, v6, v3, textureName, FALSE );
341         }
342         if ( bUseFaces[4] ) {
343                 pB->AddFace( v5, v2, v7, textureName, FALSE );
344         }
345         if ( bUseFaces[5] ) {
346                 pB->AddFace( v5, v7, v6, textureName, FALSE );
347         }
348
349         //----------------------------------
350
351         return pB;
352 }
353
354 bool DShape::BuildPit( vec3_t min, vec3_t max ){
355         if ( ( max[2] - min[2] ) < 196 ) {
356                 return FALSE;
357         }
358
359         srand( time( NULL ) );
360
361         vec3_t centre;
362         VectorAdd( min, max, centre );
363         VectorScale( centre, 0.5f, centre );
364
365         char buffer[256];
366
367         int team = ( rand() % 10000 ) + 5000;
368
369 // ************* SPEAKER ***************
370         sprintf( buffer, "t%i_1", team );
371
372 // trigger for speaker
373         vec3_t triggerVoiceBtm;
374         VectorCopy( min, triggerVoiceBtm );
375         triggerVoiceBtm[2] = max[2] - 16;
376
377         DEntity* triggerVoice = m_Container.AddEntity( "trigger_multiple" );
378         GetBoundingCube( triggerVoiceBtm, max, "textures/common/trigger", triggerVoice );
379         triggerVoice->AddEPair( "target", buffer );
380 //--------------------
381
382 // target for speaker
383         vec3_t voiceOrigin;
384         VectorCopy( centre, voiceOrigin );
385         voiceOrigin[2] = max[2] + 16;
386
387
388         DEntity* targetVoice = m_Container.AddEntity( "target_speaker" );
389         targetVoice->AddEPair( "targetname", buffer );
390
391         sprintf( buffer, "%f %f %f", voiceOrigin[0], voiceOrigin[1], voiceOrigin[2] );
392         targetVoice->AddEPair( "origin", buffer );
393         targetVoice->AddEPair( "spawnflags", "8" );
394         targetVoice->AddEPair( "noise", "*falling1.wav" );
395 //--------------------
396
397 // *********** END SPEAKER *************
398
399 // ********* POWERUP REMOVAL ***********
400         sprintf( buffer, "t%i_2", team );
401
402 // trigger for powerup removal
403         vec3_t triggerPwrRmvTop, triggerPwrRmvBtm;
404         VectorCopy( min, triggerPwrRmvBtm );
405         VectorCopy( max, triggerPwrRmvTop );
406
407         triggerPwrRmvTop[2] = triggerVoiceBtm[2] - 64;
408         triggerPwrRmvBtm[2] = triggerPwrRmvTop[2] - 16;
409
410         DEntity* triggerPwrRmv = m_Container.AddEntity( "trigger_multiple" );
411         GetBoundingCube( triggerPwrRmvBtm, triggerPwrRmvTop, "textures/common/trigger", triggerPwrRmv );
412         triggerPwrRmv->AddEPair( "target", buffer );
413 //--------------------
414
415 // target for powerup removal
416         vec3_t pwrRmvOrigin;
417         VectorCopy( centre, pwrRmvOrigin );
418         pwrRmvOrigin[2] = triggerPwrRmvTop[2] + 16;
419
420         DEntity* targetPwrRmv = m_Container.AddEntity( "target_remove_powerups" );
421         targetPwrRmv->AddEPair( "targetname", buffer );
422
423         sprintf( buffer, "%f %f %f", pwrRmvOrigin[0], pwrRmvOrigin[1], pwrRmvOrigin[2] );
424         targetPwrRmv->AddEPair( "origin", buffer );
425 //--------------------
426
427 // ****** END POWERUP REMOVAL ********
428
429 // ********* DAMAGE ***********
430
431 // trigger for damage
432         vec3_t triggerDmgTop, triggerDmgBtm;
433         VectorCopy( min, triggerDmgBtm );
434         VectorCopy( max, triggerDmgTop );
435
436         triggerDmgBtm[2] = min[2] + 64;
437         triggerDmgTop[2] = triggerDmgBtm[2] + 16;
438
439         DEntity* triggerDmg = m_Container.AddEntity( "trigger_hurt" );
440         GetBoundingCube( triggerDmgBtm, triggerDmgTop, "textures/common/trigger", triggerDmg );
441         triggerDmg->AddEPair( "dmg", "9999" );
442         triggerDmg->AddEPair( "spawnflags", "12" );
443 //--------------------
444
445 // ****** END DAMAGE ********
446
447 // ********* NODROP ***********
448
449         vec3_t nodropTop;
450         VectorCopy( max, nodropTop );
451
452         nodropTop[2] = min[2] + 64;
453
454         GetBoundingCube( min, nodropTop, "textures/common/nodrop" );
455
456 // ****** END NODROP ********
457
458         return TRUE;
459 }