scummvm/engines/saga2/property.h
2022-10-29 13:50:59 +02:00

435 lines
12 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* Based on the original sources
* Faery Tale II -- The Halls of the Dead
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
*/
#ifndef SAGA2_PROPERTY_H
#define SAGA2_PROPERTY_H
namespace Saga2 {
/* ===================================================================== *
Property class template
* ===================================================================== */
// This is an abstract property function object class. A property function
// object can be used to determine if an object of type T has a certain
// property. In order to do this, a pointer to an object of type T is
// passed to the operator () member function, which returns true if the
// object has the property and false if it does not.
// These function objects can be used to process only subset of object of
// type T which meet certain criteria, without having to know what those
// criteria are.
template < class T >
class Property {
public:
virtual ~Property() {}
virtual bool operator()(T *obj) const = 0;
};
/* ===================================================================== *
SimpleProperty class template
* ===================================================================== */
// This class defines the most simple type of property function object.
// A simple property is constructed with a pointer to a function which will
// accept as a parameter a pointer to an object of type T and evaluate the
// object to determine if it has a certain property. The only task of the
// operator () member function is to call this function and return its
// result.
template < class T >
class SimpleProperty : public Property< T > {
bool (*_propertyFunc)(T *); // The pointer to the property
// evaluation function
public:
// Constructor
SimpleProperty(bool (*func)(T *)) :
_propertyFunc(func) {
}
bool operator()(T *obj) const;
};
template < class T >
bool SimpleProperty< T >::operator()(T *obj) const {
// Simply pass this call through to the property evaluation function
return (*_propertyFunc)(obj);
}
/* ===================================================================== *
CompoundProperty class template
* ===================================================================== */
// This is an abstract base class for all compound properties: properties
// which are defined in terms of one or more other properties. This class
// cosists of a pointer to an array of pointers to Property's and a count
// of the number of pointers in the array.
template < class T >
class CompoundProperty : public Property< T > {
protected:
Property< T > **_propertyArray; // A pointer to an array of pointers
// to Properties.
uint16 _arraySize; // The number of elements in the
// array
public:
// Constructor
CompoundProperty(Property< T > **array, uint16 size);
// Virtual destructor
virtual ~CompoundProperty();
};
template < class T >
CompoundProperty< T >::CompoundProperty(
Property< T > **array,
uint16 size) {
// Determine the number of bytes needed to copy the array
uint16 arrayBytes = sizeof(Property< T > *) * size;
// Allocate memory to copy the array.
_propertyArray = (Property< T > **)malloc(arrayBytes);
assert(_propertyArray);
// Copy the array
memcpy(_propertyArray, array, arrayBytes);
_arraySize = size;
}
template < class T >
CompoundProperty< T >::~CompoundProperty() {
// Free the array memory
free(_propertyArray);
}
/* ===================================================================== *
PropertyAnd class template
* ===================================================================== */
// This class defines an 'and' compound property. Each of the sub
// properties in the compound property list must evaluate to true for this
// function object to evaluate to true.
template < class T >
class PropertyAnd : public CompoundProperty< T > {
public:
// Constructor
PropertyAnd(Property< T > **array, uint16 size) :
CompoundProperty< T >(array, size) {
}
bool operator()(T *obj) const;
};
template < class T >
bool PropertyAnd< T >::operator()(T *obj) const {
#if 0
uint16 i;
// Iterate through each element in the array and if any evaluate to
// false, return false immediately.
for (i = 0; i < arraySize; i++)
if ((*propertyArray[i])(obj) == false) return false;
#endif
warning("STUB: PropertyAnd");
return true;
}
/* ===================================================================== *
PropertyOr class template
* ===================================================================== */
// This class defines an 'or' compound property. If any of the sub
// properties in the compound property list evaluate to true this function
// object will evaluate to true.
template < class T >
class PropertyOr : public CompoundProperty< T > {
public:
// Constructor
PropertyOr(Property< T > **array, uint16 size) :
CompoundProperty< T >(array, size) {
}
bool operator()(T *obj) const;
};
template < class T >
bool PropertyOr< T >::operator()(T *obj) const {
#if 0
uint16 i;
// Iterate through each element in the array and if any evaluate to
// true, return true immediately.
for (i = 0; i < arraySize; i++)
if ((*propertyArray[i])(obj)) return true;
#endif
warning("STUB: PropertyOr");
return false;
}
/* ===================================================================== *
Object properties
* ===================================================================== */
class GameObject;
typedef Property< GameObject > ObjectProperty;
typedef SimpleProperty< GameObject > SimpleObjectProperty;
typedef PropertyAnd< GameObject > ObjectPropertyAnd;
typedef PropertyOr< GameObject > ObjectPropertyOr;
typedef int16 ObjectPropertyID;
enum {
kObjPropIDObject,
kObjPropIDActor,
kObjPropIDWorld,
kObjPropIDLocked,
kObjPropIDUnlocked,
kObjPropIDKey,
kObjPropIDPlayerActor,
kObjPropIDEnemy,
kObjPropIDCount
};
/* ===================================================================== *
Actor properties
* ===================================================================== */
class Actor;
typedef Property< Actor > ActorProperty;
typedef SimpleProperty< Actor > SimpleActorProperty;
typedef PropertyAnd< Actor > ActorPropertyAnd;
typedef PropertyOr< Actor > ActorPropertyOr;
typedef int16 ActorPropertyID;
enum {
kActorPropIDDead,
kActorPropIDCenterActor,
kActorPropIDPlayerActor,
kActorPropIDEnemy,
kActorPropIDCount
};
/* ===================================================================== *
Tile properties
* ===================================================================== */
struct TileInfo;
typedef Property< TileInfo > TileProperty;
typedef SimpleProperty< TileInfo > SimpleTileProperty;
typedef PropertyAnd< TileInfo > TilePropertyAnd;
typedef PropertyOr< TileInfo > TilePropertyOr;
typedef int16 TilePropertyID;
enum {
kTilePropIDHasWater,
kTilePropIDCount
};
/* ===================================================================== *
MetaTile properties
* ===================================================================== */
class MetaTile;
/* ===================================================================== *
MetaTileProperty class
* ===================================================================== */
// The MetaTileProperty class hierarchy is similar to the Property template
// class hierarchy. The reason that MetaTile's have a separate Property
// class hierarchy, is because a MetaTile may only be uniquely identified
// if the location of the MetaTile is specifed, as well as a pointer to the
// MetaTile structure. This difference alters the interface of the
// operator () member function by requiring an additional TilePoint
// parameter.
class MetaTileProperty {
public:
virtual ~MetaTileProperty() {}
virtual bool operator()(
MetaTile *mt,
int16 mapNum,
const TilePoint &tp) const = 0;
};
/* ===================================================================== *
SimpleMetaTileProperty class
* ===================================================================== */
class SimpleMetaTileProperty : public MetaTileProperty {
// Pointer to the property evaluation function.
bool (*_propertyFunc)(MetaTile *, int16, const TilePoint &);
public:
// Constructor
SimpleMetaTileProperty(bool (*func)(MetaTile *, int16, const TilePoint &)) :
_propertyFunc(func) {
}
virtual ~SimpleMetaTileProperty() {}
bool operator()(
MetaTile *mt,
int16 mapNum,
const TilePoint &tp) const;
};
/* ===================================================================== *
CompoundMetaTileProperty class
* ===================================================================== */
class CompoundMetaTileProperty : public MetaTileProperty {
protected:
MetaTileProperty **_propertyArray; // Array of pointers to
// MetaTileProperty's
uint16 _arraySize; // Elements in the array
public:
// Constructor
CompoundMetaTileProperty(MetaTileProperty **array, uint16 size);
// Virtual destructor
virtual ~CompoundMetaTileProperty();
};
/* ===================================================================== *
MetaTilePropertyAnd class
* ===================================================================== */
class MetaTilePropertyAnd : public CompoundMetaTileProperty {
public:
// Constructor
MetaTilePropertyAnd(MetaTileProperty **array, uint16 size) :
CompoundMetaTileProperty(array, size) {
}
bool operator()(
MetaTile *mt,
int16 mapNum,
const TilePoint &tp) const;
};
/* ===================================================================== *
MetaTilePropertyOr class
* ===================================================================== */
class MetaTilePropertyOr : public CompoundMetaTileProperty {
public:
// Constructor
MetaTilePropertyOr(MetaTileProperty **array, uint16 size) :
CompoundMetaTileProperty(array, size) {
}
bool operator()(
MetaTile *mt,
int16 mapNum,
const TilePoint &tp) const;
};
typedef int16 MetaTilePropertyID;
enum {
kMetaTilePropIDHasWater,
kMetaTilePropIDCount
};
bool objIsObject(GameObject *obj);
bool objIsActor(GameObject *obj);
bool objIsWorld(GameObject *obj);
bool objIsLocked(GameObject *obj);
bool objIsUnlocked(GameObject *obj);
bool objIsKey(GameObject *obj);
bool objIsPlayerActor(GameObject *obj);
bool objIsEnemy(GameObject *obj);
bool actorIsDead(Actor *a);
bool actorIsCenterActor(Actor *a);
bool actorIsPlayerActor(Actor *a);
bool actorIsEnemy(Actor *a);
bool tileHasWater(TileInfo *ti);
bool metaTileHasWater(MetaTile *mt, int16 mapNum, const TilePoint &mCoords);
class Properties {
private:
Common::Array<ObjectProperty *> _objPropArray;
Common::Array<ActorProperty *> _actorPropArray;
Common::Array<TileProperty *> _tilePropArray;
Common::Array<MetaTileProperty *> _metaTilePropArray;
public:
Properties();
~Properties();
const ObjectProperty *getObjProp(ObjectPropertyID id) {
return _objPropArray[id];
}
const ActorProperty *getActorProp(ActorPropertyID id) {
return _actorPropArray[id];
}
const TileProperty *getTileProp(TilePropertyID id) {
return _tilePropArray[id];
}
const MetaTileProperty *getMetaTileProp(MetaTilePropertyID id) {
return _metaTilePropArray[id];
}
};
} // end of namespace Saga2
#endif