ported bobtoolz
[xonotic/netradiant.git] / contrib / bobtoolz / DTreePlanter.h
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 #ifndef __DTREE_H__
21 #define __DTREE_H__
22
23 #include "qerplugin.h"
24 #include "signal/isignal.h"
25 #include "string/string.h"
26
27 #include "DEntity.h"
28 #include "scriptparser.h"
29 #include "mathlib.h"
30 #include "misc.h"
31
32 #define MAX_QPATH 64
33
34 typedef struct treeModel_s {
35         char name[MAX_QPATH];
36 } treeModel_t;
37
38 #define MAX_TP_MODELS 256
39
40 class DTreePlanter {
41   MouseEventHandlerId m_mouseDown;
42   SignalHandlerId m_destroyed;
43 public:
44         SignalHandlerResult mouseDown(const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers);
45   typedef Member3<DTreePlanter, const WindowVector&, ButtonIdentifier, ModifierFlags, SignalHandlerResult, &DTreePlanter::mouseDown> MouseDownCaller;
46         void destroyed()
47   {
48     m_mouseDown = MouseEventHandlerId();
49     m_destroyed = SignalHandlerId();
50   }
51   typedef Member<DTreePlanter, void, &DTreePlanter::destroyed> DestroyedCaller;
52
53   DTreePlanter() {
54                 m_numModels =   0;
55                 m_offset =              0;
56                 m_maxPitch =    0;
57                 m_minPitch =    0;
58                 m_maxYaw =              0;
59                 m_minYaw =              0;
60                 m_setAngles =   false;
61                 m_useScale =    false;
62                 m_autoLink =    false;
63                 m_linkNum =             0;
64
65                 m_world.LoadSelectedBrushes();
66
67                 char buffer[256];
68                 GetFilename( buffer, "bt/tp_ent.txt" );
69
70                 FILE* file = fopen( buffer, "rb" );
71                 if(file) {
72                         fseek( file, 0, SEEK_END );
73                         int len = ftell( file );
74                         fseek( file, 0, SEEK_SET );
75
76                         if(len) {
77                                 char* buf = new char[len+1];
78                                 buf[len] = '\0';
79                                 // parser will do the cleanup, dont delete.
80
81                                 fread( buf, len, 1, file );
82
83                                 CScriptParser parser;
84                                 parser.SetScript( buf );
85
86                                 ReadConfig( &parser );
87                         }
88
89                         fclose( file );
90                 }
91
92     m_mouseDown = GlobalRadiant().XYWindowMouseDown_connect(makeSignalHandler3(MouseDownCaller(), *this));
93     m_destroyed = GlobalRadiant().XYWindowDestroyed_connect(makeSignalHandler(DestroyedCaller(), *this));
94         }
95
96   virtual ~DTreePlanter()
97   {
98     if(!m_mouseDown.isNull())
99     {
100       GlobalRadiant().XYWindowMouseDown_disconnect(m_mouseDown);
101     }
102     if(!m_destroyed.isNull())
103     {
104       GlobalRadiant().XYWindowDestroyed_disconnect(m_destroyed);
105     }
106   }
107
108 #define MT(t)   string_equal_nocase( pToken, t )
109 #define GT              pToken = pScriptParser->GetToken( true )
110 #define CT              if(!*pToken) { return; }
111
112         void ReadConfig( CScriptParser* pScriptParser ) {
113                 const char* GT;
114                 CT;
115
116                 do {
117                         GT;
118                         if(*pToken == '}') {
119                                 break;
120                         }
121
122                         if(MT("model")) {
123                                 if(m_numModels >= MAX_TP_MODELS) {
124                                         return;
125                                 }
126
127                                 GT; CT;
128
129                                 strncpy( m_trees[m_numModels++].name, pToken, MAX_QPATH );
130                         } else if(MT("link")) {
131                                 GT; CT;
132
133                                 strncpy( m_linkName, pToken, MAX_QPATH );
134
135                                 m_autoLink = true;
136                         } else if(MT("entity")) {
137                                 GT; CT;
138
139                                 strncpy( m_entType, pToken, MAX_QPATH );
140                         } else if(MT("offset")) {
141                                 GT; CT;
142
143                                 m_offset = atoi(pToken);
144                         } else if(MT("pitch")) {
145                                 GT; CT;
146
147                                 m_minPitch = atoi(pToken);
148
149                                 GT; CT;
150
151                                 m_maxPitch = atoi(pToken);
152
153                                 m_setAngles = true;
154                         } else if(MT("yaw")) {
155                                 GT; CT;
156
157                                 m_minYaw = atoi(pToken);
158
159                                 GT; CT;
160
161                                 m_maxYaw = atoi(pToken);
162
163                                 m_setAngles = true;
164                         } else if(MT("scale")) {
165                                 GT; CT;
166
167                                 m_minScale = static_cast<float>(atof(pToken));
168
169                                 GT; CT;
170
171                                 m_maxScale = static_cast<float>(atof(pToken));
172
173                                 m_useScale = true;
174                         } else if(MT("numlinks")) {
175                                 GT; CT;
176
177                                 m_linkNum = atoi( pToken );
178                         }
179                 } while( true );
180         }
181
182         bool FindDropPoint(vec3_t in, vec3_t out);
183         void DropEntsToGround( void );
184         void MakeChain( void );
185         void SelectChain( void );
186
187 private:
188         DEntity                 m_world;
189
190         treeModel_t             m_trees[MAX_TP_MODELS];
191
192         int                             m_numModels;
193         int                             m_offset;
194         int                             m_maxPitch;
195         int                             m_minPitch;
196         int                             m_maxYaw;
197         int                             m_minYaw;
198
199         char                    m_entType[MAX_QPATH];
200         char                    m_linkName[MAX_QPATH];
201         int                             m_linkNum;
202
203         float                   m_minScale;
204         float                   m_maxScale;
205
206         bool                    m_useScale;
207         bool                    m_setAngles;
208         bool                    m_autoLink;
209 };
210
211 #endif