scummvm/engines/saga2/sensor.h

445 lines
12 KiB
C
Raw Normal View History

2021-05-17 18:47:39 +00:00
/* 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.
2021-05-17 18:47:39 +00:00
*
* 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/>.
2021-05-17 18:47:39 +00:00
*
*
* Based on the original sources
* Faery Tale II -- The Halls of the Dead
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
*/
#ifndef SAGA2_SENSOR_H
#define SAGA2_SENSOR_H
namespace Saga2 {
const uint32 kNonActorSenseFlags = kActorSeeInvis;
2021-05-17 18:47:39 +00:00
2021-06-04 18:12:34 +00:00
//const size_t maxSensorSize = 24;
const size_t kMaxSensorSize = 48;
2021-05-17 18:47:39 +00:00
// This constant represents the maximum sense range for an object.
// Zero means an infinite range.
const int16 kMaxSenseRange = 0;
2021-05-17 18:47:39 +00:00
// Integers representing sensor types
enum SensorType {
kProtaganistSensor,
kSpecificObjectSensor,
kObjectPropertySensor,
kSpecificActorSensor,
kActorPropertySensor,
kEventSensor
2021-05-17 18:47:39 +00:00
};
// Sensors will be checked every 5 frames
const int16 kSensorCheckRate = 5;
2021-05-17 18:47:39 +00:00
/* ===================================================================== *
Function prototypes
* ===================================================================== */
struct GameEvent;
// Allocate a new SensorList
void newSensorList(SensorList *s);
// Deallocate a SensorList
void deleteSensorList(SensorList *p);
2021-05-17 18:47:39 +00:00
// Fetch a specified object's SensorList
SensorList *fetchSensorList(GameObject *obj);
// Allocate a new Sensor
void newSensor(Sensor *s);
2021-05-17 18:47:39 +00:00
// Allocate a new Sensor with a specified starting check counter
void newSensor(Sensor *s, int16 ctr);
2021-05-17 18:47:39 +00:00
// Deallocate a Sensor
void deleteSensor(Sensor *p);
2021-05-17 18:47:39 +00:00
// Check all active sensors
2021-09-11 09:13:35 +00:00
void checkSensors();
2021-05-17 18:47:39 +00:00
// Evaluate an event for all active sensors
void assertEvent(const GameEvent &ev);
// Initialize the sensors
2021-09-11 09:13:35 +00:00
void initSensors();
2021-07-15 14:42:53 +00:00
void saveSensors(Common::OutSaveFile *outS);
2021-07-11 21:25:37 +00:00
void loadSensors(Common::InSaveFile *in);
2021-05-17 18:47:39 +00:00
// Cleanup the active sensors
2021-09-11 09:13:35 +00:00
void cleanupSensors();
2021-05-17 18:47:39 +00:00
/* ===================================================================== *
GameEvent struct
* ===================================================================== */
struct GameEvent {
int16 type;
GameObject *directObject,
*indirectObject;
};
/* ===================================================================== *
SenseInfo struct
* ===================================================================== */
struct SenseInfo {
GameObject *sensedObject;
};
/* ===================================================================== *
SensorList Class
* ===================================================================== */
class SensorList {
GameObject *_obj;
public:
Common::List<Sensor *> _list;
2021-05-17 18:47:39 +00:00
public:
// Constructor -- initial construction
SensorList(GameObject *o) : _obj(o) {
newSensorList(this);
2021-07-19 08:43:20 +00:00
debugC(1, kDebugSensors, "Adding SensorList %p to %d (%s) (total %d)",
(void *)this, o->thisID(), o->objName(), _list.size());
}
~SensorList() {
deleteSensorList(this);
2021-07-19 08:43:20 +00:00
debugC(1, kDebugSensors, "Deleting SensorList %p of %d (%s) (total %d)",
(void *)this, _obj->thisID(), _obj->objName(), _list.size());
}
2021-05-17 18:47:39 +00:00
2021-07-11 21:25:37 +00:00
SensorList(Common::InSaveFile *in);
2021-05-17 18:47:39 +00:00
// Return the number of bytes needed to archive this object in
// a buffer
2021-09-11 09:13:35 +00:00
static int32 archiveSize() {
2021-05-17 18:47:39 +00:00
return sizeof(ObjectID);
}
2021-07-15 14:42:53 +00:00
void write(Common::MemoryWriteStreamDynamic *out);
2021-07-11 21:25:37 +00:00
2021-09-11 09:13:35 +00:00
GameObject *getObject() {
return _obj;
2021-05-17 18:47:39 +00:00
}
};
/* ===================================================================== *
Sensor Class
* ===================================================================== */
class Sensor {
public:
GameObject *_obj;
SensorID _id;
int16 _range;
2021-05-17 18:47:39 +00:00
int16 _checkCtr;
2021-07-19 08:43:20 +00:00
bool _active;
2021-05-17 18:47:39 +00:00
public:
// Constructor -- initial construction
Sensor(GameObject *o, SensorID sensorID, int16 rng) : _obj(o), _id(sensorID), _range(rng), _active(true) {
newSensor(this);
2021-07-19 08:43:20 +00:00
SensorList *sl = fetchSensorList(o);
debugC(1, kDebugSensors, "Adding Sensor %p to %d (%s) (list = %p, total = %d)",
(void *)this, o->thisID(), o->objName(), (void *)sl, (sl != nullptr) ? sl->_list.size() : -1);
2021-05-17 18:47:39 +00:00
}
2021-07-11 21:25:37 +00:00
Sensor(Common::InSaveFile *in, int16 ctr);
2021-05-17 18:47:39 +00:00
// Virtural destructor
2021-09-11 09:13:35 +00:00
virtual ~Sensor() {
deleteSensor(this);
SensorList *sl = fetchSensorList(_obj);
2021-07-19 08:43:20 +00:00
debugC(1, kDebugSensors, "Deleting Sensor %p of %d (%s) (list = %p, total = %d)",
(void *)this, _obj->thisID(), _obj->objName(), (void *)sl, (sl != nullptr) ? sl->_list.size() : -1);
}
2021-05-17 18:47:39 +00:00
2021-07-15 14:42:53 +00:00
virtual void write(Common::MemoryWriteStreamDynamic *out);
2021-07-11 21:25:37 +00:00
2021-05-17 18:47:39 +00:00
// Return an integer representing the type of this sensor
2021-09-11 09:13:35 +00:00
virtual int16 getType() = 0;
2021-05-17 18:47:39 +00:00
2021-09-11 09:13:35 +00:00
GameObject *getObject() {
return _obj;
2021-05-17 18:47:39 +00:00
}
2021-09-11 09:13:35 +00:00
SensorID thisID() {
return _id;
2021-05-17 18:47:39 +00:00
}
2021-09-11 09:13:35 +00:00
int16 getRange() {
return _range;
2021-05-17 18:47:39 +00:00
}
// Determine if the object can sense what it's looking for
virtual bool check(SenseInfo &info, uint32 senseFlags) = 0;
// Evaluate an event to determine if the object is waiting for it
virtual bool evaluateEvent(const GameEvent &event) = 0;
};
/* ===================================================================== *
ProtaganistSensor Class
* ===================================================================== */
class ProtaganistSensor : public Sensor {
public:
// Constructor -- initial construction
ProtaganistSensor(GameObject *o, SensorID sensorID, int16 rng) :
Sensor(o, sensorID, rng) {
}
2021-07-11 21:25:37 +00:00
ProtaganistSensor(Common::InSaveFile *in, int16 ctr) : Sensor(in, ctr) {
debugC(3, kDebugSaveload, "Loading ProtagonistSensor");
}
2021-05-17 18:47:39 +00:00
// Return an integer representing the type of this sensor
2021-09-11 09:13:35 +00:00
int16 getType();
2021-05-17 18:47:39 +00:00
// Determine if the object can sense what it's looking for
bool check(SenseInfo &info, uint32 senseFlags);
// Evaluate an event to determine if the object is waiting for it
bool evaluateEvent(const GameEvent &event);
};
/* ===================================================================== *
ObjectSensor Class
* ===================================================================== */
class ObjectSensor : public Sensor {
public:
// Constructor -- initial construction
ObjectSensor(GameObject *o, SensorID sensorID, int16 rng) :
Sensor(o, sensorID, rng) {
}
2021-07-11 21:25:37 +00:00
ObjectSensor(Common::InSaveFile *in, int16 ctr) : Sensor(in, ctr) {}
2021-05-17 18:47:39 +00:00
// Determine if the object can sense what it's looking for
bool check(SenseInfo &info, uint32 senseFlags);
// Evaluate an event to determine if the object is waiting for it
bool evaluateEvent(const GameEvent &event);
private:
// Determine if an object meets the search criteria
virtual bool isObjectSought(GameObject *obj) = 0;
};
/* ===================================================================== *
SpecificObjectSensor Class
* ===================================================================== */
class SpecificObjectSensor : public ObjectSensor {
ObjectID _soughtObjID;
2021-05-17 18:47:39 +00:00
public:
// Constructor -- initial construction
SpecificObjectSensor(
GameObject *o,
SensorID sensorID,
int16 rng,
ObjectID objToSense) :
ObjectSensor(o, sensorID, rng),
_soughtObjID(objToSense) {
2021-05-17 18:47:39 +00:00
}
2021-07-11 21:25:37 +00:00
SpecificObjectSensor(Common::InSaveFile *in, int16 ctr);
2021-05-17 18:47:39 +00:00
// Return the number of bytes needed to archive this object in
// a buffer
2021-09-11 09:13:35 +00:00
int32 archiveSize();
2021-05-17 18:47:39 +00:00
2021-07-15 14:42:53 +00:00
void write(Common::MemoryWriteStreamDynamic *out);
2021-07-11 21:25:37 +00:00
2021-05-17 18:47:39 +00:00
// Return an integer representing the type of this sensor
2021-09-11 09:13:35 +00:00
int16 getType();
2021-05-17 18:47:39 +00:00
// Determine if the object can sense what it's looking for
bool check(SenseInfo &info, uint32 senseFlags);
private:
// Determine if an object meets the search criteria
bool isObjectSought(GameObject *obj);
};
/* ===================================================================== *
ObjectPropertySensor Class
* ===================================================================== */
class ObjectPropertySensor : public ObjectSensor {
ObjectPropertyID _objectProperty;
2021-05-17 18:47:39 +00:00
public:
// Constructor -- initial construction
ObjectPropertySensor(
GameObject *o,
SensorID sensorID,
int16 rng,
ObjectPropertyID propToSense) :
ObjectSensor(o, sensorID, rng),
_objectProperty(propToSense) {
2021-05-17 18:47:39 +00:00
}
2021-07-11 21:25:37 +00:00
ObjectPropertySensor(Common::InSaveFile *in, int16 ctr);
2021-05-17 18:47:39 +00:00
// Return the number of bytes needed to archive this object in
// a buffer
2021-09-11 09:13:35 +00:00
int32 archiveSize();
2021-05-17 18:47:39 +00:00
2021-07-15 14:42:53 +00:00
void write(Common::MemoryWriteStreamDynamic *out);
2021-07-11 21:25:37 +00:00
2021-05-17 18:47:39 +00:00
// Return an integer representing the type of this sensor
2021-09-11 09:13:35 +00:00
int16 getType();
2021-05-17 18:47:39 +00:00
private:
// Determine if an object meets the search criteria
bool isObjectSought(GameObject *obj);
};
/* ===================================================================== *
ActorSensor Class
* ===================================================================== */
class ActorSensor : public ObjectSensor {
public:
// Constructor -- initial construction
ActorSensor(GameObject *o, SensorID sensorID, int16 rng) :
ObjectSensor(o, sensorID, rng) {
}
2021-07-11 21:25:37 +00:00
ActorSensor(Common::InSaveFile *in, int16 ctr) : ObjectSensor(in, ctr) {}
2021-05-17 18:47:39 +00:00
private:
// Determine if an object meets the search criteria
bool isObjectSought(GameObject *obj);
// Determine if an actor meets the search criteria
virtual bool isActorSought(Actor *a) = 0;
};
/* ===================================================================== *
SpecificActorSensor Class
* ===================================================================== */
class SpecificActorSensor : public ActorSensor {
Actor *_soughtActor;
2021-05-17 18:47:39 +00:00
public:
// Constructor -- initial construction
SpecificActorSensor(
GameObject *o,
SensorID sensorID,
int16 rng,
Actor *actorToSense) :
ActorSensor(o, sensorID, rng),
_soughtActor(actorToSense) {
2021-05-17 18:47:39 +00:00
}
2021-07-11 21:25:37 +00:00
SpecificActorSensor(Common::InSaveFile *in, int16 ctr);
2021-05-17 18:47:39 +00:00
// Return the number of bytes needed to archive this object in
// a buffer
2021-09-11 09:13:35 +00:00
int32 archiveSize();
2021-05-17 18:47:39 +00:00
2021-07-15 14:42:53 +00:00
void write(Common::MemoryWriteStreamDynamic *out);
2021-07-11 21:25:37 +00:00
2021-05-17 18:47:39 +00:00
// Return an integer representing the type of this sensor
2021-09-11 09:13:35 +00:00
int16 getType();
2021-05-17 18:47:39 +00:00
// Determine if the object can sense what it's looking for
bool check(SenseInfo &info, uint32 senseFlags);
private:
// Determine if an actor meets the search criteria
bool isActorSought(Actor *a);
};
/* ===================================================================== *
ActorPropertySensor Class
* ===================================================================== */
class ActorPropertySensor : public ActorSensor {
ActorPropertyID _actorProperty;
2021-05-17 18:47:39 +00:00
public:
// Constructor -- initial construction
ActorPropertySensor(
GameObject *o,
SensorID sensorID,
int16 rng,
ActorPropertyID propToSense) :
ActorSensor(o, sensorID, rng),
_actorProperty(propToSense) {
2021-05-17 18:47:39 +00:00
}
2021-07-11 21:25:37 +00:00
ActorPropertySensor(Common::InSaveFile *in, int16 ctr);
2021-05-17 18:47:39 +00:00
// Return the number of bytes needed to archive this object in
// a buffer
2021-09-11 09:13:35 +00:00
int32 archiveSize();
2021-05-17 18:47:39 +00:00
2021-07-15 14:42:53 +00:00
void write(Common::MemoryWriteStreamDynamic *out);
2021-07-11 21:25:37 +00:00
2021-05-17 18:47:39 +00:00
// Return an integer representing the type of this sensor
2021-09-11 09:13:35 +00:00
int16 getType();
2021-05-17 18:47:39 +00:00
private:
// Determine if an actor meets the search criteria
bool isActorSought(Actor *a);
};
/* ===================================================================== *
EventSensor Class
* ===================================================================== */
class EventSensor : public Sensor {
int16 _eventType;
2021-05-17 18:47:39 +00:00
public:
// Constructor -- initial construction
EventSensor(
GameObject *o,
SensorID sensorID,
int16 rng,
int16 type);
2021-07-11 21:25:37 +00:00
EventSensor(Common::InSaveFile *in, int16 ctr);
2021-05-17 18:47:39 +00:00
// Return the number of bytes needed to archive this object in
// a buffer
2021-09-11 09:13:35 +00:00
int32 archiveSize();
2021-05-17 18:47:39 +00:00
2021-07-15 14:42:53 +00:00
void write(Common::MemoryWriteStreamDynamic *out);
2021-07-11 21:25:37 +00:00
2021-05-17 18:47:39 +00:00
// Return an integer representing the type of this sensor
2021-09-11 09:13:35 +00:00
int16 getType();
2021-05-17 18:47:39 +00:00
// Determine if the object can sense what it's looking for
bool check(SenseInfo &info, uint32 senseFlags);
// Evaluate an event to determine if the object is waiting for it
bool evaluateEvent(const GameEvent &event);
};
} // end of namespace Saga2
#endif