1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program 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 this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 *
22 * Based on the original sources
23 * Faery Tale II -- The Halls of the Dead
24 * (c) 1993-1996 The Wyrmkeep Entertainment Co.
25 */
26
27 #ifndef SAGA2_PROPERTY_H
28 #define SAGA2_PROPERTY_H
29 namespace Saga2 {
30
31 /* ===================================================================== *
32 Property class template
33 * ===================================================================== */
34
35 // This is an abstract property function object class. A property function
36 // object can be used to determine if an object of type T has a certain
37 // property. In order to do this, a pointer to an object of type T is
38 // passed to the operator () member function, which returns true if the
39 // object has the property and false if it does not.
40
41 // These function objects can be used to process only subset of object of
42 // type T which meet certain criteria, without having to know what those
43 // criteria are.
44
45 template < class T >
46 class Property {
47 public:
~Property()48 virtual ~Property() {}
49
50 virtual bool operator()(T *obj) const = 0;
51 };
52
53 /* ===================================================================== *
54 SimpleProperty class template
55 * ===================================================================== */
56
57 // This class defines the most simple type of property function object.
58 // A simple property is constructed with a pointer to a function which will
59 // accept as a parameter a pointer to an object of type T and evaluate the
60 // object to determine if it has a certain property. The only task of the
61 // operator () member function is to call this function and return its
62 // result.
63
64 template < class T >
65 class SimpleProperty : public Property< T > {
66 bool (*propertyFunc)(T *); // The pointer to the property
67 // evaluation function
68
69 public:
70 // Constructor
SimpleProperty(bool (* func)(T *))71 SimpleProperty(bool (*func)(T *)) :
72 propertyFunc(func) {
73 }
74
75 bool operator()(T *obj) const;
76 };
77
78 template < class T >
operator()79 bool SimpleProperty< T >::operator()(T *obj) const {
80 // Simply pass this call through to the property evaluation function
81 return (*propertyFunc)(obj);
82 }
83
84 /* ===================================================================== *
85 CompoundProperty class template
86 * ===================================================================== */
87
88 // This is an abstract base class for all compound properties: properties
89 // which are defined in terms of one or more other properties. This class
90 // cosists of a pointer to an array of pointers to Property's and a count
91 // of the number of pointers in the array.
92
93 template < class T >
94 class CompoundProperty : public Property< T > {
95 protected:
96 Property< T > **propertyArray; // A pointer to an array of pointers
97 // to Properties.
98 uint16 arraySize; // The number of elements in the
99 // array
100
101 public:
102 // Constructor
103 CompoundProperty(Property< T > **array, uint16 size);
104
105 // Virtual destructor
106 virtual ~CompoundProperty(void);
107 };
108
109 template < class T >
CompoundProperty(Property<T> ** array,uint16 size)110 CompoundProperty< T >::CompoundProperty(
111 Property< T > **array,
112 uint16 size) {
113 // Determine the number of bytes needed to copy the array
114 uint16 arrayBytes = sizeof(Property< T > *) * size;
115
116 // Allocate memory to copy the array.
117 propertyArray = (Property< T > **)malloc(arrayBytes);
118 #if DEBUG
119 assert(propertyArray);
120 #endif
121 // Copy the array
122 memcpy(propertyArray, array, arrayBytes);
123 arraySize = size;
124 }
125
126
127 template < class T >
~CompoundProperty(void)128 CompoundProperty< T >::~CompoundProperty(void) {
129 // Free the array memory
130 free(propertyArray);
131 }
132
133 /* ===================================================================== *
134 PropertyAnd class template
135 * ===================================================================== */
136
137 // This class defines an 'and' compound property. Each of the sub
138 // properties in the compound property list must evaluate to true for this
139 // function object to evaluate to true.
140
141 template < class T >
142 class PropertyAnd : public CompoundProperty< T > {
143 public:
144 // Constructor
PropertyAnd(Property<T> ** array,uint16 size)145 PropertyAnd(Property< T > **array, uint16 size) :
146 CompoundProperty< T >(array, size) {
147 }
148
149 bool operator()(T *obj) const;
150 };
151
152 template < class T >
operator()153 bool PropertyAnd< T >::operator()(T *obj) const {
154 #if 0
155 uint16 i;
156
157 // Iterate through each element in the array and if any evaluate to
158 // false, return false immediately.
159 for (i = 0; i < arraySize; i++)
160 if ((*propertyArray[i])(obj) == false) return false;
161 #endif
162 warning("STUB: PropertyAnd");
163
164 return true;
165 }
166
167 /* ===================================================================== *
168 PropertyOr class template
169 * ===================================================================== */
170
171 // This class defines an 'or' compound property. If any of the sub
172 // properties in the compound property list evaluate to true this function
173 // object will evaluate to true.
174
175 template < class T >
176 class PropertyOr : public CompoundProperty< T > {
177 public:
178 // Constructor
PropertyOr(Property<T> ** array,uint16 size)179 PropertyOr(Property< T > **array, uint16 size) :
180 CompoundProperty< T >(array, size) {
181 }
182
183 bool operator()(T *obj) const;
184 };
185
186 template < class T >
operator()187 bool PropertyOr< T >::operator()(T *obj) const {
188 #if 0
189 uint16 i;
190
191 // Iterate through each element in the array and if any evaluate to
192 // true, return true immediately.
193 for (i = 0; i < arraySize; i++)
194 if ((*propertyArray[i])(obj)) return true;
195 #endif
196 warning("STUB: PropertyOr");
197
198 return false;
199 }
200
201 /* ===================================================================== *
202 Object properties
203 * ===================================================================== */
204
205 class GameObject;
206
207 typedef Property< GameObject > ObjectProperty;
208 typedef SimpleProperty< GameObject > SimpleObjectProperty;
209 typedef PropertyAnd< GameObject > ObjectPropertyAnd;
210 typedef PropertyOr< GameObject > ObjectPropertyOr;
211
212 typedef int16 ObjectPropertyID;
213
214 enum {
215 objPropIDObject,
216 objPropIDActor,
217 objPropIDWorld,
218 objPropIDLocked,
219 objPropIDUnlocked,
220 objPropIDKey,
221 objPropIDPlayerActor,
222 objPropIDEnemy,
223
224 objPropIDCount
225 };
226
227 /* ===================================================================== *
228 Actor properties
229 * ===================================================================== */
230
231 class Actor;
232
233 typedef Property< Actor > ActorProperty;
234 typedef SimpleProperty< Actor > SimpleActorProperty;
235 typedef PropertyAnd< Actor > ActorPropertyAnd;
236 typedef PropertyOr< Actor > ActorPropertyOr;
237
238 typedef int16 ActorPropertyID;
239
240 enum {
241 actorPropIDDead,
242 actorPropIDCenterActor,
243 actorPropIDPlayerActor,
244 actorPropIDEnemy,
245
246 actorPropIDCount
247 };
248
249 /* ===================================================================== *
250 Tile properties
251 * ===================================================================== */
252
253 struct TileInfo;
254
255 typedef Property< TileInfo > TileProperty;
256 typedef SimpleProperty< TileInfo > SimpleTileProperty;
257 typedef PropertyAnd< TileInfo > TilePropertyAnd;
258 typedef PropertyOr< TileInfo > TilePropertyOr;
259
260 typedef int16 TilePropertyID;
261
262 enum {
263 tilePropIDHasWater,
264
265 tilePropIDCount
266 };
267
268 /* ===================================================================== *
269 MetaTile properties
270 * ===================================================================== */
271
272 class MetaTile;
273
274 /* ===================================================================== *
275 MetaTileProperty class
276 * ===================================================================== */
277
278 // The MetaTileProperty class hierarchy is similar to the Property template
279 // class hierarchy. The reason that MetaTile's have a separate Property
280 // class hierarchy, is because a MetaTile may only be uniquely identified
281 // if the location of the MetaTile is specifed, as well as a pointer to the
282 // MetaTile structure. This difference alters the interface of the
283 // operator () member function by requiring an additional TilePoint
284 // parameter.
285
286 class MetaTileProperty {
287 public:
~MetaTileProperty()288 virtual ~MetaTileProperty() {}
289 virtual bool operator()(
290 MetaTile *mt,
291 int16 mapNum,
292 const TilePoint &tp) const = 0;
293 };
294
295 /* ===================================================================== *
296 SimpleMetaTileProperty class
297 * ===================================================================== */
298
299 class SimpleMetaTileProperty : public MetaTileProperty {
300 // Pointer to the property evaluation function.
301 bool (*propertyFunc)(MetaTile *, int16, const TilePoint &);
302
303 public:
304 // Constructor
SimpleMetaTileProperty(bool (* func)(MetaTile *,int16,const TilePoint &))305 SimpleMetaTileProperty(bool (*func)(MetaTile *, int16, const TilePoint &)) :
306 propertyFunc(func) {
307 }
308
~SimpleMetaTileProperty()309 virtual ~SimpleMetaTileProperty() {}
310
311 bool operator()(
312 MetaTile *mt,
313 int16 mapNum,
314 const TilePoint &tp) const;
315 };
316
317 /* ===================================================================== *
318 CompoundMetaTileProperty class
319 * ===================================================================== */
320
321 class CompoundMetaTileProperty : public MetaTileProperty {
322 protected:
323 MetaTileProperty **propertyArray; // Array of pointers to
324 // MetaTileProperty's
325 uint16 arraySize; // Elements in the array
326
327 public:
328 // Constructor
329 CompoundMetaTileProperty(MetaTileProperty **array, uint16 size);
330
331 // Virtual destructor
332 virtual ~CompoundMetaTileProperty(void);
333 };
334
335 /* ===================================================================== *
336 MetaTilePropertyAnd class
337 * ===================================================================== */
338
339 class MetaTilePropertyAnd : public CompoundMetaTileProperty {
340 public:
341 // Constructor
MetaTilePropertyAnd(MetaTileProperty ** array,uint16 size)342 MetaTilePropertyAnd(MetaTileProperty **array, uint16 size) :
343 CompoundMetaTileProperty(array, size) {
344 }
345
346 bool operator()(
347 MetaTile *mt,
348 int16 mapNum,
349 const TilePoint &tp) const;
350 };
351
352 /* ===================================================================== *
353 MetaTilePropertyOr class
354 * ===================================================================== */
355
356 class MetaTilePropertyOr : public CompoundMetaTileProperty {
357 public:
358 // Constructor
MetaTilePropertyOr(MetaTileProperty ** array,uint16 size)359 MetaTilePropertyOr(MetaTileProperty **array, uint16 size) :
360 CompoundMetaTileProperty(array, size) {
361 }
362
363 bool operator()(
364 MetaTile *mt,
365 int16 mapNum,
366 const TilePoint &tp) const;
367 };
368
369 typedef int16 MetaTilePropertyID;
370
371 enum {
372 metaTilePropIDHasWater,
373
374 metaTilePropIDCount
375 };
376
377 bool objIsObject(GameObject *obj);
378
379 bool objIsActor(GameObject *obj);
380
381 bool objIsWorld(GameObject *obj);
382
383 bool objIsLocked(GameObject *obj);
384
385 bool objIsUnlocked(GameObject *obj);
386
387 bool objIsKey(GameObject *obj);
388
389 bool objIsPlayerActor(GameObject *obj);
390
391 bool objIsEnemy(GameObject *obj);
392
393 bool actorIsDead(Actor *a);
394
395 bool actorIsCenterActor(Actor *a);
396
397 bool actorIsPlayerActor(Actor *a);
398
399 bool actorIsEnemy(Actor *a);
400
401 bool tileHasWater(TileInfo *ti);
402
403 bool metaTileHasWater(MetaTile *mt, int16 mapNum, const TilePoint &mCoords);
404
405 class Properties {
406 private:
407 Common::Array<ObjectProperty *> _objPropArray;
408 Common::Array<ActorProperty *> _actorPropArray;
409 Common::Array<TileProperty *> _tilePropArray;
410 Common::Array<MetaTileProperty *> _metaTilePropArray;
411
412 public:
413
414 Properties();
415 ~Properties();
416
getObjProp(ObjectPropertyID id)417 const ObjectProperty *getObjProp(ObjectPropertyID id) {
418 return _objPropArray[id];
419 }
420
getActorProp(ActorPropertyID id)421 const ActorProperty *getActorProp(ActorPropertyID id) {
422 return _actorPropArray[id];
423 }
424
getTileProp(TilePropertyID id)425 const TileProperty *getTileProp(TilePropertyID id) {
426 return _tilePropArray[id];
427 }
428
getMetaTileProp(MetaTilePropertyID id)429 const MetaTileProperty *getMetaTileProp(MetaTilePropertyID id) {
430 return _metaTilePropArray[id];
431 }
432 };
433
434 } // end of namespace Saga2
435
436 #endif
437