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