xoreos  0.0.5
module.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/util.h"
26 #include "src/common/maths.h"
27 #include "src/common/error.h"
28 #include "src/common/configman.h"
29 #include "src/common/filepath.h"
30 #include "src/common/readfile.h"
31 #include "src/common/md5.h"
32 
33 #include "src/events/events.h"
34 
35 #include "src/aurora/2dareg.h"
36 #include "src/aurora/language.h"
37 #include "src/aurora/talkman.h"
38 #include "src/aurora/erffile.h"
39 #include "src/aurora/resman.h"
40 
41 #include "src/graphics/camera.h"
42 
45 
50 
51 #include "src/engines/nwn/types.h"
53 #include "src/engines/nwn/module.h"
54 #include "src/engines/nwn/game.h"
55 #include "src/engines/nwn/area.h"
57 
59 
60 struct GenderToken {
61  const char *token;
64 };
65 
66 static const GenderToken kGenderTokens[] = {
67  {"<Male/Female>" , 156, 157},
68  {"<male/female>" , 4924, 4925},
69  {"<Boy/Girl>" , 4860, 4861},
70  {"<boy/girl>" , 4862, 4863},
71  {"<Brother/Sister>" , 4864, 4865},
72  {"<brother/sister>" , 4866, 4867},
73  {"<He/She>" , 4869, 4870},
74  {"<he/she>" , 4871, 4872},
75  {"<Him/Her>" , 4873, 4874},
76  {"<him/her>" , 4875, 4876},
77  {"<His/Her>" , 4877, 4874},
78  {"<his/her>" , 4878, 4876},
79  {"<His/Hers>" , 4877, 4879},
80  {"<his/hers>" , 4878, 4880},
81  {"<Lad/Lass>" , 4881, 4882},
82  {"<lad/lass>" , 4883, 4884},
83  {"<Lord/Lady>" , 4885, 4886},
84  {"<lord/lady>" , 4887, 4888},
85  {"<Man/Woman>" , 4926, 4927},
86  {"<man/woman>" , 4928, 4929},
87  {"<Master/Mistress>", 4930, 4931},
88  {"<master/mistress>", 4932, 4933},
89  {"<Mister/Missus>" , 4934, 4935},
90  {"<mister/missus>" , 4936, 4937},
91  {"<Sir/Madam>" , 4939, 4940},
92  {"<sir/madam>" , 4941, 4942},
93  {"<bitch/bastard>" , 1757, 1739}
94 };
95 
96 namespace Engines {
97 
98 namespace NWN {
99 
100 bool Module::Action::operator<(const Action &s) const {
101  return timestamp < s.timestamp;
102 }
103 
104 
106  _console(&console), _gameVersion(&gameVersion), _hasModule(false),
107  _running(false), _currentTexturePack(-1), _exit(false), _currentArea(0) {
108 
109  _ingameGUI.reset(new IngameGUI(*this, _console));
110 }
111 
113  try {
114  clear();
115  } catch (...) {
116  }
117 }
118 
120  return *_gameVersion;
121 }
122 
124  unload();
125 }
126 
127 void Module::load(const Common::UString &module) {
128  if (isRunning()) {
129  // We are currently running a module. Schedule a safe change instead
130 
131  _ingameGUI->abortMain();
132  changeModule(module);
133  return;
134  }
135 
136  // We are not currently running a module. Directly load the new module
137  loadModule(module);
138 }
139 
141  if (!Game::isPremiumModule(module))
142  return;
143 
144  try {
145  /* If this is a premium module, we need to calculate the MD5 sum of this
146  * module file, and then load the main HAK for this module, using the
147  * MD5 has part of the decryption password. This has to be done before
148  * loading the IFO, because the HAK comes with the proper IFO. The one
149  * in the module is a stub that exists the game, assuming you haven't
150  * purchased the premium module in question. */
151 
152  Common::ReadFile mod(ResMan.findResourceFile(module));
153 
154  std::vector<byte> md5;
155  Common::hashMD5(mod, md5);
156 
158  } catch (...) {
159  }
160 }
161 
162 void Module::loadModule(const Common::UString &module) {
163  unload(false);
164 
165  if (module.empty())
166  throw Common::Exception("Tried to load an empty module");
167 
168  try {
169  indexMandatoryArchive(module, 1000, &_resModule);
170  preparePremiumModule(module);
171 
172  _ifo.load(true);
173 
174  if (_ifo.isSave())
175  throw Common::Exception("This is a save");
176 
177  checkXPs();
178  checkHAKs();
179 
180  _tag = _ifo.getTag();
181  _name = _ifo.getName().getString();
182 
183  readScripts(*_ifo.getGFF());
184 
185  } catch (Common::Exception &e) {
186  e.add("Can't load module \"%s\"", module.c_str());
187  throw e;
188  }
189 
190  _newModule.clear();
191 
192  _hasModule = true;
193 }
194 
196  uint16 hasXP = 0;
197 
198  hasXP |= ConfigMan.getBool("NWN_hasXP1") ? 1 : 0;
199  hasXP |= ConfigMan.getBool("NWN_hasXP2") ? 2 : 0;
200  hasXP |= ConfigMan.getBool("NWN_hasXP3") ? 4 : 0;
201 
202  uint16 xp = _ifo.getExpansions();
203 
204  for (int i = 0; i < 16; i++, xp >>= 1, hasXP >>= 1)
205  if ((xp & 1) && !(hasXP & 1))
206  throw Common::Exception("Module requires expansion %d and we don't have it", i + 1);
207 }
208 
210  const std::vector<Common::UString> &haks = _ifo.getHAKs();
211 
212  for (std::vector<Common::UString>::const_iterator h = haks.begin(); h != haks.end(); ++h)
213  if (!ResMan.hasArchive(*h + ".hak"))
214  throw Common::Exception("Required hak \"%s\" does not exist", h->c_str());
215 }
216 
218  TokenMan.set("<FullName>" , _pc->getName());
219  TokenMan.set("<FirstName>", _pc->getFirstName());
220  TokenMan.set("<LastName>" , _pc->getLastName());
221 
222  TokenMan.set("<Race>" , _pc->getConvRace());
223  TokenMan.set("<race>" , _pc->getConvrace());
224  TokenMan.set("<Races>", _pc->getConvRaces());
225 
226  TokenMan.set("<Subrace>", _pc->getSubRace());
227 
228  TokenMan.set("<Class>" , _pc->getConvClass());
229  TokenMan.set("<class>" , _pc->getConvclass());
230  TokenMan.set("<Classes>", _pc->getConvClasses());
231 
232  TokenMan.set("<Deity>", _pc->getDeity());
233 
234  for (size_t i = 0; i < ARRAYSIZE(kGenderTokens); i++) {
235  const uint32 strRef = _pc->isFemale() ? kGenderTokens[i].female : kGenderTokens[i].male;
236 
237  TokenMan.set(kGenderTokens[i].token, TalkMan.getString(strRef));
238  }
239 
240  // TODO: <Level>
241  // TODO: <Alignment>, <alignment>
242  // TODO: <Good/Evil>, <good/evil>
243  // TODO: <Lawful/Chaotic>, <lawful/chaotic>, <Law/Chaos>, <law/chaos>,
244  // TODO: <GameTime>. <GameYear>, <Day/Night>, <day/night>, <QuarterDay>, <quarterday>
245 }
246 
248  TokenMan.remove("<FullName>");
249  TokenMan.remove("<FirstName>");
250  TokenMan.remove("<LastName>");
251 
252  TokenMan.remove("<Race>");
253  TokenMan.remove("<race>");
254  TokenMan.remove("<Races>");
255 
256  TokenMan.remove("<Subrace>");
257 
258  TokenMan.remove("<Class>");
259  TokenMan.remove("<class>");
260  TokenMan.remove("<Classes>");
261 
262  TokenMan.remove("<Deity>");
263 
264  for (size_t i = 0; i < ARRAYSIZE(kGenderTokens); i++)
265  TokenMan.remove(kGenderTokens[i].token);
266 }
267 
268 void Module::usePC(const Common::UString &bic, bool local) {
269  unloadPC();
270 
271  if (bic.empty())
272  throw Common::Exception("Tried to load an empty PC");
273 
274  try {
275  _pc.reset(new Creature(bic, local));
276  } catch (Common::Exception &e) {
277  e.add("Can't load PC \"%s\"", bic.c_str());
278  throw e;
279  }
280 
281  setPCTokens();
282  LangMan.setCurrentGender(_pc->isFemale() ? Aurora::kLanguageGenderFemale : Aurora::kLanguageGenderMale);
283 
284  addObject(*_pc);
285 }
286 
287 void Module::usePC(Creature *creature) {
288  unloadPC();
289 
290  _pc.reset(creature);
291 
292  setPCTokens();
293  LangMan.setCurrentGender(_pc->isFemale() ? Aurora::kLanguageGenderFemale : Aurora::kLanguageGenderMale);
294 
295  addObject(*_pc);
296 }
297 
299  return _pc.get();
300 }
301 
303  _newModule = module;
304 }
305 
307  if (_newModule.empty())
308  return;
309 
310  _console->hide();
311 
312  Common::UString newModule = _newModule;
313 
314  unload(false);
315 
316  _exit = true;
317 
318  loadModule(newModule);
319  enter();
320 }
321 
323  if (!_hasModule)
324  throw Common::Exception("Module::enter(): Lacking a module?!?");
325 
326  if (!_pc)
327  throw Common::Exception("Module::enter(): Lacking a PC?!?");
328 
329  _pc->clearVariables();
330 
331  loadTexturePack();
332 
333  _console->printf("Entering module \"%s\" with character \"%s\"",
334  _ifo.getName().getString().c_str(), _pc->getName().c_str());
335 
336  _ingameGUI->updatePartyMember(0, *_pc);
337 
338  try {
339 
340  loadTLK();
341  loadHAKs();
342  loadAreas();
343 
344  } catch (Common::Exception &e) {
345  e.add("Can't initialize module \"%s\"", _ifo.getName().getString().c_str());
346  throw e;
347  }
348 
349  float entryX, entryY, entryZ, entryDirX, entryDirY;
350  _ifo.getEntryPosition(entryX, entryY, entryZ);
351  _ifo.getEntryDirection(entryDirX, entryDirY);
352 
353  const float entryAngle = -Common::rad2deg(atan2(entryDirX, entryDirY));
354 
355  _pc->setPosition(entryX, entryY, entryZ);
356  _pc->setOrientation(0.0f, 0.0f, 1.0f, entryAngle);
357 
358  _pc->loadModel();
359 
360  _running = true;
361  _exit = false;
362 
363  runScript(kScriptModuleLoad , this, _pc.get());
364  runScript(kScriptModuleStart, this, _pc.get());
365  runScript(kScriptEnter , this, _pc.get());
366 
367  // The entry scripts might have already determined that we should quit
368  if (_exit)
369  return;
370 
371  Common::UString startMovie = _ifo.getStartMovie();
372  if (!startMovie.empty())
373  playVideo(startMovie);
374 
376 
377  CameraMan.reset();
378 
379  // Roughly head position
380  CameraMan.setPosition(entryX, entryY, entryZ + 1.8f);
381  CameraMan.setOrientation(90.0f, 0.0f, entryAngle);
382  CameraMan.update();
383 
384  _ingameGUI->show();
385 
386  GfxMan.resumeAnimations();
387 }
388 
390  _ingameGUI->stopConversation();
391  _ingameGUI->hide();
392 
393  _running = false;
394  _exit = true;
395 }
396 
399  return;
400 
401  _ingameGUI->stopConversation();
402 
403  if (_currentArea) {
404  _pc->hide();
405 
407  _currentArea->hide();
408 
409  _currentArea = 0;
410  }
411 
412  if (_newArea.empty()) {
413  _exit = true;
414  return;
415  }
416 
417  AreaMap::iterator area = _areas.find(_newArea);
418  if (area == _areas.end() || !area->second) {
419  warning("Failed entering area \"%s\": No such area", _newArea.c_str());
420  _exit = true;
421  return;
422  }
423 
424  _currentArea = area->second;
425 
426  _currentArea->show();
427  _pc->show();
428 
429  EventMan.flushEvents();
430 
431  _ingameGUI->setArea(_currentArea->getName());
432 
433  _pc->setArea(_currentArea);
434 
436 
437  _console->printf("Entering area \"%s\"", _currentArea->getResRef().c_str());
438 }
439 
440 void Module::exit() {
441  _ingameGUI->abortMain();
442 
443  _exit = true;
444 }
445 
446 bool Module::isLoaded() const {
447  return _hasModule && _pc;
448 }
449 
450 bool Module::isRunning() const {
451  return !EventMan.quitRequested() && _running && !_exit && !_newArea.empty();
452 }
453 
454 void Module::addEvent(const Events::Event &event) {
455  _eventQueue.push_back(event);
456 }
457 
459  if (!isRunning())
460  return;
461 
462  replaceModule();
463  enterArea();
464 
465  if (!isRunning())
466  return;
467 
468  handleEvents();
469  handleActions();
470 
471  _ingameGUI->updatePartyMember(0, *_pc);
472 }
473 
475  for (EventQueue::const_iterator event = _eventQueue.begin(); event != _eventQueue.end(); ++event) {
476  // Handle console
477  if (_console->isVisible()) {
478  _console->processEvent(*event);
479  continue;
480  }
481 
482  if (event->type == Events::kEventKeyDown) {
483  // Menu
484  if (event->key.keysym.sym == SDLK_ESCAPE) {
485  // But only if we're not in a conversation, where ESC should abort that
486  if (!_ingameGUI->hasRunningConversation()) {
487  showMenu();
488  continue;
489  }
490  }
491 
492  // Console
493  if ((event->key.keysym.sym == SDLK_d) && (event->key.keysym.mod & KMOD_CTRL)) {
494  _console->show();
495  continue;
496  }
497  }
498 
499  // Camera
500  if (!_console->isVisible())
501  if (FreeRoamCam.handleCameraInput(*event))
502  continue;
503 
504  _ingameGUI->addEvent(*event);
505  _currentArea->addEvent(*event);
506  }
507 
508  _eventQueue.clear();
509 
510  CameraMan.update();
511 
513  _ingameGUI->processEventQueue();
514 }
515 
517  uint32 now = EventMan.getTimestamp();
518 
519  while (!_delayedActions.empty()) {
520  ActionQueue::iterator action = _delayedActions.begin();
521 
522  if (now < action->timestamp)
523  break;
524 
525  if (action->type == kActionScript)
526  ScriptContainer::runScript(action->script, action->state,
527  action->owner, action->triggerer);
528 
529  _delayedActions.erase(action);
530  }
531 }
532 
533 void Module::unload(bool completeUnload) {
534  GfxMan.pauseAnimations();
535 
536  unloadAreas();
537  unloadHAKs();
538  unloadTLK();
539  unloadModule();
540 
541  if (!completeUnload)
542  return;
543 
544  unloadPC();
546 }
547 
549  runScript(kScriptExit, this, _pc.get());
550  handleActions();
551 
552  _eventQueue.clear();
553  _delayedActions.clear();
554 
555  TwoDAReg.clear();
556 
557  clearVariables();
558  clearScripts();
559 
560  _tag.clear();
561 
562  _ifo.unload();
563 
565 
566  _newModule.clear();
567  _hasModule = false;
568 }
569 
571  if (!_pc)
572  return;
573 
574  removeObject(*_pc);
575 
576  removePCTokens();
577 
578  _pc.reset();
579 }
580 
582  if (_ifo.getTLK().empty())
583  return;
584 
585  TalkMan.addTable(_ifo.getTLK(), _ifo.getTLK() + "f", true, 0, &_resTLK);
586 }
587 
589  TalkMan.removeTable(_resTLK);
590 }
591 
593  const std::vector<Common::UString> &haks = _ifo.getHAKs();
594 
595  for (size_t i = 0; i < haks.size(); i++)
596  indexMandatoryArchive(haks[i] + ".hak", 1002 + i, _resHAKs);
597 }
598 
601 }
602 
603 static const char * const texturePacks[4][4] = {
604  { "textures_tpc.erf", "tiles_tpc.erf", "xp1_tex_tpc.erf", "xp2_tex_tpc.erf" }, // Worst
605  { "textures_tpa.erf", "tiles_tpc.erf", "xp1_tex_tpc.erf", "xp2_tex_tpc.erf" }, // Bad
606  { "textures_tpa.erf", "tiles_tpb.erf", "xp1_tex_tpb.erf", "xp2_tex_tpb.erf" }, // Okay
607  { "textures_tpa.erf", "tiles_tpa.erf", "xp1_tex_tpa.erf", "xp2_tex_tpa.erf" } // Best
608 };
609 
611  int level = ConfigMan.getInt("texturepack", 1);
612  if (_currentTexturePack == level)
613  // Nothing to do
614  return;
615 
616  const int oldTexturePack = _currentTexturePack;
617 
619 
620  status("Loading texture pack %d", level);
621  indexMandatoryArchive(texturePacks[level][0], 400, &_resTP[0]);
622  indexMandatoryArchive(texturePacks[level][1], 401, &_resTP[1]);
623  indexOptionalArchive (texturePacks[level][2], 402, &_resTP[2]);
624  indexOptionalArchive (texturePacks[level][3], 403, &_resTP[3]);
625 
626  // If we already had a texture pack loaded, reload all textures
627  if (oldTexturePack != -1)
628  TextureMan.reloadAll();
629 
630  _currentTexturePack = level;
631 }
632 
634  for (int i = 0; i < 4; i++)
636 
637  _currentTexturePack = -1;
638 }
639 
641  status("Loading areas...");
642 
643  const std::vector<Common::UString> &areas = _ifo.getAreas();
644  for (size_t i = 0; i < areas.size(); i++) {
645  status("Loading area \"%s\" (%d / %d)", areas[i].c_str(), (int)i, (int)areas.size() - 1);
646 
647  std::pair<AreaMap::iterator, bool> result;
648 
649  result = _areas.insert(std::make_pair(areas[i], (Area *) 0));
650  if (!result.second)
651  throw Common::Exception("Area tag collision: \"%s\"", areas[i].c_str());
652 
653  try {
654  result.first->second = new Area(*this, areas[i].c_str());
655  } catch (Common::Exception &e) {
656  e.add("Can't load area \"%s\"", areas[i].c_str());
657  throw;
658  }
659  }
660 }
661 
663  _ingameGUI->stopConversation();
664 
665  _areas.clear();
666  _newArea.clear();
667 
668  _currentArea = 0;
669 }
670 
673 
674  if (_ingameGUI->showMain() == 2) {
675  _exit = true;
676  return;
677  }
678 
679  // In case we changed the texture pack settings, reload it
680  loadTexturePack();
681 }
682 
684  NWN::Object &obj, bool playHello) {
685 
686  return _ingameGUI->startConversation(conv, pc, obj, playHello);
687 }
688 
689 void Module::movePC(const Common::UString &area) {
690  if (!_pc)
691  return;
692 
693  float x, y, z;
694  _pc->getPosition(x, y, z);
695 
696  movePC(area, x, y, z);
697 }
698 
699 void Module::movePC(float x, float y, float z) {
700  if (!_pc)
701  return;
702 
703  movePC(_currentArea, x, y, z);
704 }
705 
706 void Module::movePC(const Common::UString &area, float x, float y, float z) {
707  if (!_pc)
708  return;
709 
710  Area *pcArea = 0;
711 
712  AreaMap::iterator a = _areas.find(area);
713  if (a != _areas.end())
714  pcArea = a->second;
715 
716  movePC(pcArea, x, y, z);
717 }
718 
719 void Module::movePC(Area *area, float x, float y, float z) {
720  if (!_pc)
721  return;
722 
723  _pc->setArea(area);
724  _pc->setPosition(x, y, z);
725 
726  movedPC();
727 }
728 
730  if (!_pc)
731  return;
732 
733  float x, y, z;
734  _pc->getPosition(x, y, z);
735 
736  // Roughly head position
737  CameraMan.setPosition(x, y, z + 1.8f);
738  CameraMan.update();
739 
740  _newArea.clear();
741  if (_pc->getArea()) {
742  _ingameGUI->abortMain();
743 
744  _newArea = _pc->getArea()->getResRef();
745  }
746 }
747 
749  return _ifo;
750 }
751 
753  return _currentArea;
754 }
755 
757  const Aurora::NWScript::ScriptState &state,
759  Aurora::NWScript::Object *triggerer, uint32 delay) {
760  Action action;
761 
762  action.type = kActionScript;
763  action.script = script;
764  action.state = state;
765  action.owner = owner;
766  action.triggerer = triggerer;
767  action.timestamp = EventMan.getTimestamp() + delay;
768 
769  _delayedActions.insert(action);
770 }
771 
773  if (!Common::FilePath::getExtension(module).equalsIgnoreCase(".mod"))
774  module += ".mod";
775 
776  try {
777  Common::UString moduleDir = ConfigMan.getString("NWN_extraModuleDir");
778  Common::UString modFile = module;
779 
780  return Aurora::ERFFile::getDescription(moduleDir + "/" + modFile).getString();
781  } catch (...) {
782  }
783 
784  return "";
785 }
786 
788  if (!Common::FilePath::getExtension(module).equalsIgnoreCase(".nwm"))
789  module += ".nwm";
790 
791  try {
792  Common::UString moduleDir = ConfigMan.getString("NWN_campaignDir");
793  Common::UString modFile = module;
794 
795  return Aurora::ERFFile::getDescription(moduleDir + "/" + modFile).getString();
796  } catch (...) {
797  }
798 
799  return "";
800 }
801 
803  Common::UString description;
804 
805  description = getDescriptionCampaign(module);
806  if (!description.empty())
807  return description;
808  description = getDescriptionExtra (module);
809  if (!description.empty())
810  return description;
811 
812  return "";
813 }
814 
815 } // End of namespace NWN
816 
817 } // End of namespace Engines
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
void checkHAKs()
Do we have all HAKs needed for the module?
Definition: module.cpp:209
AreaMap _areas
The areas in the current module.
Definition: module.h:204
bool isSave() const
Is the module a save file?
Definition: ifofile.cpp:259
void showMenu()
Show the ingame main menu.
Definition: module.cpp:671
Creature * getPC()
Return the currently playing PC.
Definition: module.cpp:298
void preparePremiumModule(const Common::UString &module)
Check if this is premium module, and if so, prepare its loading.
Definition: module.cpp:140
void playVideo(const Common::UString &video)
Play this video resource.
Definition: util.cpp:54
void add(const char *s,...) GCC_PRINTF(2
Definition: error.cpp:58
bool isVisible() const
Definition: console.cpp:797
void unloadAreas()
Unload the areas.
Definition: module.cpp:662
void hashMD5(ReadStream &stream, std::vector< byte > &digest)
Hash the stream into an MD5 digest of 16 bytes.
Definition: md5.cpp:248
#define TalkMan
Shortcut for accessing the talk manager.
Definition: talkman.h:111
const Common::UString & getResRef()
Return the area&#39;s resref (resource ID).
Definition: area.cpp:120
const Common::UString & getTLK() const
Return the custom TLK table this module uses.
Definition: ifofile.cpp:275
void readScripts(const Aurora::GFF3Struct &gff)
Definition: container.cpp:123
A class holding an UTF-8 string.
Definition: ustring.h:48
void replaceModule()
Actually replace the currently running module.
Definition: module.cpp:306
void changeModule(const Common::UString &module)
Schedule a change to a new module.
Definition: module.cpp:302
void enterArea()
Enter a new area.
Definition: module.cpp:397
bool _exit
Should we exit the module?
Definition: module.h:202
#define TextureMan
Shortcut for accessing the texture manager.
Definition: textureman.h:127
void unloadHAKs()
Unload the HAKs required by the module.
Definition: module.cpp:599
static UString getExtension(const UString &p)
Return a file name&#39;s extension.
Definition: filepath.cpp:93
The global config manager.
void loadTLK()
Load the TLK used by the module.
Definition: module.cpp:581
void unload()
Unload a currently loaded IFO.
Definition: ifofile.cpp:97
bool indexOptionalArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:69
The Aurora texture manager.
Aurora::NWScript::ObjectReference owner
Definition: module.h:163
Common::UString _name
The object&#39;s display name.
Definition: object.h:165
Mathematical helpers.
Camera management.
void unloadTLK()
Unload the TLK used by the module.
Definition: module.cpp:588
A simple streaming file reading class.
Definition: readfile.h:40
Basic Neverwinter Nights type definitions.
void loadHAKs()
Load the HAKs required by the module.
Definition: module.cpp:592
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
Definition: util.h:131
Neverwinter Nights installation version detection.
void movePC(const Common::UString &area)
Move the player character to this area.
Definition: module.cpp:689
const Common::UString & getDescription() const
Return the object&#39;s description.
Definition: object.cpp:94
void getEntryDirection(float &x, float &y) const
Return the entry direction.
Definition: ifofile.cpp:302
void clear()
Clear the whole context.
Definition: module.cpp:123
void show()
Show the area.
Definition: area.cpp:221
void removeFocus()
Forcibly remove the focus from the currently highlighted object.
Definition: area.cpp:614
const Version & getGameVersion() const
Definition: module.cpp:119
void exit()
Exit the currently running module.
Definition: module.cpp:440
An area in Neverwinter Nights, holding all objects and room tiles within, as well as general area pro...
Definition: area.h:63
The NWN ingame GUI elements.
bool _running
Are we currently running a module?
Definition: module.h:182
const Common::UString & getString(Language language, LanguageGender gender=kLanguageGenderCurrent) const
Get the string of that language.
Definition: locstring.cpp:82
Exception that provides a stack of explanations.
Definition: error.h:36
const LocString & getDescription() const
Return the description.
Definition: erffile.cpp:693
#define FreeRoamCam
void delayScript(const Common::UString &script, const Aurora::NWScript::ScriptState &state, Aurora::NWScript::Object *owner, Aurora::NWScript::Object *triggerer, uint32 delay)
Definition: module.cpp:756
EventQueue _eventQueue
Definition: module.h:210
SDL_Event Event
Definition: types.h:42
void deindexResources(Common::ChangeID &changeID)
Remove previously added resources from the ResourceManager.
Definition: resources.cpp:164
ChangeList _resHAKs
Resources added by the HAKs of the module.
Definition: module.h:192
Aurora::NWScript::ObjectReference triggerer
Definition: module.h:164
Keyboard key was pressed.
Definition: types.h:46
The context needed to run a Neverwinter Nights module.
Common::ChangeID _resModule
Resources added by the module.
Definition: module.h:187
void loadTexturePack()
Load the texture pack.
Definition: module.cpp:610
const std::vector< Common::UString > & getHAKs() const
Return the list of required HAK files.
Definition: ifofile.cpp:307
Basic exceptions to throw.
void load(Common::SeekableReadStream *stream, bool repairNWNPremium=false)
Take over this stream and load an IFO out of it.
Definition: ifofile.cpp:101
void load(const Common::UString &module)
Load a module.
Definition: module.cpp:127
Common::ScopedPtr< IngameGUI > _ingameGUI
The ingame GUI elements.
Definition: module.h:184
void indexMandatoryArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:36
The context holding a Neverwinter Nights area.
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
ActionQueue _delayedActions
Definition: module.h:211
Common::ChangeID _resTP[4]
Definition: module.h:200
uint16_t uint16
Definition: types.h:202
#define ConfigMan
Shortcut for accessing the config manager.
Definition: configman.h:176
void enter()
Enter the loaded module, starting it.
Definition: module.cpp:322
Utility templates and functions.
An IFO (module information) file, describing global module properties in many Aurora games...
Definition: ifofile.h:69
The NWN ingame GUI elements.
Definition: ingame.h:58
Fake value for a module object.
Definition: types.h:53
void clear()
Definition: ptrmap.h:48
Area * getCurrentArea()
Return the area the PC is currently in.
Definition: module.cpp:752
const Aurora::IFOFile & getIFO() const
Return the IFO of the currently loaded module.
Definition: module.cpp:748
bool operator<(const Action &s) const
Definition: module.cpp:100
The global events manager.
void addEvent(const Events::Event &event)
Add a single event for consideration into the area event queue.
Definition: area.cpp:525
Types and functions related to language.
Handling BioWare&#39;s ERFs (encapsulated resource file).
A 3D model of an object.
bool isLoaded() const
Is a module currently loaded and ready to run?
Definition: module.cpp:446
const std::vector< Common::UString > & getAreas() const
Return the list of areas in the module.
Definition: ifofile.cpp:311
void loadModule(const Common::UString &module)
Load the actual module.
Definition: module.cpp:162
bool isRunning() const
Is a module currently running?
Definition: module.cpp:450
Area * _currentArea
The current area.
Definition: module.h:206
Aurora::IFOFile _ifo
The module&#39;s IFO.
Definition: module.h:194
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
#define TwoDAReg
Shortcut for accessing the 2da registry.
Definition: 2dareg.h:101
Generic Aurora engines (debug) console.
StackException Exception
Definition: error.h:59
void addObject(NWN::Object &object)
Add an object to this container.
The global 2DA registry.
Common::UString _newArea
The new area to enter.
Definition: module.h:205
void warning(const char *s,...)
Definition: util.cpp:33
Common::ScopedPtr< Creature > _pc
The player character we use.
Definition: module.h:196
Module(::Engines::Console &console, const Version &gameVersion)
Definition: module.cpp:105
Common::UString script
Definition: module.h:160
uint32 female
Definition: module.cpp:63
#define EventMan
Shortcut for accessing the events manager.
Definition: events.h:210
void usePC(const Common::UString &bic, bool local)
Use this character as the player character.
Definition: module.cpp:268
void hide()
Hide the area.
Definition: area.cpp:246
static const char *const texturePacks[4][4]
Definition: module.cpp:603
Implementing the stream reading interfaces for files.
void loadAreas()
Load the areas.
Definition: module.cpp:640
bool _hasModule
Do we have a module?
Definition: module.h:181
void unloadModule()
Unload the module.
Definition: module.cpp:548
uint32 male
Definition: module.cpp:62
const char * token
Definition: module.cpp:61
static Common::UString getDescriptionCampaign(Common::UString module)
Definition: module.cpp:787
#define LangMan
Shortcut for accessing the language manager.
Definition: language.h:275
static Common::UString getDescriptionExtra(Common::UString module)
Definition: module.cpp:772
const GFF3Struct * getGFF() const
Return the IFO&#39;s GFF struct.
Definition: ifofile.cpp:244
uint32_t uint32
Definition: types.h:204
The global talk manager for Aurora strings.
A creature in a Neverwinter Nights area.
void processEventQueue()
Process the current event queue.
Definition: module.cpp:458
const LocString & getName() const
Return the name of the module.
Definition: ifofile.cpp:267
Common::UString _tag
Definition: object.h:56
Common::UString _newModule
The module we should change to.
Definition: module.h:208
void status(const char *s,...)
Definition: util.cpp:52
void printf(const char *s,...) GCC_PRINTF(2
Definition: console.cpp:1093
bool startConversation(const Common::UString &conv, Creature &pc, NWN::Object &obj, bool playHello=true)
Start a conversation.
Definition: module.cpp:683
bool processEvent(const Events::Event &event)
Definition: console.cpp:817
#define CameraMan
Shortcut for accessing the camera manager.
Definition: camera.h:83
static float rad2deg(float rad)
Definition: maths.h:93
Generic Aurora engines utility functions.
Common::ChangeID _resTLK
Resources added for the custom TLK.
Definition: module.h:189
void processEventQueue()
Process the current event queue.
Definition: area.cpp:529
void checkXPs()
Do we have all expansions needed for the module?
Definition: module.cpp:195
The context handling the gameplay in Neverwinter Nights.
void unloadPC()
Unload the PC.
Definition: module.cpp:570
static bool isPremiumModule(const Common::UString &module)
Is this module file (including extension) a premium module?
Definition: game.cpp:249
void removeObject(NWN::Object &object)
Remove an object from this container.
Manager for tokens in Aurora engines text strings.
const Common::UString & getTag() const
Return the module&#39;s tag.
Definition: ifofile.cpp:263
Aurora::NWScript::ScriptState state
Definition: module.h:162
uint16 getExpansions() const
Return the list of required expansions.
Definition: ifofile.cpp:284
void leave()
Leave the running module, quitting it.
Definition: module.cpp:389
void getEntryPosition(float &x, float &y, float &z) const
Return the entry position.
Definition: ifofile.cpp:296
const Common::UString & getEntryArea() const
Return the entry area.
Definition: ifofile.cpp:292
Engine utility class for free-roam camera handling.
void clear()
Clear the string&#39;s contents.
Definition: ustring.cpp:236
bool runScript(Script script, const Aurora::NWScript::ObjectReference owner=Aurora::NWScript::ObjectReference(), const Aurora::NWScript::ObjectReference triggerer=Aurora::NWScript::ObjectReference())
Definition: container.cpp:139
void movedPC()
Notify the module that the PC was moved.
Definition: module.cpp:729
Hashing/digesting using the MD5 algorithm.
::Engines::Console * _console
Definition: module.h:177
const Common::UString & getStartMovie() const
Return the starting movie.
Definition: ifofile.cpp:288
#define TokenMan
Shortcut for accessing the token manager.
Definition: tokenman.h:63
void addEvent(const Events::Event &event)
Add a single event for consideration into the event queue.
Definition: module.cpp:454
const Version * _gameVersion
Definition: module.h:179
#define GfxMan
Shortcut for accessing the graphics manager.
Definition: graphics.h:299
The global resource manager for Aurora resources.
Utility class for manipulating file paths.
static const GenderToken kGenderTokens[]
Definition: module.cpp:66
const Common::UString & getName()
Return the area&#39;s localized name.
Definition: area.cpp:124
static UString changeExtension(const UString &p, const UString &ext="")
Change a file name&#39;s extension.
Definition: filepath.cpp:99
void unload(bool completeUnload=true)
Unload the whole shebang.
Definition: module.cpp:533
void unloadTexturePack()
Unload the texture pack.
Definition: module.cpp:633