xoreos  0.0.5
area.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos 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 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos 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 xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/common/scopedptr.h"
26 #include "src/common/util.h"
27 #include "src/common/error.h"
28 #include "src/common/readstream.h"
29 
30 #include "src/aurora/resman.h"
31 #include "src/aurora/gff3file.h"
32 
33 #include "src/graphics/graphics.h"
35 
37 
39 
40 #include "src/engines/jade/area.h"
45 
46 namespace Engines {
47 
48 namespace Jade {
49 
51  _module(&module), _activeObject(0), _highlightAll(false) {
52 
53  _resRef = resRef;
54 
55  try {
56  load();
57  } catch (...) {
58  clear();
59  throw;
60  }
61 
62  // Tell the module that we exist
63  _module->addObject(*this);
64 }
65 
67  _module->removeObject(*this);
68 
69  hide();
70 
71  removeFocus();
72 
73  clear();
74 }
75 
76 void Area::load() {
77  Aurora::GFF3File are(_resRef, Aurora::kFileTypeARE, MKTAG('A', 'R', 'E', ' '));
78  loadARE(are.getTopLevel());
79 
81 
82  Aurora::GFF3File sav(_resRef, Aurora::kFileTypeSAV, MKTAG('S', 'A', 'V', ' '));
83  loadSAV(sav.getTopLevel());
84 }
85 
86 void Area::clear() {
87  // Delete objects
88  for (ObjectList::iterator o = _objects.begin(); o != _objects.end(); ++o)
89  _module->removeObject(**o);
90 
91  _objects.clear();
92 
94 }
95 
96 void Area::show() {
97  if (_visible)
98  return;
99 
100  GfxMan.lockFrame();
101 
102  // Show objects
103  for (ObjectList::iterator o = _objects.begin(); o != _objects.end(); ++o) {
104  if ((*o)->isActive()) {
105  (*o)->show();
106  (*o)->runScript(kScriptOnSpawn, *o, this);
107  }
108  }
109 
110  GfxMan.unlockFrame();
111 
113 }
114 
115 void Area::hide() {
116  if (!_visible)
117  return;
118 
119  removeFocus();
120 
121  GfxMan.lockFrame();
122 
123  // Hide objects
124  for (ObjectList::iterator o = _objects.begin(); o != _objects.end(); ++o)
125  (*o)->hide();
126 
127  GfxMan.unlockFrame();
128 
130 }
131 
133  _layout = are.getString("Layout");
134 
135  // Scripts
136  readScripts(are);
137 }
138 
140  if (sav.hasField("CreatureList")) {
141  const Aurora::GFF3Struct &creatures = sav.getStruct("CreatureList");
142  loadCreatures(creatures.getList("StaticList"));
143  loadCreatures(creatures.getList("DynamicList"));
144  }
145 
146  // TODO load crowd list
147 
148  if (sav.hasField("PlaceableList")) {
149  const Aurora::GFF3Struct &placeables = sav.getStruct("PlaceableList");
150  loadPlaceables(placeables.getList("StaticList"));
151  loadPlaceables(placeables.getList("DynamicList"));
152  }
153 
154  // TODO load sound list
155 
156  if (sav.hasField("TriggerList")) {
157  const Aurora::GFF3Struct &trigger = sav.getStruct("TriggerList");
158  loadTriggers(trigger.getList("StaticList"));
159  loadTriggers(trigger.getList("DynamicList"));
160  }
161 
162  if (sav.hasField("WaypointList")) {
163  const Aurora::GFF3Struct &waypoints = sav.getStruct("WaypointList");
164  loadWaypoints(waypoints.getList("StaticList"));
165  loadWaypoints(waypoints.getList("DynamicList"));
166  }
167 
168  // TODO load projectile list
169 
170  // TODO load area of effect list
171 
172  // TODO load store list
173 
174  // TODO load apple list
175 
176  // TODO load camera list
177 }
178 
180  Common::ChangeID change;
181 
182  _resources.push_back(Common::ChangeID());
183  indexMandatoryArchive(_resRef + "/" + _layout + ".rim" , 1000, &_resources.back());
184 
185  _resources.push_back(Common::ChangeID());
186  indexMandatoryArchive(_resRef + "/" + _layout + "-a.rim", 1001, &_resources.back());
187 }
188 
189 void Area::loadObject(Object &object) {
190  _objects.push_back(&object);
191  _module->addObject(object);
192 
193  if (!object.isStatic()) {
194  const std::list<uint32> &ids = object.getIDs();
195 
196  for (std::list<uint32>::const_iterator id = ids.begin(); id != ids.end(); ++id)
197  _objectMap.insert(std::make_pair(*id, &object));
198  }
199 }
200 
202  for (Aurora::GFF3List::const_iterator w = list.begin(); w != list.end(); ++w) {
203  Waypoint *waypoint = new Waypoint(**w);
204 
205  loadObject(*waypoint);
206  }
207 }
208 
210  for (Aurora::GFF3List::const_iterator c = list.begin(); c != list.end(); ++c) {
211  Creature *creature = new Creature(**c);
212 
213  loadObject(*creature);
214  }
215 }
216 
218  for (Aurora::GFF3List::const_iterator c = list.begin(); c != list.end(); ++c) {
219  Placeable *placeable = new Placeable(**c);
220 
221  loadObject(*placeable);
222  }
223 }
224 
226  for (Aurora::GFF3List::const_iterator c = list.begin(); c != list.end(); ++c) {
227  Trigger *trigger = new Trigger(**c);
228 
229  loadObject(*trigger);
230  }
231 }
232 
233 void Area::addEvent(const Events::Event &event) {
234  _eventQueue.push_back(event);
235 }
236 
238  bool hasMove = false;
239  for (std::list<Events::Event>::const_iterator e = _eventQueue.begin();
240  e != _eventQueue.end(); ++e) {
241 
242  if (e->type == Events::kEventMouseMove) { // Moving the mouse
243  hasMove = true;
244  } else if (e->type == Events::kEventMouseDown) { // Clicking
245  if (e->button.button == SDL_BUTTON_LMASK) {
246  checkActive(e->button.x, e->button.y);
247  click(e->button.x, e->button.y);
248  }
249  } else if (e->type == Events::kEventKeyDown) { // Holding down TAB
250  if (e->key.keysym.sym == SDLK_TAB)
251  highlightAll(true);
252  } else if (e->type == Events::kEventKeyUp) { // Releasing TAB
253  if (e->key.keysym.sym == SDLK_TAB)
254  highlightAll(false);
255  }
256  }
257 
258  _eventQueue.clear();
259 
260  if (hasMove)
261  checkActive();
262 }
263 
265  const Graphics::Renderable *obj = GfxMan.getObjectAt(x, y);
266  if (!obj)
267  return 0;
268 
269  ObjectMap::iterator o = _objectMap.find(obj->getID());
270  if (o == _objectMap.end())
271  return 0;
272 
273  return o->second;
274 }
275 
277  if (object == _activeObject)
278  return;
279 
280  if (_activeObject)
281  _activeObject->leave();
282 
283  _activeObject = object;
284 
285  if (_activeObject)
286  _activeObject->enter();
287 }
288 
289 void Area::checkActive(int x, int y) {
290  if (_highlightAll)
291  return;
292 
294 
295  if ((x < 0) || (y < 0))
296  CursorMan.getPosition(x, y);
297 
298  setActive(getObjectAt(x, y));
299 }
300 
301 void Area::click(int x, int y) {
303 
304  Jade::Object *o = getObjectAt(x, y);
305  if (!o)
306  return;
307 
308  o->click(_module->getPC());
309 }
310 
311 void Area::highlightAll(bool enabled) {
312  if (_highlightAll == enabled)
313  return;
314 
315  _highlightAll = enabled;
316 
317  for (ObjectMap::iterator o = _objectMap.begin(); o != _objectMap.end(); ++o)
318  if (o->second->isClickable())
319  o->second->highlight(enabled);
320 }
321 
323  if (_activeObject)
324  _activeObject->leave();
325 
326  _activeObject = 0;
327 }
328 
330  checkActive();
331 }
332 
333 } // End of namespace Jade
334 
335 } // End of namespace Engines
Handling version V3.2/V3.3 of BioWare&#39;s GFFs (generic file format).
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
Generic Aurora engines resource utility functions.
void highlightAll(bool enabled)
Definition: area.cpp:311
The global graphics manager.
void addObject(Jade::Object &object)
Add an object to this container.
A class holding an UTF-8 string.
Definition: ustring.h:48
void loadWaypoints(const Aurora::GFF3List &list)
Definition: area.cpp:201
std::list< Common::ChangeID > _resources
The area&#39;s resource archives.
Definition: arealayout.h:71
A waypoint in a Jade Empire area.
void addEvent(const Events::Event &event)
Add a single event for consideration into the area event queue.
Definition: area.cpp:233
void processEventQueue()
Process the current event queue.
Definition: area.cpp:237
bool hasField(const Common::UString &field) const
Does this specific field exist?
Definition: gff3file.cpp:400
void loadCreatures(const Aurora::GFF3List &list)
Definition: area.cpp:209
Common::UString _layout
The area&#39;s layout resref (resource ID).
Definition: arealayout.h:69
A placeable in a Jade Empire area.
const GFF3Struct & getTopLevel() const
Returns the top-level struct.
Definition: gff3file.cpp:91
void removeObject(Jade::Object &object)
Remove an object from this container.
void setActive(Jade::Object *object)
Definition: area.cpp:276
void checkActive(int x=-1, int y=-1)
Definition: area.cpp:289
ObjectList _objects
List of all objects in the area.
Definition: area.h:90
void readScripts(const Aurora::GFF3Struct &gff)
Definition: container.cpp:91
Mouse was moved.
Definition: types.h:48
A simple scoped smart pointer template.
Creature * getPC()
Return the currently playing PC.
Definition: module.cpp:107
SDL_Event Event
Definition: types.h:42
void click(int x, int y)
Definition: area.cpp:301
void loadARE(const Aurora::GFF3Struct &are)
Definition: area.cpp:132
Mouse button was pressed.
Definition: types.h:49
std::list< Events::Event > _eventQueue
The event queue.
Definition: area.h:98
Keyboard key was pressed.
Definition: types.h:46
virtual void enter()
The cursor entered the object.
Definition: object.cpp:169
Basic exceptions to throw.
void indexMandatoryArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:36
ObjectMap _objectMap
Map of all non-static objects in the area.
Definition: area.h:91
bool _highlightAll
Are we currently highlighting all objects?
Definition: area.h:96
Game save, ERF.
Definition: types.h:123
Utility templates and functions.
Area(Module &module, const Common::UString &resRef)
Definition: area.cpp:50
Module * _module
The module this area is in.
Definition: area.h:87
A trigger in a Jade Empire area.
bool _visible
Is the area currently visible?
Definition: arealayout.h:73
A GFF (generic file format) V3.2/V3.3 file, found in all Aurora games except Sonic Chronicles: The Da...
Definition: gff3file.h:85
void loadTriggers(const Aurora::GFF3List &list)
Definition: area.cpp:225
Jade::Object * getObjectAt(int x, int y)
Definition: area.cpp:264
virtual bool click(Object *triggerer=0)
The object was clicked.
Definition: object.cpp:178
void removeFocus()
Forcibly remove the focus from the currently highlighted object.
Definition: area.cpp:322
bool isStatic() const
Is the object static (not manipulable at all)?
Definition: object.cpp:86
#define CursorMan
Shortcut for accessing the cursor manager.
Definition: cursorman.h:129
Basic reading stream interfaces.
std::vector< const GFF3Struct * > GFF3List
Definition: types.h:449
An area.
Convenience class that locks a mutex on creation and unlocks it on destruction.
Definition: mutex.h:71
An object within a Jade area.
Definition: object.h:53
The Aurora cursor manager.
A Jade module.
Definition: module.h:53
An object that can be displayed by the graphics manager.
Definition: renderable.h:42
const GFF3List & getList(const Common::UString &field) const
Definition: gff3file.cpp:741
uint32 getID() const
Get the object&#39;s unique ID.
Definition: renderable.cpp:86
Jade::Object * _activeObject
The currently active (highlighted) object.
Definition: area.h:94
void clear()
Definition: ptrlist.h:47
A struct within a GFF3.
Definition: gff3file.h:164
A class representing an undoable change.
Definition: changeid.h:35
const GFF3Struct & getStruct(const Common::UString &field) const
Definition: gff3file.cpp:728
void loadPlaceables(const Aurora::GFF3List &list)
Definition: area.cpp:217
Static area data, GFF.
Definition: types.h:81
void loadSAV(const Aurora::GFF3Struct &sav)
Definition: area.cpp:139
Common::UString getString(const Common::UString &field, const Common::UString &def="") const
Definition: gff3file.cpp:527
void loadObject(Jade::Object &object)
Definition: area.cpp:189
Common::Mutex _mutex
Mutex securing access to the area.
Definition: area.h:100
virtual void leave()
The cursor left the object.
Definition: object.cpp:172
Common::UString _resRef
The area&#39;s resref (resource ID).
Definition: arealayout.h:68
void notifyCameraMoved()
Definition: area.cpp:329
Keyboard key was released.
Definition: types.h:47
An object that can be displayed by the graphics manager.
void loadResources()
Definition: area.cpp:179
#define GfxMan
Shortcut for accessing the graphics manager.
Definition: graphics.h:299
The global resource manager for Aurora resources.
A creature in a Jade Empire area.