2010-01-07 19:22:41 +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 2
|
|
|
|
* 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, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
2010-01-14 10:24:12 +00:00
|
|
|
* MIT License:
|
|
|
|
*
|
|
|
|
* Copyright (c) 2009 Alexei Svitkine, Eugene Sandulenko
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person
|
|
|
|
* obtaining a copy of this software and associated documentation
|
|
|
|
* files (the "Software"), to deal in the Software without
|
|
|
|
* restriction, including without limitation the rights to use,
|
|
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following
|
|
|
|
* conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
2010-01-07 19:22:41 +00:00
|
|
|
*/
|
|
|
|
|
2015-12-21 14:47:10 +00:00
|
|
|
#include "common/file.h"
|
|
|
|
|
2010-01-07 19:22:41 +00:00
|
|
|
#include "wage/wage.h"
|
2010-01-10 22:44:27 +00:00
|
|
|
#include "wage/entities.h"
|
2010-01-07 21:52:31 +00:00
|
|
|
#include "wage/script.h"
|
|
|
|
#include "wage/world.h"
|
2010-01-07 19:22:41 +00:00
|
|
|
|
|
|
|
namespace Wage {
|
|
|
|
|
2015-12-25 00:09:12 +00:00
|
|
|
World::World(WageEngine *engine) {
|
2015-12-25 12:12:11 +00:00
|
|
|
_storageScene = new Scene;
|
|
|
|
_storageScene->_name = STORAGESCENE;
|
|
|
|
|
|
|
|
_orderedScenes.push_back(_storageScene);
|
|
|
|
_scenes[STORAGESCENE] = _storageScene;
|
2015-12-21 11:19:27 +00:00
|
|
|
|
|
|
|
_gameOverMessage = nullptr;
|
|
|
|
_saveBeforeQuitMessage = nullptr;
|
|
|
|
_saveBeforeCloseMessage = nullptr;
|
|
|
|
_revertMessage = nullptr;
|
2015-12-25 00:09:12 +00:00
|
|
|
|
|
|
|
_engine = engine;
|
2010-01-07 21:52:31 +00:00
|
|
|
}
|
|
|
|
|
2015-12-25 12:12:11 +00:00
|
|
|
World::~World() {
|
2016-01-06 22:40:08 +00:00
|
|
|
for (uint i = 0; i < _orderedObjs.size(); i++)
|
|
|
|
delete _orderedObjs[i];
|
|
|
|
|
|
|
|
for (uint i = 0; i < _orderedChrs.size(); i++)
|
|
|
|
delete _orderedChrs[i];
|
|
|
|
|
|
|
|
for (uint i = 0; i < _orderedSounds.size(); i++)
|
|
|
|
delete _orderedSounds[i];
|
|
|
|
|
|
|
|
for (uint i = 0; i < _orderedScenes.size(); i++)
|
|
|
|
delete _orderedScenes[i];
|
2016-01-07 00:24:42 +00:00
|
|
|
|
|
|
|
for (uint i = 0; i < _patterns.size(); i++)
|
|
|
|
free(_patterns[i]);
|
|
|
|
|
|
|
|
delete _globalScript;
|
|
|
|
|
|
|
|
delete _gameOverMessage;
|
|
|
|
delete _saveBeforeQuitMessage;
|
|
|
|
delete _saveBeforeCloseMessage;
|
|
|
|
delete _revertMessage;
|
|
|
|
|
2015-12-25 12:12:11 +00:00
|
|
|
}
|
|
|
|
|
2010-01-11 20:46:24 +00:00
|
|
|
bool World::loadWorld(Common::MacResManager *resMan) {
|
|
|
|
Common::MacResIDArray resArray;
|
2011-05-30 16:37:27 +00:00
|
|
|
Common::SeekableReadStream *res;
|
2010-01-11 20:46:24 +00:00
|
|
|
Common::MacResIDArray::const_iterator iter;
|
2010-01-07 19:22:41 +00:00
|
|
|
|
2011-05-30 16:05:26 +00:00
|
|
|
if ((resArray = resMan->getResIDArray(MKTAG('G','C','O','D'))).size() == 0)
|
2010-01-07 21:52:31 +00:00
|
|
|
return false;
|
|
|
|
|
2010-01-08 23:42:28 +00:00
|
|
|
// Load global script
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('G','C','O','D'), resArray[0]);
|
2011-06-01 01:16:39 +00:00
|
|
|
_globalScript = new Script(res);
|
2010-01-07 21:52:31 +00:00
|
|
|
|
2012-10-19 22:38:04 +00:00
|
|
|
// TODO: read creator
|
|
|
|
|
2010-01-08 23:42:28 +00:00
|
|
|
// Load main configuration
|
2011-05-30 16:05:26 +00:00
|
|
|
if ((resArray = resMan->getResIDArray(MKTAG('V','E','R','S'))).size() == 0)
|
2010-01-07 19:22:41 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (resArray.size() > 1)
|
|
|
|
warning("Too many VERS resources");
|
|
|
|
|
2012-10-19 22:38:04 +00:00
|
|
|
if (resArray.size()) {
|
|
|
|
debug(3, "Loading version info");
|
2010-01-07 19:22:41 +00:00
|
|
|
|
2012-10-19 22:38:04 +00:00
|
|
|
res = resMan->getResource(MKTAG('V','E','R','S'), resArray[0]);
|
2010-01-07 19:22:41 +00:00
|
|
|
|
2012-10-19 22:38:04 +00:00
|
|
|
res->skip(10);
|
|
|
|
byte b = res->readByte();
|
|
|
|
_weaponMenuDisabled = (b != 0);
|
|
|
|
if (b != 0 && b != 1)
|
|
|
|
error("Unexpected value for weapons menu");
|
2010-01-07 19:22:41 +00:00
|
|
|
|
2012-10-19 22:38:04 +00:00
|
|
|
res->skip(3);
|
|
|
|
_aboutMessage = readPascalString(res);
|
2010-01-07 19:22:41 +00:00
|
|
|
|
2012-10-19 22:38:04 +00:00
|
|
|
if (!scumm_stricmp(resMan->getBaseFileName().c_str(), "Scepters"))
|
|
|
|
res->skip(1); // ????
|
2010-01-07 19:22:41 +00:00
|
|
|
|
2012-10-19 22:38:04 +00:00
|
|
|
_soundLibrary1 = readPascalString(res);
|
|
|
|
_soundLibrary2 = readPascalString(res);
|
|
|
|
|
|
|
|
delete res;
|
|
|
|
}
|
2010-01-10 22:26:01 +00:00
|
|
|
|
2015-12-21 11:19:27 +00:00
|
|
|
Common::String *message;
|
|
|
|
if ((message = loadStringFromDITL(resMan, 2910, 1)) != NULL) {
|
|
|
|
message->trim();
|
|
|
|
warning("_gameOverMessage: %s", message->c_str());
|
|
|
|
_gameOverMessage = message;
|
|
|
|
}
|
|
|
|
if ((message = loadStringFromDITL(resMan, 2480, 3)) != NULL) {
|
|
|
|
message->trim();
|
|
|
|
warning("_saveBeforeQuitMessage: %s", message->c_str());
|
|
|
|
_saveBeforeQuitMessage = message;
|
|
|
|
}
|
|
|
|
if ((message = loadStringFromDITL(resMan, 2490, 3)) != NULL) {
|
|
|
|
message->trim();
|
|
|
|
warning("_saveBeforeCloseMessage: %s", message->c_str());
|
|
|
|
_saveBeforeCloseMessage = message;
|
|
|
|
}
|
|
|
|
if ((message = loadStringFromDITL(resMan, 2940, 2)) != NULL) {
|
|
|
|
message->trim();
|
|
|
|
warning("_revertMessage: %s", message->c_str());
|
|
|
|
_revertMessage = message;
|
|
|
|
}
|
|
|
|
|
2010-01-08 23:42:28 +00:00
|
|
|
// Load scenes
|
2011-05-30 16:05:26 +00:00
|
|
|
resArray = resMan->getResIDArray(MKTAG('A','S','C','N'));
|
2012-10-19 22:38:04 +00:00
|
|
|
debug(3, "Loading %d scenes", resArray.size());
|
|
|
|
|
2010-01-08 23:42:28 +00:00
|
|
|
for (iter = resArray.begin(); iter != resArray.end(); ++iter) {
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('A','S','C','N'), *iter);
|
2011-06-01 02:42:06 +00:00
|
|
|
Scene *scene = new Scene(resMan->getResName(MKTAG('A','S','C','N'), *iter), res);
|
2010-01-09 00:01:58 +00:00
|
|
|
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('A','C','O','D'), *iter);
|
2010-01-09 00:01:58 +00:00
|
|
|
if (res != NULL)
|
2011-06-01 02:42:06 +00:00
|
|
|
scene->_script = new Script(res);
|
2010-01-10 22:26:01 +00:00
|
|
|
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('A','T','X','T'), *iter);
|
2010-01-10 22:26:01 +00:00
|
|
|
if (res != NULL) {
|
2012-10-19 22:38:04 +00:00
|
|
|
scene->_textBounds = readRect(res);
|
2011-06-01 01:16:39 +00:00
|
|
|
scene->_fontType = res->readUint16BE();
|
|
|
|
scene->_fontSize = res->readUint16BE();
|
2015-12-17 08:44:51 +00:00
|
|
|
|
2015-12-27 12:18:59 +00:00
|
|
|
if (scene->_fontType != 3 || scene->_fontSize != 9)
|
2016-01-07 11:14:07 +00:00
|
|
|
warning("scene: %s font: '%s' (%d) size: %d", scene->_name.c_str(), scene->getFontName(), scene->_fontType, scene->_fontSize);
|
2015-12-27 12:18:59 +00:00
|
|
|
|
2011-06-01 02:42:06 +00:00
|
|
|
String text;
|
|
|
|
while (res->pos() < res->size()) {
|
|
|
|
char c = res->readByte();
|
|
|
|
if (c == 0x0d)
|
|
|
|
c = '\n';
|
|
|
|
text += c;
|
|
|
|
}
|
2010-01-10 22:26:01 +00:00
|
|
|
scene->_text = text;
|
|
|
|
|
2011-05-30 16:37:27 +00:00
|
|
|
delete res;
|
2010-01-10 22:26:01 +00:00
|
|
|
}
|
|
|
|
addScene(scene);
|
2010-01-08 23:42:28 +00:00
|
|
|
}
|
2015-12-17 08:44:51 +00:00
|
|
|
|
2010-01-10 22:26:01 +00:00
|
|
|
// Load Objects
|
2011-05-30 16:05:26 +00:00
|
|
|
resArray = resMan->getResIDArray(MKTAG('A','O','B','J'));
|
2012-10-19 22:38:04 +00:00
|
|
|
debug(3, "Loading %d objects", resArray.size());
|
|
|
|
|
2010-01-10 22:26:01 +00:00
|
|
|
for (iter = resArray.begin(); iter != resArray.end(); ++iter) {
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('A','O','B','J'), *iter);
|
2011-06-01 02:42:06 +00:00
|
|
|
addObj(new Obj(resMan->getResName(MKTAG('A','O','B','J'), *iter), res));
|
2010-01-10 22:26:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Load Characters
|
2011-05-30 16:05:26 +00:00
|
|
|
resArray = resMan->getResIDArray(MKTAG('A','C','H','R'));
|
2012-10-19 22:38:04 +00:00
|
|
|
debug(3, "Loading %d characters", resArray.size());
|
|
|
|
|
2010-01-10 22:26:01 +00:00
|
|
|
for (iter = resArray.begin(); iter != resArray.end(); ++iter) {
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('A','C','H','R'), *iter);
|
2011-06-01 02:42:06 +00:00
|
|
|
Chr *chr = new Chr(resMan->getResName(MKTAG('A','C','H','R'), *iter), res);
|
2010-01-10 22:26:01 +00:00
|
|
|
|
|
|
|
addChr(chr);
|
|
|
|
// TODO: What if there's more than one player character?
|
|
|
|
if (chr->_playerCharacter)
|
|
|
|
_player = chr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load Sounds
|
2011-05-30 16:05:26 +00:00
|
|
|
resArray = resMan->getResIDArray(MKTAG('A','S','N','D'));
|
2012-10-19 22:38:04 +00:00
|
|
|
debug(3, "Loading %d sounds", resArray.size());
|
|
|
|
|
2010-01-10 22:26:01 +00:00
|
|
|
for (iter = resArray.begin(); iter != resArray.end(); ++iter) {
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('A','S','N','D'), *iter);
|
2011-06-01 02:42:06 +00:00
|
|
|
addSound(new Sound(resMan->getResName(MKTAG('A','S','N','D'), *iter), res));
|
2010-01-10 22:26:01 +00:00
|
|
|
}
|
2015-12-17 08:44:51 +00:00
|
|
|
|
2010-01-10 22:26:01 +00:00
|
|
|
if (_soundLibrary1.size() > 0) {
|
|
|
|
loadExternalSounds(_soundLibrary1);
|
|
|
|
}
|
|
|
|
if (_soundLibrary2.size() > 0) {
|
|
|
|
loadExternalSounds(_soundLibrary2);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load Patterns
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('P','A','T','#'), 900);
|
2010-01-10 22:26:01 +00:00
|
|
|
if (res != NULL) {
|
2011-06-01 01:16:39 +00:00
|
|
|
int count = res->readUint16BE();
|
2012-10-19 22:38:04 +00:00
|
|
|
debug(3, "Loading %d patterns", count);
|
|
|
|
|
2010-01-10 22:26:01 +00:00
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
byte *pattern = (byte *)malloc(8);
|
2015-12-19 11:29:16 +00:00
|
|
|
|
|
|
|
res->read(pattern, 8);
|
2015-12-17 08:44:51 +00:00
|
|
|
_patterns.push_back(pattern);
|
2010-01-10 22:26:01 +00:00
|
|
|
}
|
2015-12-17 08:44:51 +00:00
|
|
|
|
2011-05-30 16:37:27 +00:00
|
|
|
delete res;
|
2015-12-21 12:08:09 +00:00
|
|
|
} else {
|
|
|
|
/* Enchanted Scepters did not use the PAT# resource for the textures. */
|
|
|
|
res = resMan->getResource(MKTAG('C','O','D','E'), 1);
|
|
|
|
if (res != NULL) {
|
|
|
|
res->skip(0x55ac);
|
|
|
|
for (int i = 0; i < 29; i++) {
|
|
|
|
byte *pattern = (byte *)malloc(8);
|
|
|
|
|
|
|
|
res->read(pattern, 8);
|
|
|
|
_patterns.push_back(pattern);
|
|
|
|
}
|
|
|
|
}
|
2015-12-21 12:14:11 +00:00
|
|
|
delete res;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = resMan->getResource(MKTAG('M','E','N','U'), 2001);
|
|
|
|
if (res != NULL) {
|
2015-12-21 14:47:10 +00:00
|
|
|
readMenu(res);
|
2015-12-21 12:14:11 +00:00
|
|
|
warning("STUB: aboutMenu");
|
|
|
|
//String aboutMenuItemName = appleMenu[1].split(";")[0];
|
|
|
|
//world.setAboutMenuItemName(aboutMenuItemName);
|
|
|
|
delete res;
|
|
|
|
}
|
|
|
|
res = resMan->getResource(MKTAG('M','E','N','U'), 2004);
|
|
|
|
if (res != NULL) {
|
2015-12-21 14:47:10 +00:00
|
|
|
readMenu(res);
|
2015-12-21 12:14:11 +00:00
|
|
|
warning("STUB: commandsMenu");
|
|
|
|
//world.setCommandsMenuName(commandsMenu[0]);
|
|
|
|
//world.setDefaultCommandsMenu(commandsMenu[1]);
|
|
|
|
delete res;
|
|
|
|
}
|
|
|
|
res = resMan->getResource(MKTAG('M','E','N','U'), 2005);
|
|
|
|
if (res != NULL) {
|
2015-12-21 14:47:10 +00:00
|
|
|
readMenu(res);
|
2015-12-21 12:14:11 +00:00
|
|
|
warning("STUB: weaponsMenu");
|
|
|
|
//world.setWeaponsMenuName(weaponsMenu[0]);
|
|
|
|
delete res;
|
2010-01-10 22:26:01 +00:00
|
|
|
}
|
2015-12-21 12:14:11 +00:00
|
|
|
// TODO: Read Apple menu and get the name of that menu item..
|
|
|
|
|
|
|
|
// store global info in state object for use with save/load actions
|
|
|
|
//world.setCurrentState(initialState); // pass off the state object to the world
|
2010-01-07 19:22:41 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-12-21 14:47:10 +00:00
|
|
|
Common::StringArray World::readMenu(Common::SeekableReadStream *res) {
|
|
|
|
res->skip(10);
|
|
|
|
int enableFlags = res->readUint32BE();
|
|
|
|
String menuName = readPascalString(res);
|
|
|
|
String menuItem = readPascalString(res);
|
|
|
|
int menuItemNumber = 1;
|
|
|
|
Common::String sb;
|
|
|
|
byte itemData[4];
|
|
|
|
|
|
|
|
while (menuItem.size() > 0) {
|
|
|
|
if (sb.size() > 0) {
|
|
|
|
sb += ';';
|
|
|
|
}
|
|
|
|
if ((enableFlags & (1 << menuItemNumber)) == 0) {
|
|
|
|
sb += '(';
|
|
|
|
}
|
|
|
|
sb += menuItem;
|
|
|
|
res->read(itemData, 4);
|
|
|
|
static const char styles[] = {'B', 'I', 'U', 'O', 'S', 'C', 'E', 0};
|
|
|
|
for (int i = 0; styles[i] != 0; i++) {
|
|
|
|
if ((itemData[3] & (1 << i)) != 0) {
|
|
|
|
sb += '<';
|
|
|
|
sb += styles[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (itemData[1] != 0) {
|
|
|
|
sb += '/';
|
|
|
|
sb += (char)itemData[1];
|
|
|
|
}
|
|
|
|
menuItem = readPascalString(res);
|
|
|
|
menuItemNumber++;
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::StringArray result;
|
|
|
|
result.push_back(menuName);
|
|
|
|
result.push_back(sb);
|
|
|
|
|
|
|
|
warning("menuName: %s", menuName.c_str());
|
|
|
|
warning("sb: %s", sb.c_str());
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-01-10 22:44:27 +00:00
|
|
|
void World::loadExternalSounds(String fname) {
|
2010-01-11 19:30:48 +00:00
|
|
|
Common::File in;
|
|
|
|
|
|
|
|
in.open(fname);
|
|
|
|
if (!in.isOpen()) {
|
|
|
|
warning("Cannot load sound file <%s>", fname.c_str());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
in.close();
|
|
|
|
|
2010-01-11 20:46:24 +00:00
|
|
|
Common::MacResManager *resMan;
|
2011-06-01 02:42:06 +00:00
|
|
|
resMan = new Common::MacResManager();
|
|
|
|
resMan->open(fname);
|
2010-01-11 19:30:48 +00:00
|
|
|
|
2010-01-11 20:46:24 +00:00
|
|
|
Common::MacResIDArray resArray;
|
2011-05-30 16:37:27 +00:00
|
|
|
Common::SeekableReadStream *res;
|
2010-01-11 20:46:24 +00:00
|
|
|
Common::MacResIDArray::const_iterator iter;
|
2010-01-11 19:30:48 +00:00
|
|
|
|
2011-05-30 16:05:26 +00:00
|
|
|
resArray = resMan->getResIDArray(MKTAG('A','S','N','D'));
|
2010-01-11 19:30:48 +00:00
|
|
|
for (iter = resArray.begin(); iter != resArray.end(); ++iter) {
|
2011-05-30 16:37:27 +00:00
|
|
|
res = resMan->getResource(MKTAG('A','S','N','D'), *iter);
|
2011-06-01 02:42:06 +00:00
|
|
|
addSound(new Sound(resMan->getResName(MKTAG('A','S','N','D'), *iter), res));
|
2010-01-11 19:30:48 +00:00
|
|
|
}
|
2010-01-10 22:44:27 +00:00
|
|
|
}
|
|
|
|
|
2015-12-21 11:19:27 +00:00
|
|
|
Common::String *World::loadStringFromDITL(Common::MacResManager *resMan, int resourceId, int itemIndex) {
|
|
|
|
Common::SeekableReadStream *res = resMan->getResource(MKTAG('D','I','T','L'), resourceId);
|
|
|
|
if (res) {
|
|
|
|
int itemCount = res->readSint16BE();
|
|
|
|
for (int i = 0; i <= itemCount; i++) {
|
|
|
|
// int placeholder; short rect[4]; byte flags; pstring str;
|
|
|
|
res->skip(13);
|
|
|
|
Common::String message = readPascalString(res);
|
|
|
|
if (i == itemIndex) {
|
|
|
|
Common::String *msg = new Common::String(message);
|
2016-01-06 23:51:14 +00:00
|
|
|
delete res;
|
2015-12-21 11:19:27 +00:00
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
}
|
2016-01-06 23:51:14 +00:00
|
|
|
|
|
|
|
delete res;
|
2015-12-21 11:19:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-12-25 11:57:54 +00:00
|
|
|
bool InvComparator(Obj *l, Obj *r) {
|
2015-12-25 11:49:47 +00:00
|
|
|
return l->_index < r->_index;
|
|
|
|
}
|
|
|
|
|
2015-12-24 13:12:19 +00:00
|
|
|
void World::move(Obj *obj, Chr *chr) {
|
2015-12-25 11:49:47 +00:00
|
|
|
if (obj == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Designed *from = obj->removeFromCharOrScene();
|
|
|
|
obj->_currentOwner = chr;
|
|
|
|
chr->_inventory.push_back(obj);
|
|
|
|
|
2015-12-25 11:57:54 +00:00
|
|
|
Common::sort(chr->_inventory.begin(), chr->_inventory.end(), InvComparator);
|
2015-12-25 11:49:47 +00:00
|
|
|
|
|
|
|
_engine->onMove(obj, from, chr);
|
2015-12-25 00:09:12 +00:00
|
|
|
}
|
|
|
|
|
2015-12-25 11:57:54 +00:00
|
|
|
bool ObjComparator(Obj *o1, Obj *o2) {
|
|
|
|
bool o1Immobile = (o1->_type == Obj::IMMOBILE_OBJECT);
|
|
|
|
bool o2Immobile = (o2->_type == Obj::IMMOBILE_OBJECT);
|
|
|
|
if (o1Immobile == o2Immobile) {
|
|
|
|
return o1->_index - o2->_index;
|
|
|
|
}
|
|
|
|
return o1Immobile;
|
|
|
|
}
|
|
|
|
|
2015-12-28 18:09:16 +00:00
|
|
|
void World::move(Obj *obj, Scene *scene, bool skipSort) {
|
2015-12-25 11:57:54 +00:00
|
|
|
if (obj == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Designed *from = obj->removeFromCharOrScene();
|
|
|
|
obj->_currentScene = scene;
|
|
|
|
scene->_objs.push_back(obj);
|
|
|
|
|
2015-12-28 18:09:16 +00:00
|
|
|
if (!skipSort)
|
|
|
|
Common::sort(scene->_objs.begin(), scene->_objs.end(), ObjComparator);
|
2015-12-25 11:57:54 +00:00
|
|
|
|
|
|
|
_engine->onMove(obj, from, scene);
|
2015-12-25 00:09:12 +00:00
|
|
|
}
|
|
|
|
|
2015-12-25 12:12:11 +00:00
|
|
|
bool ChrComparator(Chr *l, Chr *r) {
|
|
|
|
return l->_index < r->_index;
|
|
|
|
}
|
|
|
|
|
2015-12-28 18:09:16 +00:00
|
|
|
void World::move(Chr *chr, Scene *scene, bool skipSort) {
|
2015-12-25 12:12:11 +00:00
|
|
|
if (chr == NULL)
|
|
|
|
return;
|
|
|
|
Scene *from = chr->_currentScene;
|
|
|
|
if (from == scene)
|
|
|
|
return;
|
|
|
|
if (from != NULL)
|
|
|
|
from->_chrs.remove(chr);
|
|
|
|
scene->_chrs.push_back(chr);
|
|
|
|
|
2015-12-28 18:09:16 +00:00
|
|
|
if (!skipSort)
|
|
|
|
Common::sort(scene->_chrs.begin(), scene->_chrs.end(), ChrComparator);
|
2015-12-25 12:12:11 +00:00
|
|
|
|
|
|
|
if (scene == _storageScene) {
|
2015-12-31 21:34:44 +00:00
|
|
|
chr->resetState();
|
2015-12-25 12:12:11 +00:00
|
|
|
} else if (chr->_playerCharacter) {
|
|
|
|
scene->_visited = true;
|
2015-12-31 21:34:44 +00:00
|
|
|
_player->_context._visits++;
|
2015-12-25 12:12:11 +00:00
|
|
|
}
|
|
|
|
chr->_currentScene = scene;
|
|
|
|
|
|
|
|
_engine->onMove(chr, from, scene);
|
2015-12-25 00:09:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Scene *World::getRandomScene() {
|
|
|
|
// Not including storage:
|
2016-01-06 23:42:57 +00:00
|
|
|
return _orderedScenes[1 + _engine->_rnd->getRandomNumber(_orderedScenes.size() - 2)];
|
2015-12-24 13:12:19 +00:00
|
|
|
}
|
|
|
|
|
2016-01-03 23:42:10 +00:00
|
|
|
Scene *World::getSceneAt(int x, int y) {
|
2016-01-06 22:19:51 +00:00
|
|
|
for (uint i = 0; i < _orderedScenes.size(); i++) {
|
2016-01-03 23:42:10 +00:00
|
|
|
Scene *scene = _orderedScenes[i];
|
|
|
|
|
|
|
|
if (scene != _storageScene && scene->_worldX == x && scene->_worldY == y) {
|
|
|
|
return scene;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-01-07 23:26:31 +00:00
|
|
|
static const int directionsX[] = { 0, 0, 1, -1 };
|
|
|
|
static const int directionsY[] = { -1, 1, 0, 0 };
|
|
|
|
|
|
|
|
bool World::scenesAreConnected(Scene *scene1, Scene *scene2) {
|
|
|
|
if (!scene1 || !scene2)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int x = scene2->_worldX;
|
|
|
|
int y = scene2->_worldY;
|
|
|
|
|
|
|
|
for (int dir = 0; dir < 4; dir++)
|
|
|
|
if (!scene2->_blocked[dir])
|
|
|
|
if (getSceneAt(x + directionsX[dir], y + directionsY[dir]) == scene1)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-01-07 19:22:41 +00:00
|
|
|
} // End of namespace Wage
|