1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 #ifndef BZF_OBSTACLE_MGR_H
14 #define BZF_OBSTACLE_MGR_H
15 
16 #include "common.h"
17 
18 // system headers
19 #include <string>
20 #include <vector>
21 #include <iostream>
22 
23 // common headers
24 #include "ObstacleList.h"
25 #include "MeshTransform.h"
26 #include "BzMaterial.h"
27 
28 // avoid nasty dependencies
29 class Obstacle;
30 class BoxBuilding;
31 class PyramidBuilding;
32 class BaseBuilding;
33 class Teleporter;
34 class MeshObstacle;
35 class ArcObstacle;
36 class ConeObstacle;
37 class SphereObstacle;
38 class TetraBuilding;
39 class ObstacleModifier;
40 
41 
42 //
43 // Group Instance
44 // - uses a group definition and a transform to produce obstacles
45 //
46 
47 class GroupInstance
48 {
49 
50     friend class ObstacleModifier;
51 
52 public:
53     GroupInstance(const std::string& groupdef);
54     GroupInstance();
55     ~GroupInstance();
56     void init();
57 
58     void setName(const std::string& name);
59     void setTeam(int team);
60     void setTint(const float tint[4]);
61     void setPhysicsDriver(int phydrv);
62     void setTransform(const MeshTransform&);
63     void setMaterial(const BzMaterial*);
64     void setDriveThrough();
65     void setShootThrough();
66     void setCanRicochet();
67     void addMaterialSwap(const BzMaterial* src,
68                          const BzMaterial* dst);
69 
70     const std::string& getName() const;
71 
72     const std::string& getGroupDef() const;
73     const MeshTransform& getTransform() const;
74 
75     void *pack(void*);
76     const void *unpack(const void*);
77     int packSize();
78 
79     void print(std::ostream& out, const std::string& indent) const;
80 
81 private:
82     std::string groupdef;
83 
84     std::string name;
85     MeshTransform transform;
86     bool modifyTeam;
87     int team;
88     bool modifyColor;
89     float tint[4];
90     bool modifyPhysicsDriver;
91     int phydrv;
92     bool modifyMaterial;
93     const BzMaterial* material;
94     bool driveThrough;
95     bool shootThrough;
96     bool ricochet;
97     MaterialMap matMap;
98 };
99 
100 
101 //
102 // Group Definition
103 // - defines an obstacle group
104 //
105 
106 class GroupDefinition
107 {
108 public:
109     GroupDefinition(const std::string& name);
110     ~GroupDefinition();
111 
112     enum ObstacleTypes
113     {
114         wallType = 0,
115         boxType,
116         pyrType,
117         baseType,
118         teleType,
119         meshType,
120         arcType,
121         coneType,
122         sphereType,
123         tetraType,
124         ObstacleTypeCount
125     };
126 
127     void addObstacle(Obstacle* obstacle);
128     void addGroupInstance(GroupInstance* group);
129 
130     void clear(); // delete the list and the obstacles
131     void tighten(); // reduce memory usage
132 
133     void sort(int (*compare)(const void* a, const void* b));
134 
135     void makeGroups(const MeshTransform& xform,
136                     const ObstacleModifier& obsMod) const;
137 
138     void replaceBasesWithBoxes();
139     void deleteInvalidObstacles();
140 
141     const std::string& getName() const;
142     const ObstacleList& getList(int type) const;
143     const std::vector<GroupInstance*>& getGroups() const;
144 
145     // Get the list of meshes that came from the world file.
146     // This includes the meshes in group definitions, even if
147     // they have never been instantiated.
148     void getSourceMeshes(std::vector<MeshObstacle*>& meshes) const;
149 
150     int packSize() const;
151     void *pack(void*) const;
152     const void *unpack(const void*);
153 
154     void printGrouped(std::ostream& out, const std::string& indent) const;
155     void printFlatFile(std::ostream& out, const std::string& indent) const;
156 
157 public:
158     static void clearDepthName();
159 
160 private:
161     Obstacle* newObstacle(int type);
162     void makeTeleName(Obstacle* obs, unsigned int pos) const;
163     void appendGroupName(const GroupInstance* group) const;
164 
165 private:
166     std::string name;
167 
168     ObstacleList lists[ObstacleTypeCount];
169     std::vector<GroupInstance*>     groups;
170 
171     mutable bool active; // for recursion checking
172 
173 private:
174     static std::string depthName;
175 };
176 
getName()177 inline const std::string& GroupDefinition::getName() const
178 {
179     return name;
180 }
getList(int type)181 inline const ObstacleList& GroupDefinition::getList(int type) const
182 {
183     return lists[type];
184 }
getGroups()185 inline const std::vector<GroupInstance*>& GroupDefinition::getGroups() const
186 {
187     return groups;
188 }
189 
190 
191 //
192 // Group Definition Manager
193 // - utility class to keep track of group definitions
194 //
195 
196 class GroupDefinitionMgr
197 {
198 public:
199     GroupDefinitionMgr();
200     ~GroupDefinitionMgr();
201 
202     void clear(); // delete the lists and the obstacles
203     void tighten(); // reduce memory usage
204     void makeWorld(); // make the local obstacles for the groups
205     void replaceBasesWithBoxes();
206 
207     void addWorldObstacle(Obstacle* obstacle);
208     void addGroupDef(GroupDefinition* groupdef);
209 
210     GroupDefinition* findGroupDef(const std::string& name) const;
211 
212     // Get the list of meshes that came from the world file.
213     // This includes the meshes in group definitions, even if
214     // they have never been instantiated.
215     void getSourceMeshes(std::vector<MeshObstacle*>& meshes) const;
216 
217     const GroupDefinition* getWorld() const;
218 
219     // convenience functions
220     const ObstacleList& getWalls() const;
221     const ObstacleList& getBoxes() const;
222     const ObstacleList& getPyrs() const;
223     const ObstacleList& getBases() const;
224     const ObstacleList& getTeles() const;
225     const ObstacleList& getMeshes() const;
226     const ObstacleList& getArcs() const;
227     const ObstacleList& getCones() const;
228     const ObstacleList& getSpheres() const;
229     const ObstacleList& getTetras() const;
230 
231     int packSize() const;
232     void *pack(void*) const;
233     const void *unpack(const void*);
234 
235     void print(std::ostream& out, const std::string& indent) const;
236 
237 private:
238     GroupDefinition world;
239     std::vector<GroupDefinition*> list;
240 };
241 
getWorld()242 inline const GroupDefinition* GroupDefinitionMgr::getWorld() const
243 {
244     return &world;
245 }
246 
getWalls()247 inline const ObstacleList& GroupDefinitionMgr::getWalls() const
248 {
249     return world.getList(GroupDefinition::wallType);
250 }
getBoxes()251 inline const ObstacleList& GroupDefinitionMgr::getBoxes() const
252 {
253     return world.getList(GroupDefinition::boxType);
254 }
getPyrs()255 inline const ObstacleList& GroupDefinitionMgr::getPyrs() const
256 {
257     return world.getList(GroupDefinition::pyrType);
258 }
getBases()259 inline const ObstacleList& GroupDefinitionMgr::getBases() const
260 {
261     return world.getList(GroupDefinition::baseType);
262 }
getTeles()263 inline const ObstacleList& GroupDefinitionMgr::getTeles() const
264 {
265     return world.getList(GroupDefinition::teleType);
266 }
getMeshes()267 inline const ObstacleList& GroupDefinitionMgr::getMeshes() const
268 {
269     return world.getList(GroupDefinition::meshType);
270 }
getArcs()271 inline const ObstacleList& GroupDefinitionMgr::getArcs() const
272 {
273     return world.getList(GroupDefinition::arcType);
274 }
getCones()275 inline const ObstacleList& GroupDefinitionMgr::getCones() const
276 {
277     return world.getList(GroupDefinition::coneType);
278 }
getSpheres()279 inline const ObstacleList& GroupDefinitionMgr::getSpheres() const
280 {
281     return world.getList(GroupDefinition::sphereType);
282 }
getTetras()283 inline const ObstacleList& GroupDefinitionMgr::getTetras() const
284 {
285     return world.getList(GroupDefinition::tetraType);
286 }
287 
288 
289 extern GroupDefinitionMgr OBSTACLEMGR;
290 
291 
292 #endif // BZF_OBSTACLE_MGR_H
293 
294 
295 // Local Variables: ***
296 // mode: C++ ***
297 // tab-width: 4 ***
298 // c-basic-offset: 4 ***
299 // indent-tabs-mode: nil ***
300 // End: ***
301 // ex: shiftwidth=4 tabstop=4
302