ScummVM API documentation
sensor.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  *
21  * Based on the original sources
22  * Faery Tale II -- The Halls of the Dead
23  * (c) 1993-1996 The Wyrmkeep Entertainment Co.
24  */
25 
26 #ifndef SAGA2_SENSOR_H
27 #define SAGA2_SENSOR_H
28 
29 namespace Saga2 {
30 
31 const uint32 kNonActorSenseFlags = kActorSeeInvis;
32 
33 //const size_t maxSensorSize = 24;
34 const size_t kMaxSensorSize = 48;
35 
36 // This constant represents the maximum sense range for an object.
37 // Zero means an infinite range.
38 const int16 kMaxSenseRange = 0;
39 
40 // Integers representing sensor types
41 enum SensorType {
42  kProtaganistSensor,
43  kSpecificObjectSensor,
44  kObjectPropertySensor,
45  kSpecificActorSensor,
46  kActorPropertySensor,
47  kEventSensor
48 };
49 
50 // Sensors will be checked every 5 frames
51 const int16 kSensorCheckRate = 5;
52 
53 /* ===================================================================== *
54  Function prototypes
55  * ===================================================================== */
56 
57 struct GameEvent;
58 
59 // Allocate a new SensorList
60 void newSensorList(SensorList *s);
61 // Deallocate a SensorList
62 void deleteSensorList(SensorList *p);
63 
64 // Fetch a specified object's SensorList
65 SensorList *fetchSensorList(GameObject *obj);
66 
67 // Allocate a new Sensor
68 void newSensor(Sensor *s);
69 // Allocate a new Sensor with a specified starting check counter
70 void newSensor(Sensor *s, int16 ctr);
71 // Deallocate a Sensor
72 void deleteSensor(Sensor *p);
73 
74 // Check all active sensors
75 void checkSensors();
76 // Evaluate an event for all active sensors
77 void assertEvent(const GameEvent &ev);
78 
79 // Initialize the sensors
80 void initSensors();
81 void saveSensors(Common::OutSaveFile *outS);
82 void loadSensors(Common::InSaveFile *in);
83 // Cleanup the active sensors
84 void cleanupSensors();
85 
86 /* ===================================================================== *
87  GameEvent struct
88  * ===================================================================== */
89 
90 struct GameEvent {
91  int16 type;
92  GameObject *directObject,
93  *indirectObject;
94 };
95 
96 /* ===================================================================== *
97  SenseInfo struct
98  * ===================================================================== */
99 
100 struct SenseInfo {
101  GameObject *sensedObject;
102 };
103 
104 /* ===================================================================== *
105  SensorList Class
106  * ===================================================================== */
107 
108 class SensorList {
109  GameObject *_obj;
110 
111 public:
113 
114 public:
115  // Constructor -- initial construction
116  SensorList(GameObject *o) : _obj(o) {
117  newSensorList(this);
118  debugC(1, kDebugSensors, "Adding SensorList %p to %d (%s) (total %d)",
119  (void *)this, o->thisID(), o->objName(), _list.size());
120  }
121 
122  ~SensorList() {
123  deleteSensorList(this);
124  debugC(1, kDebugSensors, "Deleting SensorList %p of %d (%s) (total %d)",
125  (void *)this, _obj->thisID(), _obj->objName(), _list.size());
126  }
127 
129 
130  // Return the number of bytes needed to archive this object in
131  // a buffer
132  static int32 archiveSize() {
133  return sizeof(ObjectID);
134  }
135 
136  void write(Common::MemoryWriteStreamDynamic *out);
137 
138  GameObject *getObject() {
139  return _obj;
140  }
141 };
142 
143 /* ===================================================================== *
144  Sensor Class
145  * ===================================================================== */
146 
147 class Sensor {
148 public:
149  GameObject *_obj;
150  SensorID _id;
151  int16 _range;
152 
153  int16 _checkCtr;
154  bool _active;
155 
156 public:
157  // Constructor -- initial construction
158  Sensor(GameObject *o, SensorID sensorID, int16 rng) : _obj(o), _id(sensorID), _range(rng), _active(true) {
159  newSensor(this);
160  SensorList *sl = fetchSensorList(o);
161  debugC(1, kDebugSensors, "Adding Sensor %p to %d (%s) (list = %p, total = %d)",
162  (void *)this, o->thisID(), o->objName(), (void *)sl, (sl != nullptr) ? sl->_list.size() : -1);
163  }
164 
165  Sensor(Common::InSaveFile *in, int16 ctr);
166 
167  // Virtural destructor
168  virtual ~Sensor() {
169  deleteSensor(this);
170  SensorList *sl = fetchSensorList(_obj);
171  debugC(1, kDebugSensors, "Deleting Sensor %p of %d (%s) (list = %p, total = %d)",
172  (void *)this, _obj->thisID(), _obj->objName(), (void *)sl, (sl != nullptr) ? sl->_list.size() : -1);
173  }
174 
175  virtual void write(Common::MemoryWriteStreamDynamic *out);
176 
177  // Return an integer representing the type of this sensor
178  virtual int16 getType() = 0;
179 
180  GameObject *getObject() {
181  return _obj;
182  }
183  SensorID thisID() {
184  return _id;
185  }
186  int16 getRange() {
187  return _range;
188  }
189 
190  // Determine if the object can sense what it's looking for
191  virtual bool check(SenseInfo &info, uint32 senseFlags) = 0;
192 
193  // Evaluate an event to determine if the object is waiting for it
194  virtual bool evaluateEvent(const GameEvent &event) = 0;
195 };
196 
197 /* ===================================================================== *
198  ProtaganistSensor Class
199  * ===================================================================== */
200 
201 class ProtaganistSensor : public Sensor {
202 public:
203  // Constructor -- initial construction
204  ProtaganistSensor(GameObject *o, SensorID sensorID, int16 rng) :
205  Sensor(o, sensorID, rng) {
206  }
207 
208  ProtaganistSensor(Common::InSaveFile *in, int16 ctr) : Sensor(in, ctr) {
209  debugC(3, kDebugSaveload, "Loading ProtagonistSensor");
210  }
211 
212  // Return an integer representing the type of this sensor
213  int16 getType();
214 
215  // Determine if the object can sense what it's looking for
216  bool check(SenseInfo &info, uint32 senseFlags);
217 
218  // Evaluate an event to determine if the object is waiting for it
219  bool evaluateEvent(const GameEvent &event);
220 };
221 
222 /* ===================================================================== *
223  ObjectSensor Class
224  * ===================================================================== */
225 
226 class ObjectSensor : public Sensor {
227 public:
228  // Constructor -- initial construction
229  ObjectSensor(GameObject *o, SensorID sensorID, int16 rng) :
230  Sensor(o, sensorID, rng) {
231  }
232 
233  ObjectSensor(Common::InSaveFile *in, int16 ctr) : Sensor(in, ctr) {}
234 
235  // Determine if the object can sense what it's looking for
236  bool check(SenseInfo &info, uint32 senseFlags);
237 
238  // Evaluate an event to determine if the object is waiting for it
239  bool evaluateEvent(const GameEvent &event);
240 
241 private:
242  // Determine if an object meets the search criteria
243  virtual bool isObjectSought(GameObject *obj) = 0;
244 };
245 
246 /* ===================================================================== *
247  SpecificObjectSensor Class
248  * ===================================================================== */
249 
251  ObjectID _soughtObjID;
252 
253 public:
254  // Constructor -- initial construction
256  GameObject *o,
257  SensorID sensorID,
258  int16 rng,
259  ObjectID objToSense) :
260  ObjectSensor(o, sensorID, rng),
261  _soughtObjID(objToSense) {
262  }
263 
265 
266  // Return the number of bytes needed to archive this object in
267  // a buffer
268  int32 archiveSize();
269 
270  void write(Common::MemoryWriteStreamDynamic *out);
271 
272  // Return an integer representing the type of this sensor
273  int16 getType();
274 
275  // Determine if the object can sense what it's looking for
276  bool check(SenseInfo &info, uint32 senseFlags);
277 
278 private:
279  // Determine if an object meets the search criteria
280  bool isObjectSought(GameObject *obj);
281 };
282 
283 /* ===================================================================== *
284  ObjectPropertySensor Class
285  * ===================================================================== */
286 
288  ObjectPropertyID _objectProperty;
289 
290 public:
291  // Constructor -- initial construction
293  GameObject *o,
294  SensorID sensorID,
295  int16 rng,
296  ObjectPropertyID propToSense) :
297  ObjectSensor(o, sensorID, rng),
298  _objectProperty(propToSense) {
299  }
300 
302 
303  // Return the number of bytes needed to archive this object in
304  // a buffer
305  int32 archiveSize();
306 
307  void write(Common::MemoryWriteStreamDynamic *out);
308 
309  // Return an integer representing the type of this sensor
310  int16 getType();
311 
312 private:
313  // Determine if an object meets the search criteria
314  bool isObjectSought(GameObject *obj);
315 };
316 
317 /* ===================================================================== *
318  ActorSensor Class
319  * ===================================================================== */
320 
321 class ActorSensor : public ObjectSensor {
322 public:
323  // Constructor -- initial construction
324  ActorSensor(GameObject *o, SensorID sensorID, int16 rng) :
325  ObjectSensor(o, sensorID, rng) {
326  }
327 
328  ActorSensor(Common::InSaveFile *in, int16 ctr) : ObjectSensor(in, ctr) {}
329 
330 private:
331  // Determine if an object meets the search criteria
332  bool isObjectSought(GameObject *obj);
333 
334  // Determine if an actor meets the search criteria
335  virtual bool isActorSought(Actor *a) = 0;
336 };
337 
338 /* ===================================================================== *
339  SpecificActorSensor Class
340  * ===================================================================== */
341 
343  Actor *_soughtActor;
344 
345 public:
346  // Constructor -- initial construction
348  GameObject *o,
349  SensorID sensorID,
350  int16 rng,
351  Actor *actorToSense) :
352  ActorSensor(o, sensorID, rng),
353  _soughtActor(actorToSense) {
354  }
355 
356  SpecificActorSensor(Common::InSaveFile *in, int16 ctr);
357 
358  // Return the number of bytes needed to archive this object in
359  // a buffer
360  int32 archiveSize();
361 
362  void write(Common::MemoryWriteStreamDynamic *out);
363 
364  // Return an integer representing the type of this sensor
365  int16 getType();
366 
367  // Determine if the object can sense what it's looking for
368  bool check(SenseInfo &info, uint32 senseFlags);
369 
370 private:
371  // Determine if an actor meets the search criteria
372  bool isActorSought(Actor *a);
373 };
374 
375 /* ===================================================================== *
376  ActorPropertySensor Class
377  * ===================================================================== */
378 
380  ActorPropertyID _actorProperty;
381 
382 public:
383  // Constructor -- initial construction
385  GameObject *o,
386  SensorID sensorID,
387  int16 rng,
388  ActorPropertyID propToSense) :
389  ActorSensor(o, sensorID, rng),
390  _actorProperty(propToSense) {
391  }
392 
393  ActorPropertySensor(Common::InSaveFile *in, int16 ctr);
394 
395  // Return the number of bytes needed to archive this object in
396  // a buffer
397  int32 archiveSize();
398 
399  void write(Common::MemoryWriteStreamDynamic *out);
400 
401  // Return an integer representing the type of this sensor
402  int16 getType();
403 
404 private:
405  // Determine if an actor meets the search criteria
406  bool isActorSought(Actor *a);
407 };
408 
409 /* ===================================================================== *
410  EventSensor Class
411  * ===================================================================== */
412 
413 class EventSensor : public Sensor {
414  int16 _eventType;
415 
416 public:
417  // Constructor -- initial construction
418  EventSensor(
419  GameObject *o,
420  SensorID sensorID,
421  int16 rng,
422  int16 type);
423 
424  EventSensor(Common::InSaveFile *in, int16 ctr);
425 
426  // Return the number of bytes needed to archive this object in
427  // a buffer
428  int32 archiveSize();
429 
430  void write(Common::MemoryWriteStreamDynamic *out);
431 
432  // Return an integer representing the type of this sensor
433  int16 getType();
434 
435  // Determine if the object can sense what it's looking for
436  bool check(SenseInfo &info, uint32 senseFlags);
437 
438  // Evaluate an event to determine if the object is waiting for it
439  bool evaluateEvent(const GameEvent &event);
440 };
441 
442 } // end of namespace Saga2
443 
444 #endif
Definition: sensor.h:413
Definition: sensor.h:250
Definition: savefile.h:54
Definition: sensor.h:201
Definition: actor.h:32
Definition: list.h:44
size_type size() const
Definition: list.h:198
Definition: memstream.h:194
Definition: sensor.h:90
Definition: stream.h:745
Definition: sensor.h:100
Definition: actor.h:589
Definition: sensor.h:342
Definition: sensor.h:287
Definition: sensor.h:321
Definition: sensor.h:147
Definition: objects.h:118
Definition: sensor.h:108
Definition: sensor.h:226
Definition: sensor.h:379
void void void void void debugC(int level, uint32 debugChannels, MSVC_PRINTF const char *s,...) GCC_PRINTF(3