]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/brushscript.cpp
fix unzip code
[xonotic/netradiant.git] / radiant / brushscript.cpp
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 // BrushScript stuff
23 //
24
25 /*!
26    \todo is this still used / in working state?
27    should we cleanup and remove it for good
28  */
29
30 #include "stdafx.h"
31 #include "gtkmisc.h"
32
33 //
34 struct SVariableDef
35 {
36         CString m_strName;
37         CString m_strInput;
38         float m_fValue;
39 };
40
41 struct SVecVariableDef
42 {
43         CString m_strName;
44         CString m_strInput;
45         vec3_t m_vValue;
46 };
47
48
49
50 const int MAX_VARIABLES = 64;
51
52 brush_t* g_pHold1 = NULL;
53 brush_t* g_pHold2 = NULL;
54 brush_t* g_pHold3 = NULL;
55 bool g_bRotateAroundSelection;
56 int g_nVariableCount;
57 int g_nVecVariableCount;
58 int g_nLoopCounter;
59 float g_fDefault = 9999.9f;
60 vec3_t g_vDefault;
61 bool g_bStartLoop;
62 char* g_pLooper;
63 bool g_bKeepGoing;
64
65 SVariableDef g_Variables[MAX_VARIABLES];
66 SVecVariableDef g_VecVariables[MAX_VARIABLES];
67
68 void InitForScriptRun(){
69         g_pHold1 = NULL;
70         g_pHold2 = NULL;
71         g_pHold3 = NULL;
72         g_bRotateAroundSelection = true;
73         g_nVariableCount = 0;
74         g_nVecVariableCount = 0;
75         g_nLoopCounter = 0;
76         g_bStartLoop = false;
77         g_pLooper = NULL;
78         g_bKeepGoing = true;
79 }
80
81 void AddVariable( const char* pName, float fValue, const char* pInput = NULL ){
82         if ( g_nVariableCount < MAX_VARIABLES ) {
83                 g_Variables[g_nVariableCount].m_strName = pName;
84                 g_Variables[g_nVariableCount].m_strName.MakeLower();
85                 g_Variables[g_nVariableCount].m_fValue = fValue;
86                 if ( pInput ) {
87                         g_Variables[g_nVariableCount].m_strInput = pInput;
88                 }
89                 g_nVariableCount++;
90         }
91         else{
92                 gtk_MessageBox( g_pParentWnd->m_pWidget, "Maximum script variable limit reached!" );
93         }
94 }
95
96 float VariableValue( const char* pName ){
97         CString strName = pName;
98         strName.MakeLower();
99         for ( int n = 0; n < g_nVariableCount; n++ )
100         {
101                 if ( strName == g_Variables[n].m_strName ) {
102                         return g_Variables[n].m_fValue;
103                 }
104         }
105         //strName.Format("Reference to non-existant varirable %s", pName);
106         //g_pParentWnd->MessageBox(strName);
107         return g_fDefault;
108 }
109
110 void SetVariableValue( const char* pName, float fValue ){
111         CString strName = pName;
112         strName.MakeLower();
113         for ( int n = 0; n < g_nVariableCount; n++ )
114         {
115                 if ( strName == g_Variables[n].m_strName ) {
116                         g_Variables[n].m_fValue = fValue;
117                 }
118         }
119 }
120
121
122
123 void AddVectorVariable( const char* pName, const char* pInput = NULL ){
124         if ( g_nVecVariableCount < MAX_VARIABLES ) {
125                 g_VecVariables[g_nVecVariableCount].m_strName = pName;
126                 g_VecVariables[g_nVecVariableCount].m_strName.MakeLower();
127                 if ( pInput ) {
128                         g_VecVariables[g_nVariableCount].m_strInput = pInput;
129                 }
130                 g_nVecVariableCount++;
131         }
132         else{
133                 gtk_MessageBox( g_pParentWnd->m_pWidget, "Maximum script variable limit reached!" );
134         }
135 }
136
137 void VectorVariableValue( const char* pName, vec3_t& v ){
138         CString strName = pName;
139         strName.MakeLower();
140         for ( int n = 0; n < g_nVecVariableCount; n++ )
141         {
142                 if ( strName == g_VecVariables[n].m_strName ) {
143                         VectorCopy( g_VecVariables[n].m_vValue, v );
144                         return;
145                 }
146         }
147         strName.Format( "Reference to non-existant variable %s", pName );
148         gtk_MessageBox( g_pParentWnd->m_pWidget, strName );
149 }
150
151 void SetVectorVariableValue( const char* pName, vec3_t v ){
152         CString strName = pName;
153         strName.MakeLower();
154         for ( int n = 0; n < g_nVecVariableCount; n++ )
155         {
156                 if ( strName == g_VecVariables[n].m_strName ) {
157                         VectorCopy( v, g_VecVariables[n].m_vValue );
158                 }
159         }
160 }
161
162
163
164
165
166 // commands
167 //
168 // _CopySelected(nHoldPos)
169 // copies selected brush to hold spot 1, 2 or 3
170 //
171 // _MoveSelected(x, y, z)
172 // moves selected brush by coords provided
173 //
174 // _RotateSelected(x, y, z)
175 // rotates selected brush by coords provided
176 //
177 // _MoveHold(nHoldPos, x, y, z)
178 // moves brush in hold pos by coords provided
179 //
180 // _RotateHold(nHoldPos, x, y, z)
181 // rotates brush in hold pos by coords provided
182 //
183 // _CopyToMap(nHoldPos)
184 // copies hold brush to map
185 //
186 // _CopyAndSelect(nHoldPos)
187 // copies hold brush to map and selects it
188 //
189 // _Input(VarName1, ... VarNamennn)
190 // inputs a list of values from the user
191 //
192
193 typedef void ( PFNScript )( char*& );
194
195
196 struct SBrushScript
197 {
198         const char* m_pName;
199         PFNScript* m_pProc;
200 };
201
202
203 const char* GetParam( char*& pBuffer ){
204         static CString strParam;
205         bool bStringMode = false;
206
207         while ( *pBuffer != (char)NULL && isspace( *pBuffer ) ) // skip and whitespace
208                 pBuffer++;
209
210         if ( *pBuffer == '(' ) { // if it's an opening paren, skip it
211                 pBuffer++;
212         }
213
214         if ( *pBuffer == '\"' ) { // string ?
215                 pBuffer++;
216                 bStringMode = true;
217         }
218
219         strParam = "";
220
221         if ( bStringMode ) {
222                 while ( *pBuffer != (char)NULL && *pBuffer != '\"' )
223                         strParam += *pBuffer++;
224         }
225         else
226         {
227                 while ( *pBuffer != (char)NULL && *pBuffer != ' ' && *pBuffer != ')' && *pBuffer != ',' )
228                         strParam += *pBuffer++;
229         }
230
231         if ( *pBuffer != (char)NULL ) { // skip last char
232                 pBuffer++;
233         }
234
235         if ( strParam.GetLength() > 0 ) {
236                 if ( strParam.GetAt( 0 ) == '$' ) { // ? variable name
237                         float f = VariableValue( strParam );
238                         if ( f != g_fDefault ) {
239                                 strParam.Format( "%f", f );
240                         }
241                 }
242         }
243
244         return strParam;
245 }
246
247 brush_t* CopyBrush( brush_t* p ){
248         brush_t* pCopy = Brush_Clone( p );
249         //Brush_AddToList (pCopy, &active_brushes);
250         //Entity_LinkBrush (world_entity, pCopy);
251         Brush_Build( pCopy, false );
252
253         return pCopy;
254 }
255
256
257 void CopySelected( char*& pBuffer ){
258         // expects one param
259         CString strParam = GetParam( pBuffer );
260         int n = atoi( strParam );
261
262         brush_t* pCopy = NULL;
263         if ( selected_brushes.next != &selected_brushes &&
264                  selected_brushes.next->next == &selected_brushes ) {
265                 pCopy = selected_brushes.next;
266         }
267
268         if ( pCopy ) {
269                 if ( n == 1 ) {
270                         //if (g_pHold1)
271                         //Brush_Free(g_pHold1);
272                         g_pHold1 = CopyBrush( pCopy );
273                 }
274                 else if ( n == 2 ) {
275                         //if (g_pHold2)
276                         //Brush_Free(g_pHold2);
277                         g_pHold2 = CopyBrush( pCopy );
278                 }
279                 else
280                 {
281                         //if (g_pHold3)
282                         //Brush_Free(g_pHold3);
283                         g_pHold3 = CopyBrush( pCopy );
284                 }
285         }
286 }
287
288 void MoveSelected( char*& pBuffer ){
289         vec3_t v;
290         CString strParam = GetParam( pBuffer );
291         v[0] = atof( strParam );
292         strParam = GetParam( pBuffer );
293         v[1] = atof( strParam );
294         strParam = GetParam( pBuffer );
295         v[2] = atof( strParam );
296         Select_Move( v, false );
297         Sys_UpdateWindows( W_ALL );
298 }
299
300 void RotateSelected( char*& pBuffer ){
301         vec3_t v;
302
303         if ( g_bRotateAroundSelection ) {
304                 Select_GetTrueMid( v );
305                 VectorCopy( v, g_pParentWnd->ActiveXY()->RotateOrigin() );
306         }
307
308         CString strParam = GetParam( pBuffer );
309         v[0] = atof( strParam );
310         strParam = GetParam( pBuffer );
311         v[1] = atof( strParam );
312         strParam = GetParam( pBuffer );
313         v[2] = atof( strParam );
314         for ( int i = 0; i < 3; i++ )
315                 if ( v[i] != 0.0 ) {
316                         Select_RotateAxis( i, v[i], false, true );
317                 }
318         Sys_UpdateWindows( W_ALL );
319 }
320
321 void MoveHold( char*& pBuffer ){
322         CString strParam = GetParam( pBuffer );
323         brush_t* pBrush = NULL;
324         int nHold = atoi( strParam );
325         if ( nHold == 1 ) {
326                 pBrush = g_pHold1;
327         }
328         else if ( nHold == 2 ) {
329                 pBrush = g_pHold2;
330         }
331         else{
332                 pBrush = g_pHold3;
333         }
334
335         if ( pBrush ) {
336                 vec3_t v;
337                 strParam = GetParam( pBuffer );
338                 v[0] = atof( strParam );
339                 strParam = GetParam( pBuffer );
340                 v[1] = atof( strParam );
341                 strParam = GetParam( pBuffer );
342                 v[2] = atof( strParam );
343                 Brush_Move( pBrush, v, false );
344         }
345 }
346
347 void RotateHold( char*& pBuffer ){
348         CString strParam = GetParam( pBuffer );
349         brush_t* pBrush = NULL;
350         int nHold = atoi( strParam );
351         if ( nHold == 1 ) {
352                 pBrush = g_pHold1;
353         }
354         else if ( nHold == 2 ) {
355                 pBrush = g_pHold2;
356         }
357         else{
358                 pBrush = g_pHold3;
359         }
360
361         if ( pBrush ) {
362                 vec3_t v;
363                 strParam = GetParam( pBuffer );
364                 v[0] = atof( strParam );
365                 strParam = GetParam( pBuffer );
366                 v[1] = atof( strParam );
367                 strParam = GetParam( pBuffer );
368                 v[2] = atof( strParam );
369                 for ( int i = 0; i < 3; i++ )
370                         if ( v[i] != 0.0 ) {
371                                 Select_RotateAxis( i, v[i] );
372                         }
373         }
374 }
375
376 void CopyToMap( char*& pBuffer ){
377         CString strParam = GetParam( pBuffer );
378         brush_t* pBrush = NULL;
379         int nHold = atoi( strParam );
380         if ( nHold == 1 ) {
381                 pBrush = g_pHold1;
382         }
383         else if ( nHold == 2 ) {
384                 pBrush = g_pHold2;
385         }
386         else{
387                 pBrush = g_pHold3;
388         }
389
390         if ( pBrush ) {
391                 Brush_AddToList( pBrush, &active_brushes );
392                 Entity_LinkBrush( world_entity, pBrush );
393                 Brush_Build( pBrush, false );
394
395                 Sys_UpdateWindows( W_ALL );
396         }
397 }
398
399 void CopyAndSelect( char*& pBuffer ){
400         CString strParam = GetParam( pBuffer );
401         brush_t* pBrush = NULL;
402         int nHold = atoi( strParam );
403         if ( nHold == 1 ) {
404                 pBrush = g_pHold1;
405         }
406         else if ( nHold == 2 ) {
407                 pBrush = g_pHold2;
408         }
409         else{
410                 pBrush = g_pHold3;
411         }
412
413         if ( pBrush ) {
414                 Select_Deselect();
415                 Brush_AddToList( pBrush, &active_brushes );
416                 Entity_LinkBrush( world_entity, pBrush );
417                 Brush_Build( pBrush, false );
418
419                 Select_Brush( pBrush );
420                 Sys_UpdateWindows( W_ALL );
421         }
422 }
423
424 void Input( char*& pBuffer ){
425         bool bGo = false;
426         const char *fields[5] = { "", "", "", "", "" };
427         float values[5];
428
429         for ( int n = 0; n < 5 && n < g_nVariableCount; n++ )
430         {
431                 if ( g_Variables[n].m_strInput.GetLength() > 0 ) {
432                         bGo = true;
433                         fields[n] = g_Variables[n].m_strInput.GetBuffer();
434                 }
435         }
436
437         if ( !bGo ) {
438                 return;
439         }
440
441         if ( DoBSInputDlg( fields, values ) != IDOK ) {
442                 g_bKeepGoing = false;
443                 return;
444         }
445
446         for ( int n = 0; n < 5 && n < g_nVariableCount; n++ )
447         {
448                 if ( g_Variables[n].m_strInput.GetLength() > 0 ) {
449                         g_Variables[n].m_fValue = values[n];
450                 }
451         }
452 }
453
454 bool g_bWaiting;
455 void _3DPointDone( bool b, int n ){
456         g_bWaiting = false;
457 }
458
459 void _3DPointInput( char*& pBuffer ){
460         CString strParam = GetParam( pBuffer );
461         CString strParam2 = GetParam( pBuffer );
462         ShowInfoDialog( strParam2 );
463         AddVectorVariable( strParam, strParam2 );
464         g_bWaiting = true;
465         AcquirePath( 2, &_3DPointDone );
466         while ( g_bWaiting )
467                 gtk_main_iteration();
468         HideInfoDialog();
469         SetVectorVariableValue( strParam, g_PathPoints[0] );
470 }
471
472 void SetRotateOrigin( char*& pBuffer ){
473         vec3_t v;
474         CString strParam = GetParam( pBuffer );
475         VectorVariableValue( strParam, v );
476         VectorCopy( v, g_pParentWnd->ActiveXY()->RotateOrigin() );
477         g_bRotateAroundSelection = false;
478 }
479
480 void InputVar( char*& pBuffer ){
481         CString strParam = GetParam( pBuffer );
482         CString strParam2 = GetParam( pBuffer );
483         AddVariable( strParam, 0.0, strParam2 );
484 }
485
486 void LoopCount( char*& pBuffer ){
487         CString strParam = GetParam( pBuffer );
488         g_nLoopCounter = atoi( strParam );
489         if ( g_nLoopCounter == 0 ) {
490                 g_nLoopCounter = (int)VariableValue( strParam );
491         }
492         if ( g_nLoopCounter > 0 ) {
493                 g_pLooper = pBuffer;
494         }
495 }
496
497 void LoopRun( char*& pBuffer ){
498         if ( g_bStartLoop == true ) {
499                 g_nLoopCounter--;
500                 if ( g_nLoopCounter == 0 ) {
501                         g_bStartLoop = false;
502                         GetParam( pBuffer );
503                 }
504                 else{
505                         pBuffer = g_pLooper;
506                 }
507         }
508         else
509         {
510                 if ( g_pLooper && g_nLoopCounter > 0 ) {
511                         g_bStartLoop = true;
512                         pBuffer = g_pLooper;
513                 }
514                 else
515                 {
516                         GetParam( pBuffer );
517                 }
518         }
519 }
520
521
522 void ConfirmMessage( char*& pBuffer ){
523         CString strParam = GetParam( pBuffer );
524         if ( gtk_MessageBox( g_pParentWnd->m_pWidget, strParam, "Script Info", MB_OKCANCEL ) == IDCANCEL ) {
525                 g_bKeepGoing = false;
526         }
527 }
528
529 void Spherize( char*& pBuffer ){
530         g_bScreenUpdates = false;
531         for ( int n = 0; n < 120; n += 36 )
532         {
533                 for ( int i = 0; i < 360; i += 36 )
534                 {
535                         Select_RotateAxis( 0, i, false, true );
536                         CSG_Subtract();
537                 }
538                 Select_RotateAxis( 2, n, false, true );
539         }
540         g_bScreenUpdates = true;
541 }
542
543 void RunIt( char*& pBuffer );
544 SBrushScript g_ScriptCmds[] =
545 {
546         {"_CopySelected", &CopySelected},
547         {"_MoveSelected", &MoveSelected},
548         {"_RotateSelected", &RotateSelected},
549         {"_MoveHold", &MoveHold},
550         {"_RotateHold", &RotateHold},
551         {"_CopyToMap", &CopyToMap},
552         {"_CopyAndSelect", &CopyAndSelect},
553         {"_Input", &Input},
554         {"_3DPointInput", &_3DPointInput},
555         {"_SetRotateOrigin", &SetRotateOrigin},
556         {"_InputVar", &InputVar},
557         {"_LoopCount", &LoopCount},
558         {"_LoopRun", &LoopRun},
559         {"_ConfirmMessage", &ConfirmMessage},
560         {"_Spherize", &Spherize},
561         {"_RunScript", RunIt}
562 };
563
564 const int g_nScriptCmdCount = sizeof( g_ScriptCmds ) / sizeof( SBrushScript );
565
566 void RunScript( char* pBuffer ){
567         g_pHold1 = NULL;
568         g_pHold2 = NULL;
569         g_pHold3 = NULL;
570
571         while ( g_bKeepGoing && pBuffer && *pBuffer )
572         {
573                 while ( *pBuffer != (char)NULL && *pBuffer != '_' )
574                         pBuffer++;
575
576                 char* pTemp = pBuffer;
577                 int nLen = 0;
578                 while ( *pTemp != (char)NULL && *pTemp != '(' )
579                 {
580                         pTemp++;
581                         nLen++;
582                 }
583                 if ( *pBuffer != (char)NULL ) {
584                         bool bFound = false;
585                         for ( int i = 0; i < g_nScriptCmdCount; i++ )
586                         {
587                                 //if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, strlen(g_ScriptCmds[i].m_pName)) ==  0)
588                                 if ( strnicmp( g_ScriptCmds[i].m_pName, pBuffer, nLen ) ==  0 ) {
589                                         pBuffer += strlen( g_ScriptCmds[i].m_pName );
590                                         g_ScriptCmds[i].m_pProc( pBuffer );
591                                         if ( g_bStartLoop ) {
592                                         }
593                                         bFound = true;
594                                         break;
595                                 }
596                         }
597                         if ( !bFound ) {
598                                 pBuffer++;
599                         }
600                 }
601         }
602 }
603
604
605 void RunScriptByName( char* pBuffer, bool bInit ){
606         if ( bInit ) {
607                 InitForScriptRun();
608         }
609         char* pScript = new char[4096];
610         CString strINI;
611         strINI = g_strGameToolsPath;
612         strINI += "/scripts.ini";
613         CString strScript;
614         FILE *f;
615
616         f = fopen( strINI.GetBuffer(), "rt" );
617         if ( f != NULL ) {
618                 char line[1024], *ptr;
619
620                 // read section names
621                 while ( fgets( line, 1024, f ) != 0 )
622                 {
623                         if ( line[0] != '[' ) {
624                                 continue;
625                         }
626
627                         ptr = strchr( line, ']' );
628                         *ptr = '\0';
629
630                         if ( strcmp( line, pScript ) == 0 ) {
631                                 while ( fgets( line, 1024, f ) != 0 )
632                                 {
633                                         if ( ( strchr( line, '=' ) == NULL ) ||
634                                                  strlen( line ) == 0 ) {
635                                                 break;
636                                         }
637                                         strScript += line;
638                                 }
639                                 break;
640                         }
641                 }
642                 fclose( f );
643         }
644         RunScript( (char*)strScript.GetBuffer() );
645 }
646
647
648 void RunIt( char*& pBuffer ){
649         brush_t* p1 = g_pHold1;
650         brush_t* p2 = g_pHold2;
651         brush_t* p3 = g_pHold3;
652
653         CString strParam = GetParam( pBuffer );
654         RunScriptByName( (char*)strParam.GetBuffer(), false );
655
656         g_pHold3 = p3;
657         g_pHold2 = p2;
658         g_pHold1 = p1;
659 }