This commit is contained in:
vorenon 2013-03-11 20:06:11 +01:00
commit b700f72a66
25 changed files with 348 additions and 604 deletions

View file

@ -183,7 +183,7 @@ endif()
# find boost without components so we can use Boost_VERSION
find_package(Boost REQUIRED)
set(BOOST_COMPONENTS system filesystem program_options thread)
set(BOOST_COMPONENTS system filesystem program_options thread date_time)
if (Boost_VERSION LESS 104900)
set(SHINY_USE_WAVE_SYSTEM_INSTALL "TRUE")

View file

@ -17,19 +17,6 @@
#include "utils/textinputdialog.hpp"
//sort QModelIndexList ascending
bool rowGreaterThan(const QModelIndex &index1, const QModelIndex &index2)
{
return index1.row() >= index2.row();
}
//sort QModelIndexList descending
bool rowSmallerThan(const QModelIndex &index1, const QModelIndex &index2)
{
return index1.row() <= index2.row();
}
DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent)
: mCfgMgr(cfg)
, mGameSettings(gameSettings)
@ -121,35 +108,15 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam
void DataFilesPage::createActions()
{
// Refresh the plugins
QAction *refreshAction = new QAction(tr("Refresh"), this);
refreshAction->setShortcut(QKeySequence(tr("F5")));
connect(refreshAction, SIGNAL(triggered()), this, SLOT(refresh()));
// We can't create actions inside the .ui file
mNewProfileAction = new QAction(QIcon::fromTheme("document-new"), tr("&New Profile"), this);
mNewProfileAction->setToolTip(tr("New Profile"));
mNewProfileAction->setShortcut(QKeySequence(tr("Ctrl+N")));
connect(mNewProfileAction, SIGNAL(triggered()), this, SLOT(newProfile()));
mDeleteProfileAction = new QAction(QIcon::fromTheme("edit-delete"), tr("Delete Profile"), this);
mDeleteProfileAction->setToolTip(tr("Delete Profile"));
connect(mDeleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile()));
// Add the newly created actions to the toolbuttons
newProfileButton->setDefaultAction(mNewProfileAction);
deleteProfileButton->setDefaultAction(mDeleteProfileAction);
// Add the actions to the toolbuttons
newProfileButton->setDefaultAction(newProfileAction);
deleteProfileButton->setDefaultAction(deleteProfileAction);
// Context menu actions
mCheckAction = new QAction(tr("Check Selection"), this);
connect(mCheckAction, SIGNAL(triggered()), this, SLOT(check()));
mUncheckAction = new QAction(tr("Uncheck Selection"), this);
connect(mUncheckAction, SIGNAL(triggered()), this, SLOT(uncheck()));
mContextMenu = new QMenu(this);
mContextMenu->addAction(mCheckAction);
mContextMenu->addAction(mUncheckAction);
mContextMenu->addAction(checkAction);
mContextMenu->addAction(uncheckAction);
}
void DataFilesPage::setupDataFiles()
@ -184,6 +151,8 @@ void DataFilesPage::setupDataFiles()
profilesComboBox->addItem(QString("Default"));
if (profile.isEmpty() || profile == QLatin1String("Default")) {
deleteProfileAction->setEnabled(false);
profilesComboBox->setEditEnabled(false);
profilesComboBox->setCurrentIndex(profilesComboBox->findText(QString("Default")));
} else {
profilesComboBox->setEditEnabled(true);
@ -257,15 +226,6 @@ void DataFilesPage::saveSettings()
}
void DataFilesPage::newProfile()
{
if (mNewProfileDialog->exec() == QDialog::Accepted) {
QString profile = mNewProfileDialog->lineEdit()->text();
profilesComboBox->addItem(profile);
profilesComboBox->setCurrentIndex(profilesComboBox->findText(profile));
}
}
void DataFilesPage::updateOkButton(const QString &text)
{
// We do this here because we need the profiles combobox text
@ -331,7 +291,16 @@ int DataFilesPage::profilesComboBoxIndex()
return profilesComboBox->currentIndex();
}
void DataFilesPage::deleteProfile()
void DataFilesPage::on_newProfileAction_triggered()
{
if (mNewProfileDialog->exec() == QDialog::Accepted) {
QString profile = mNewProfileDialog->lineEdit()->text();
profilesComboBox->addItem(profile);
profilesComboBox->setCurrentIndex(profilesComboBox->findText(profile));
}
}
void DataFilesPage::on_deleteProfileAction_triggered()
{
QString profile = profilesComboBox->currentText();
@ -358,7 +327,7 @@ void DataFilesPage::deleteProfile()
}
}
void DataFilesPage::check()
void DataFilesPage::on_checkAction_triggered()
{
if (pluginsTable->hasFocus())
setPluginsCheckstates(Qt::Checked);
@ -368,7 +337,7 @@ void DataFilesPage::check()
}
void DataFilesPage::uncheck()
void DataFilesPage::on_uncheckAction_triggered()
{
if (pluginsTable->hasFocus())
setPluginsCheckstates(Qt::Unchecked);
@ -377,14 +346,6 @@ void DataFilesPage::uncheck()
setMastersCheckstates(Qt::Unchecked);
}
void DataFilesPage::refresh()
{
// mDataFilesModel->sort(0);
// Refresh the plugins table
pluginsTable->scrollToTop();
}
void DataFilesPage::setMastersCheckstates(Qt::CheckState state)
{
if (!mastersTable->selectionModel()->hasSelection()) {
@ -476,10 +437,10 @@ void DataFilesPage::profileChanged(const QString &previous, const QString &curre
{
// Prevent the deletion of the default profile
if (current == QLatin1String("Default")) {
mDeleteProfileAction->setEnabled(false);
deleteProfileAction->setEnabled(false);
profilesComboBox->setEditEnabled(false);
} else {
mDeleteProfileAction->setEnabled(true);
deleteProfileAction->setEnabled(true);
profilesComboBox->setEditEnabled(true);
}
@ -533,8 +494,8 @@ void DataFilesPage::showContextMenu(const QPoint &point)
QModelIndexList indexes = pluginsTable->selectionModel()->selectedIndexes();
// Show the check/uncheck actions depending on the state of the selected items
mUncheckAction->setEnabled(false);
mCheckAction->setEnabled(false);
uncheckAction->setEnabled(false);
checkAction->setEnabled(false);
foreach (const QModelIndex &index, indexes)
{
@ -548,8 +509,8 @@ void DataFilesPage::showContextMenu(const QPoint &point)
return;
(mDataFilesModel->checkState(sourceIndex) == Qt::Checked)
? mUncheckAction->setEnabled(true)
: mCheckAction->setEnabled(true);
? uncheckAction->setEnabled(true)
: checkAction->setEnabled(true);
}
// Show menu
@ -564,8 +525,8 @@ void DataFilesPage::showContextMenu(const QPoint &point)
QModelIndexList indexes = mastersTable->selectionModel()->selectedIndexes();
// Show the check/uncheck actions depending on the state of the selected items
mUncheckAction->setEnabled(false);
mCheckAction->setEnabled(false);
uncheckAction->setEnabled(false);
checkAction->setEnabled(false);
foreach (const QModelIndex &index, indexes)
{
@ -578,8 +539,8 @@ void DataFilesPage::showContextMenu(const QPoint &point)
return;
(mDataFilesModel->checkState(sourceIndex) == Qt::Checked)
? mUncheckAction->setEnabled(true)
: mCheckAction->setEnabled(true);
? uncheckAction->setEnabled(true)
: checkAction->setEnabled(true);
}
mContextMenu->exec(globalPos);

View file

@ -48,11 +48,10 @@ public slots:
void updateViews();
// Action slots
void newProfile();
void deleteProfile();
void check();
void uncheck();
void refresh();
void on_newProfileAction_triggered();
void on_deleteProfileAction_triggered();
void on_checkAction_triggered();
void on_uncheckAction_triggered();
private slots:
void slotCurrentIndexChanged(int index);
@ -65,23 +64,7 @@ private:
QSortFilterProxyModel *mFilterProxyModel;
// QTableView *mMastersTable;
// QTableView *mPluginsTable;
// QToolBar *mProfileToolBar;
QMenu *mContextMenu;
// QSplitter *mSplitter;
QAction *mNewProfileAction;
QAction *mDeleteProfileAction;
QAction *mCheckAction;
QAction *mUncheckAction;
// QAction *mMoveUpAction;
// QAction *mMoveDownAction;
// QAction *mMoveTopAction;
// QAction *mMoveBottomAction;
Files::ConfigurationManager &mCfgMgr;

View file

@ -213,8 +213,6 @@ bool MainDialog::showFirstRunDialog()
return false;
// Re-read the game settings
mGameSettings.clear();
if (!setupGameSettings())
return false;
@ -389,7 +387,7 @@ bool MainDialog::setupGameSettings()
QFileInfo info(selectedFile);
// Add the new dir to the settings file and to the data dir container
mGameSettings.setValue(QString("data"), info.absolutePath());
mGameSettings.setMultiValue(QString("data"), info.absolutePath());
mGameSettings.addDataDir(info.absolutePath());
}
@ -478,7 +476,7 @@ void MainDialog::saveSettings()
}
void MainDialog::writeSettings()
bool MainDialog::writeSettings()
{
// Now write all config files
saveSettings();
@ -498,7 +496,7 @@ void MainDialog::writeSettings()
Please make sure you have the right permissions \
and try again.<br>").arg(userPath));
msgBox.exec();
return;
return false;
}
}
@ -515,7 +513,7 @@ void MainDialog::writeSettings()
Please make sure you have the right permissions \
and try again.<br>").arg(file.fileName()));
msgBox.exec();
return;
return false;
}
QTextStream stream(&file);
@ -537,7 +535,7 @@ void MainDialog::writeSettings()
Please make sure you have the right permissions \
and try again.<br>").arg(file.fileName()));
msgBox.exec();
return;
return false;
}
stream.setDevice(&file);
@ -559,7 +557,7 @@ void MainDialog::writeSettings()
Please make sure you have the right permissions \
and try again.<br>").arg(file.fileName()));
msgBox.exec();
return;
return false;
}
stream.setDevice(&file);
@ -567,19 +565,20 @@ void MainDialog::writeSettings()
mLauncherSettings.writeFile(stream);
file.close();
return true;
}
void MainDialog::closeEvent(QCloseEvent *event)
{
saveSettings();
writeSettings();
event->accept();
}
void MainDialog::play()
{
saveSettings();
writeSettings();
if (!writeSettings())
qApp->quit();
// Launch the game detached
startProgram(QString("openmw"), true);

View file

@ -45,7 +45,7 @@ private:
void loadSettings();
void saveSettings();
void writeSettings();
bool writeSettings();
inline bool startProgram(const QString &name, bool detached = false) { return startProgram(name, QStringList(), detached); }
bool startProgram(const QString &name, const QStringList &arguments, bool detached = false);

View file

@ -6,13 +6,12 @@ PlayPage::PlayPage(QWidget *parent) : QWidget(parent)
{
setupUi(this);
// Hacks to get the stylesheet look properly on different platforms
// Hacks to get the stylesheet look properly
#ifdef Q_OS_MAC
QPlastiqueStyle *style = new QPlastiqueStyle;
QFont font = QApplication::font();
font.setPointSize(12); // Fixes problem with overlapping items
profilesComboBox->setStyle(style);
profilesComboBox->setFont(font);
#endif
profilesComboBox->setView(new QListView());
connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int)));
connect(playButton, SIGNAL(clicked()), this, SLOT(slotPlayClicked()));

View file

@ -40,11 +40,6 @@ public:
mSettings.remove(key);
}
inline void clear()
{
mSettings.clear();
}
inline QStringList getDataDirs() { return mDataDirs; }
inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); }
inline QString getDataLocal() {return mDataLocal; }

View file

@ -1,14 +1,14 @@
#include "textinputdialog.hpp"
#include <QDialogButtonBox>
#include <QApplication>
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>
#include <QValidator>
#include <QLabel>
#include <components/fileorderlist/utils/lineedit.hpp>
#include "textinputdialog.hpp"
TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) :
QDialog(parent)
{
@ -38,7 +38,6 @@ TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWid
Q_UNUSED(title);
#endif
setMaximumHeight(height());
setOkButtonEnabled(false);
setModal(true);

View file

@ -149,16 +149,22 @@ OMW::Engine::~Engine()
delete mOgre;
}
// Load all BSA files in data directory.
// Load BSA files
void OMW::Engine::loadBSA()
{
const Files::MultiDirCollection& bsa = mFileCollections.getCollection (".bsa");
for (Files::MultiDirCollection::TIter iter(bsa.begin()); iter!=bsa.end(); ++iter)
for (std::vector<std::string>::const_iterator archive = mArchives.begin(); archive != mArchives.end(); ++archive)
{
std::cout << "Adding " << iter->second.string() << std::endl;
Bsa::addBSA(iter->second.string());
if (mFileCollections.doesExist(*archive))
{
const std::string archivePath = mFileCollections.getPath(*archive).string();
std::cout << "Adding BSA archive " << archivePath << std::endl;
Bsa::addBSA(archivePath);
}
else
{
std::cout << "Archive " << *archive << " not found" << std::endl;
}
}
const Files::PathContainer& dataDirs = mFileCollections.getPaths();
@ -199,6 +205,11 @@ void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs)
mFileCollections = Files::Collections (dataDirs, !mFSStrict);
}
// Add BSA archive
void OMW::Engine::addArchive (const std::string& archive) {
mArchives.push_back(archive);
}
// Set resource dir
void OMW::Engine::setResourceDir (const boost::filesystem::path& parResDir)
{

View file

@ -64,6 +64,7 @@ namespace OMW
ToUTF8::FromType mEncoding;
ToUTF8::Utf8Encoder* mEncoder;
Files::PathContainer mDataDirs;
std::vector<std::string> mArchives;
boost::filesystem::path mResDir;
OEngine::Render::OgreRenderer *mOgre;
std::string mCellName;
@ -99,7 +100,7 @@ namespace OMW
/// add a .zip resource
void addZipResource (const boost::filesystem::path& path);
/// Load all BSA files in data directory.
/// Load BSA files
void loadBSA();
void executeLocalScripts();
@ -126,6 +127,9 @@ namespace OMW
/// Set data dirs
void setDataDirs(const Files::PathContainer& dataDirs);
/// Add BSA archive
void addArchive(const std::string& archive);
/// Set resource dir
void setResourceDir(const boost::filesystem::path& parResDir);

View file

@ -100,6 +100,9 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("data-local", bpo::value<std::string>()->default_value(""),
"set local data directory (highest priority)")
("fallback-archive", bpo::value<StringsVector>()->default_value(StringsVector(), "fallback-archive")
->multitoken(), "set fallback BSA archives (later archives have higher priority)")
("resources", bpo::value<std::string>()->default_value("resources"),
"set resources directory")
@ -201,6 +204,13 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.setDataDirs(dataDirs);
// fallback archives
StringsVector archives = variables["fallback-archive"].as<StringsVector>();
for (StringsVector::const_iterator it = archives.begin(); it != archives.end(); it++)
{
engine.addArchive(*it);
}
engine.setResourceDir(variables["resources"].as<std::string>());
// master and plugin

View file

@ -8,7 +8,7 @@
#include "dialogue.hpp"
#include "mode.hpp"
#include "inventorywindow.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
@ -17,94 +17,24 @@ namespace
{
struct Step
{
const char* mText;
const char* mButtons[3];
const char* mSound;
ESM::Class::Specialization mSpecializations[3]; // The specialization for each answer
const std::string mText;
const std::string mButtons[3];
const std::string mSound;
};
static boost::array<Step, 10> sGenerateClassSteps = { {
// Question 1
{"On a clear day you chance upon a strange animal, its legs trapped in a hunter's clawsnare. Judging from the bleeding, it will not survive long.",
{"Draw your dagger, mercifully endings its life with a single thrust.",
"Use herbs from your pack to put it to sleep.",
"Do not interfere in the natural evolution of events, but rather take the opportunity to learn more about a strange animal that you have never seen before."},
"vo\\misc\\chargen qa1.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 2
{"One Summer afternoon your father gives you a choice of chores.",
{"Work in the forge with him casting iron for a new plow.",
"Gather herbs for your mother who is preparing dinner.",
"Go catch fish at the stream using a net and line."},
"vo\\misc\\chargen qa2.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 3
{"Your cousin has given you a very embarrassing nickname and, even worse, likes to call you it in front of your friends. You asked him to stop, but he finds it very amusing to watch you blush.",
{"Beat up your cousin, then tell him that if he ever calls you that nickname again, you will bloody him worse than this time.",
"Make up a story that makes your nickname a badge of honor instead of something humiliating.",
"Make up an even more embarrassing nickname for him and use it constantly until he learns his lesson."},
"vo\\misc\\chargen qa3.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 4
{"There is a lot of heated discussion at the local tavern over a grouped of people called 'Telepaths'. They have been hired by certain City-State kings. Rumor has it these Telepaths read a person's mind and tell their lord whether a follower is telling the truth or not.",
{"This is a terrible practice. A person's thoughts are his own and no one, not even a king, has the right to make such an invasion into another human's mind.",
"Loyal followers to the king have nothing to fear from a Telepath. It is important to have a method of finding assassins and spies before it is too late.",
"In these times, it is a necessary evil. Although you do not necessarily like the idea, a Telepath could have certain advantages during a time of war or in finding someone innocent of a crime."},
"vo\\misc\\chargen qa4.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 5
{"Your mother sends you to the market with a list of goods to buy. After you finish you find that by mistake a shopkeeper has given you too much money back in exchange for one of the items.",
{"Return to the store and give the shopkeeper his hard-earned money, explaining to him the mistake?",
"Decide to put the extra money to good use and purchase items that would help your family?",
"Pocket the extra money, knowing that shopkeepers in general tend to overcharge customers anyway?"},
"vo\\misc\\chargen qa5.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 6
{"While in the market place you witness a thief cut a purse from a noble. Even as he does so, the noble notices and calls for the city guards. In his haste to get away, the thief drops the purse near you. Surprisingly no one seems to notice the bag of coins at your feet.",
{"Pick up the bag and signal to the guard, knowing that the only honorable thing to do is return the money to its rightful owner.",
"Leave the bag there, knowing that it is better not to get involved.",
"Pick up the bag and pocket it, knowing that the extra windfall will help your family in times of trouble."},
"vo\\misc\\chargen qa6.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 7
{"Your father sends you on a task which you loathe, cleaning the stables. On the way there, pitchfork in hand, you run into your friend from the homestead near your own. He offers to do it for you, in return for a future favor of his choosing.",
{"Decline his offer, knowing that your father expects you to do the work, and it is better not to be in debt.",
"Ask him to help you, knowing that two people can do the job faster than one, and agree to help him with one task of his choosing in the future.",
"Accept his offer, reasoning that as long as the stables are cleaned, it matters not who does the cleaning."},
"vo\\misc\\chargen qa7.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 8
{"Your mother asks you to help fix the stove. While you are working, a very hot pipe slips its mooring and falls towards her.",
{"Position yourself between the pipe and your mother.",
"Grab the hot pipe and try to push it away.",
"Push your mother out of the way."},
"vo\\misc\\chargen qa8.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 9
{"While in town the baker gives you a sweetroll. Delighted, you take it into an alley to enjoy only to be intercepted by a gang of three other kids your age. The leader demands the sweetroll, or else he and his friends will beat you and take it.",
{"Drop the sweetroll and step on it, then get ready for the fight.",
"Give him the sweetroll now without argument, knowing that later this afternoon you will have all your friends with you and can come and take whatever he owes you.",
"Act like you're going to give him the sweetroll, but at the last minute throw it in the air, hoping that they'll pay attention to it long enough for you to get a shot in on the leader."},
"vo\\misc\\chargen qa9.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 10
{"Entering town you find that you are witness to a very well-dressed man running from a crowd. He screams to you for help. The crowd behind him seem very angry.",
{"Rush to the town's aid immediately, despite your lack of knowledge of the circumstances.",
"Stand aside and allow the man and the mob to pass, realizing it is probably best not to get involved.",
"Rush to the man's aid immediately, despite your lack of knowledge of the circumstances."},
"vo\\misc\\chargen qa10.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
}
} };
const ESM::Class::Specialization mSpecializations[3]={ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}; // The specialization for each answer
Step sGenerateClassSteps(int number) {
MWBase::World *world = MWBase::Environment::get().getWorld();
number++;
Step step = {world->getFallback("Question_"+boost::lexical_cast<std::string>(number)+"_Question"),
{world->getFallback("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerOne"),
world->getFallback("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerTwo"),
world->getFallback("Question_"+boost::lexical_cast<std::string>(number)+"_AnswerThree")},
"vo\\misc\\chargen qa"+boost::lexical_cast<std::string>(number)+".wav"
};
return step;
}
struct ClassPoint
{
@ -638,7 +568,7 @@ void CharacterCreation::onClassQuestionChosen(int _index)
return;
}
ESM::Class::Specialization specialization = sGenerateClassSteps[mGenerateClassStep].mSpecializations[_index];
ESM::Class::Specialization specialization = mSpecializations[_index];
if (specialization == ESM::Class::Stealth)
++mGenerateClassSpecializations[0];
else if (specialization == ESM::Class::Combat)
@ -651,7 +581,7 @@ void CharacterCreation::onClassQuestionChosen(int _index)
void CharacterCreation::showClassQuestionDialog()
{
if (mGenerateClassStep == sGenerateClassSteps.size())
if (mGenerateClassStep == 10)
{
static boost::array<ClassPoint, 23> classes = { {
{"Acrobat", {6, 2, 2}},
@ -718,7 +648,7 @@ void CharacterCreation::showClassQuestionDialog()
return;
}
if (mGenerateClassStep > sGenerateClassSteps.size())
if (mGenerateClassStep > 10)
{
mWM->popGuiMode();
mWM->pushGuiMode(GM_Class);
@ -731,15 +661,15 @@ void CharacterCreation::showClassQuestionDialog()
mGenerateClassQuestionDialog = new InfoBoxDialog(*mWM);
InfoBoxDialog::ButtonList buttons;
mGenerateClassQuestionDialog->setText(sGenerateClassSteps[mGenerateClassStep].mText);
buttons.push_back(sGenerateClassSteps[mGenerateClassStep].mButtons[0]);
buttons.push_back(sGenerateClassSteps[mGenerateClassStep].mButtons[1]);
buttons.push_back(sGenerateClassSteps[mGenerateClassStep].mButtons[2]);
mGenerateClassQuestionDialog->setText(sGenerateClassSteps(mGenerateClassStep).mText);
buttons.push_back(sGenerateClassSteps(mGenerateClassStep).mButtons[0]);
buttons.push_back(sGenerateClassSteps(mGenerateClassStep).mButtons[1]);
buttons.push_back(sGenerateClassSteps(mGenerateClassStep).mButtons[2]);
mGenerateClassQuestionDialog->setButtons(buttons);
mGenerateClassQuestionDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen);
mGenerateClassQuestionDialog->setVisible(true);
MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps[mGenerateClassStep].mSound);
MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps(mGenerateClassStep).mSound);
}
void CharacterCreation::onGenerateClassBack()

View file

@ -162,7 +162,8 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
mBounds.merge(Vector3(c4.x, c4.y, 0));
// apply a little padding
mBounds.scale ((mBounds.getSize ()+Ogre::Vector3(1000,1000,0)) / mBounds.getSize ());
mBounds.setMinimum (mBounds.getMinimum() - Vector3(500,500,0));
mBounds.setMaximum (mBounds.getMaximum() + Vector3(500,500,0));
Vector2 center(mBounds.getCenter().x, mBounds.getCenter().y);

View file

@ -21,7 +21,7 @@ namespace
template<typename T>
void insertCellRefList(MWRender::RenderingManager& rendering,
T& cellRefList, MWWorld::CellStore &cell, MWWorld::PhysicsSystem& physics)
T& cellRefList, MWWorld::CellStore &cell, MWWorld::PhysicsSystem& physics, bool rescale)
{
if (!cellRefList.mList.empty())
{
@ -31,6 +31,14 @@ namespace
for (typename T::List::iterator it = cellRefList.mList.begin();
it != cellRefList.mList.end(); it++)
{
if (rescale)
{
if (it->mRef.mScale<0.5)
it->mRef.mScale = 0.5;
else if (it->mRef.mScale>2)
it->mRef.mScale = 2;
}
++current;
if (it->mData.getCount() || it->mData.isEnabled())
@ -68,7 +76,7 @@ namespace MWWorld
{
std::cout << "Unloading cell\n";
ListHandles functor;
(*iter)->forEach<ListHandles>(functor);
{
// silence annoying g++ warning
@ -107,7 +115,9 @@ namespace MWWorld
if(result.second)
{
insertCell(*cell);
/// \todo rescale depending on the state of a new GMST
insertCell (*cell, true);
mRendering.cellAdded (cell);
float verts = ESM::Land::LAND_SIZE;
@ -335,7 +345,7 @@ namespace MWWorld
bool loadcell = (mCurrentCell == NULL);
if(!loadcell)
loadcell = *mCurrentCell != *cell;
if(!loadcell)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
@ -347,7 +357,7 @@ namespace MWWorld
world->rotateObject(world->getPlayer().getPlayer(), x, y, z);
return;
}
std::cout << "Changing to interior\n";
// remove active
@ -383,7 +393,7 @@ namespace MWWorld
// adjust fog
mRendering.switchToInterior();
mRendering.configureFog(*mCurrentCell);
// adjust player
playerCellChange (mCurrentCell, position);
@ -415,29 +425,29 @@ namespace MWWorld
mCellChanged = false;
}
void Scene::insertCell (Ptr::CellStore &cell)
void Scene::insertCell (Ptr::CellStore &cell, bool rescale)
{
// Loop through all references in the cell
insertCellRefList(mRendering, cell.mActivators, cell, *mPhysics);
insertCellRefList(mRendering, cell.mPotions, cell, *mPhysics);
insertCellRefList(mRendering, cell.mAppas, cell, *mPhysics);
insertCellRefList(mRendering, cell.mArmors, cell, *mPhysics);
insertCellRefList(mRendering, cell.mBooks, cell, *mPhysics);
insertCellRefList(mRendering, cell.mClothes, cell, *mPhysics);
insertCellRefList(mRendering, cell.mContainers, cell, *mPhysics);
insertCellRefList(mRendering, cell.mCreatures, cell, *mPhysics);
insertCellRefList(mRendering, cell.mDoors, cell, *mPhysics);
insertCellRefList(mRendering, cell.mIngreds, cell, *mPhysics);
insertCellRefList(mRendering, cell.mCreatureLists, cell, *mPhysics);
insertCellRefList(mRendering, cell.mItemLists, cell, *mPhysics);
insertCellRefList(mRendering, cell.mLights, cell, *mPhysics);
insertCellRefList(mRendering, cell.mLockpicks, cell, *mPhysics);
insertCellRefList(mRendering, cell.mMiscItems, cell, *mPhysics);
insertCellRefList(mRendering, cell.mNpcs, cell, *mPhysics);
insertCellRefList(mRendering, cell.mProbes, cell, *mPhysics);
insertCellRefList(mRendering, cell.mRepairs, cell, *mPhysics);
insertCellRefList(mRendering, cell.mStatics, cell, *mPhysics);
insertCellRefList(mRendering, cell.mWeapons, cell, *mPhysics);
insertCellRefList(mRendering, cell.mActivators, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mPotions, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mAppas, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mArmors, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mBooks, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mClothes, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mContainers, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mCreatures, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mDoors, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mIngreds, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mCreatureLists, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mItemLists, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mLights, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mLockpicks, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mMiscItems, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mNpcs, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mProbes, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mRepairs, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mStatics, cell, *mPhysics, rescale);
insertCellRefList(mRendering, cell.mWeapons, cell, *mPhysics, rescale);
}
void Scene::addObjectToScene (const Ptr& ptr)

View file

@ -56,6 +56,7 @@ namespace MWWorld
void playerCellChange (CellStore *cell, const ESM::Position& position,
bool adjustPlayerPos = true);
void insertCell (Ptr::CellStore &cell, bool rescale);
public:
@ -86,8 +87,6 @@ namespace MWWorld
void markCellAsUnchanged();
void insertCell (Ptr::CellStore &cell);
void update (float duration, bool paused);
void addObjectToScene (const Ptr& ptr);

View file

@ -4,7 +4,7 @@
#include <cstdlib>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
@ -19,262 +19,125 @@ using namespace MWWorld;
using namespace MWSound;
#define lerp(x, y) (x * (1-factor) + y * factor)
std::string WeatherManager::getFallback (const std::string& key) const
{
std::map<std::string,std::string>::const_iterator it;
if((it = mFallback.find(key)) == mFallback.end())
{
return "";
}
return it->second;
}
std::string WeatherManager::getFallbackString(const std::string& fall) const
{
return getFallback(fall);
}
const std::string WeatherGlobals::mThunderSoundID0 = "Thunder0";
const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1";
const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2";
const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3";
const float WeatherGlobals::mSunriseTime = 8;
const float WeatherGlobals::mSunsetTime = 18;
const float WeatherGlobals::mSunriseDuration = 2;
const float WeatherGlobals::mSunsetDuration = 2;
const float WeatherGlobals::mWeatherUpdateTime = 20.f;
float WeatherManager::getFallbackFloat(const std::string& fall) const
{
std::string fallback=getFallbackString(fall);
return boost::lexical_cast<float>(fallback);
}
ColourValue WeatherManager::getFallbackColour(const std::string& fall) const
{
std::string sum;
std::string ret[3];
sum=getFallback(fall);
unsigned int j=0;
for(unsigned int i=0;i<sum.length();i++){
if(sum[i]==',') j++;
else ret[j]+=sum[i];
}
return ColourValue(boost::lexical_cast<int>(ret[0])/255.f,boost::lexical_cast<int>(ret[1])/255.f,boost::lexical_cast<int>(ret[2])/255.f);
}
void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name)
{
std::string upper=name;
upper[0]=toupper(name[0]);
weather.mCloudsMaximumPercent = getFallbackFloat("Weather_"+upper+"_Clouds_Maximum_Percent");
weather.mTransitionDelta = getFallbackFloat("Weather_"+upper+"_Transition_Delta");
weather.mSkySunriseColor=getFallbackColour("Weather_"+upper+"_Sky_Sunrise_Color");
weather.mSkyDayColor = getFallbackColour("Weather_"+upper+"_Sky_Day_Color");
weather.mSkySunsetColor = getFallbackColour("Weather_"+upper+"_Sky_Sunset_Color");
weather.mSkyNightColor = getFallbackColour("Weather_"+upper+"_Sky_Night_Color");
weather.mFogSunriseColor = getFallbackColour("Weather_"+upper+"_Fog_Sunrise_Color");
weather.mFogDayColor = getFallbackColour("Weather_"+upper+"_Fog_Day_Color");
weather.mFogSunsetColor = getFallbackColour("Weather_"+upper+"_Fog_Sunset_Color");
weather.mFogNightColor = getFallbackColour("Weather_"+upper+"_Fog_Night_Color");
weather.mAmbientSunriseColor = getFallbackColour("Weather_"+upper+"_Ambient_Sunrise_Color");
weather.mAmbientDayColor = getFallbackColour("Weather_"+upper+"_Ambient_Day_Color");
weather.mAmbientSunsetColor = getFallbackColour("Weather_"+upper+"_Ambient_Sunset_Color");
weather.mAmbientNightColor = getFallbackColour("Weather_"+upper+"_Ambient_Night_Color");
weather.mSunSunriseColor = getFallbackColour("Weather_"+upper+"_Sun_Sunrise_Color");
weather.mSunDayColor = getFallbackColour("Weather_"+upper+"_Sun_Day_Color");
weather.mSunSunsetColor = getFallbackColour("Weather_"+upper+"_Sun_Sunset_Color");
weather.mSunNightColor = getFallbackColour("Weather_"+upper+"_Sun_Night_Color");
weather.mSunDiscSunsetColor = getFallbackColour("Weather_"+upper+"_Sun_Disc_Sunset_Color");
weather.mLandFogDayDepth = getFallbackFloat("Weather_"+upper+"_Land_Fog_Day_Depth");
weather.mLandFogNightDepth = getFallbackFloat("Weather_"+upper+"_Land_Fog_Night_Depth");
weather.mWindSpeed = getFallbackFloat("Weather_"+upper+"_Wind_Speed");
weather.mCloudSpeed = getFallbackFloat("Weather_"+upper+"_Cloud_Speed");
weather.mGlareView = getFallbackFloat("Weather_"+upper+"_Glare_View");
mWeatherSettings[name] = weather;
}
// morrowind sets these per-weather, but since they are only used by 'thunderstorm'
// weather setting anyway, we can just as well set them globally
const float WeatherGlobals::mThunderFrequency = .4;
const float WeatherGlobals::mThunderThreshold = 0.6;
const float WeatherGlobals::mThunderSoundDelay = 0.25;
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering) :
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,const std::map<std::string,std::string>& fallbackMap) :
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0),
mRemainingTransitionTime(0), mMonth(0), mDay(0),
mTimePassed(0)
mTimePassed(0), mFallback(fallbackMap)
{
mRendering = rendering;
#define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f)
/// \todo read these from Morrowind.ini
//Globals
mThunderSoundID0 = getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0");
mThunderSoundID1 = getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_1");
mThunderSoundID2 = getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_2");
mThunderSoundID3 = getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_3");
mSunriseTime = getFallbackFloat("Weather_Sunrise_Time");
mSunsetTime = getFallbackFloat("Weather_Sunset_Time");
mSunriseDuration = getFallbackFloat("Weather_Sunrise_Duration");
mSunsetDuration = getFallbackFloat("Weather_Sunset_Duration");
mWeatherUpdateTime = getFallbackFloat("Weather_Hours_Between_Weather_Changes");
mThunderFrequency = getFallbackFloat("Weather_Thunderstorm_Thunder_Frequency");
mThunderThreshold = getFallbackFloat("Weather_Thunderstorm_Thunder_Threshold");
mThunderSoundDelay = 0.25;
//Weather
Weather clear;
clear.mCloudTexture = "tx_sky_clear.dds";
clear.mCloudsMaximumPercent = 1.0;
clear.mTransitionDelta = 0.015;
clear.mSkySunriseColor = clr(118, 141, 164);
clear.mSkyDayColor = clr(95, 135, 203);
clear.mSkySunsetColor = clr(56, 89, 129);
clear.mSkyNightColor = clr(9, 10, 11);
clear.mFogSunriseColor = clr(255, 189, 157);
clear.mFogDayColor = clr(206, 227, 255);
clear.mFogSunsetColor = clr(255, 189, 157);
clear.mFogNightColor = clr(9, 10, 11);
clear.mAmbientSunriseColor = clr(47, 66, 96);
clear.mAmbientDayColor = clr(137, 140, 160);
clear.mAmbientSunsetColor = clr(68, 75, 96);
clear.mAmbientNightColor = clr(32, 35, 42);
clear.mSunSunriseColor = clr(242, 159, 99);
clear.mSunDayColor = clr(255, 252, 238);
clear.mSunSunsetColor = clr(255, 115, 79);
clear.mSunNightColor = clr(59, 97, 176);
clear.mSunDiscSunsetColor = clr(255, 189, 157);
clear.mLandFogDayDepth = 0.69;
clear.mLandFogNightDepth = 0.69;
clear.mWindSpeed = 0.1;
clear.mCloudSpeed = 1.25;
clear.mGlareView = 1.0;
mWeatherSettings["clear"] = clear;
setFallbackWeather(clear,"clear");
Weather cloudy;
cloudy.mCloudTexture = "tx_sky_cloudy.dds";
cloudy.mCloudsMaximumPercent = 1.0;
cloudy.mTransitionDelta = 0.015;
cloudy.mSkySunriseColor = clr(126, 158, 173);
cloudy.mSkyDayColor = clr(117, 160, 215);
cloudy.mSkySunsetColor = clr(111, 114, 159);
cloudy.mSkyNightColor = clr(9, 10, 11);
cloudy.mFogSunriseColor = clr(255, 207, 149);
cloudy.mFogDayColor = clr(245, 235, 224);
cloudy.mFogSunsetColor = clr(255, 155, 106);
cloudy.mFogNightColor = clr(9, 10, 11);
cloudy.mAmbientSunriseColor = clr(66, 74, 87);
cloudy.mAmbientDayColor = clr(137, 145, 160);
cloudy.mAmbientSunsetColor = clr(71, 80, 92);
cloudy.mAmbientNightColor = clr(32, 39, 54);
cloudy.mSunSunriseColor = clr(241, 177, 99);
cloudy.mSunDayColor = clr(255, 236, 221);
cloudy.mSunSunsetColor = clr(255, 89, 00);
cloudy.mSunNightColor = clr(77, 91, 124);
cloudy.mSunDiscSunsetColor = clr(255, 202, 179);
cloudy.mLandFogDayDepth = 0.72;
cloudy.mLandFogNightDepth = 0.72;
cloudy.mWindSpeed = 0.2;
cloudy.mCloudSpeed = 2;
cloudy.mGlareView = 1.0;
mWeatherSettings["cloudy"] = cloudy;
setFallbackWeather(cloudy,"cloudy");
Weather foggy;
foggy.mCloudTexture = "tx_sky_foggy.dds";
foggy.mCloudsMaximumPercent = 1.0;
foggy.mTransitionDelta = 0.015;
foggy.mSkySunriseColor = clr(197, 190, 180);
foggy.mSkyDayColor = clr(184, 211, 228);
foggy.mSkySunsetColor = clr(142, 159, 176);
foggy.mSkyNightColor = clr(18, 23, 28);
foggy.mFogSunriseColor = clr(173, 164, 148);
foggy.mFogDayColor = clr(150, 187, 209);
foggy.mFogSunsetColor = clr(113, 135, 157);
foggy.mFogNightColor = clr(19, 24, 29);
foggy.mAmbientSunriseColor = clr(48, 43, 37);
foggy.mAmbientDayColor = clr(92, 109, 120);
foggy.mAmbientSunsetColor = clr(28, 33, 39);
foggy.mAmbientNightColor = clr(28, 33, 39);
foggy.mSunSunriseColor = clr(177, 162, 137);
foggy.mSunDayColor = clr(111, 131, 151);
foggy.mSunSunsetColor = clr(125, 157, 189);
foggy.mSunNightColor = clr(81, 100, 119);
foggy.mSunDiscSunsetColor = clr(223, 223, 223);
foggy.mLandFogDayDepth = 1.0;
foggy.mLandFogNightDepth = 1.9;
foggy.mWindSpeed = 0;
foggy.mCloudSpeed = 1.25;
foggy.mGlareView = 0.25;
mWeatherSettings["foggy"] = foggy;
setFallbackWeather(foggy,"foggy");
Weather thunderstorm;
thunderstorm.mCloudTexture = "tx_sky_thunder.dds";
thunderstorm.mCloudsMaximumPercent = 0.66;
thunderstorm.mTransitionDelta = 0.03;
thunderstorm.mSkySunriseColor = clr(35, 36, 39);
thunderstorm.mSkyDayColor = clr(97, 104, 115);
thunderstorm.mSkySunsetColor = clr(35, 36, 39);
thunderstorm.mSkyNightColor = clr(19, 20, 22);
thunderstorm.mFogSunriseColor = clr(70, 74, 85);
thunderstorm.mFogDayColor = clr(97, 104, 115);
thunderstorm.mFogSunsetColor = clr(70, 74, 85);
thunderstorm.mFogNightColor = clr(19, 20, 22);
thunderstorm.mAmbientSunriseColor = clr(54, 54, 54);
thunderstorm.mAmbientDayColor = clr(90, 90, 90);
thunderstorm.mAmbientSunsetColor = clr(54, 54, 54);
thunderstorm.mAmbientNightColor = clr(49, 51, 54);
thunderstorm.mSunSunriseColor = clr(91, 99, 122);
thunderstorm.mSunDayColor = clr(138, 144, 155);
thunderstorm.mSunSunsetColor = clr(96, 101, 117);
thunderstorm.mSunNightColor = clr(55, 76, 110);
thunderstorm.mSunDiscSunsetColor = clr(128, 128, 128);
thunderstorm.mLandFogDayDepth = 1;
thunderstorm.mLandFogNightDepth = 1.15;
thunderstorm.mWindSpeed = 0.5;
thunderstorm.mCloudSpeed = 3;
thunderstorm.mGlareView = 0;
thunderstorm.mRainLoopSoundID = "rain heavy";
mWeatherSettings["thunderstorm"] = thunderstorm;
setFallbackWeather(thunderstorm,"thunderstorm");
Weather rain;
rain.mCloudTexture = "tx_sky_rainy.dds";
rain.mCloudsMaximumPercent = 0.66;
rain.mTransitionDelta = 0.015;
rain.mSkySunriseColor = clr(71, 74, 75);
rain.mSkyDayColor = clr(116, 120, 122);
rain.mSkySunsetColor = clr(73, 73, 73);
rain.mSkyNightColor = clr(24, 25, 26);
rain.mFogSunriseColor = clr(71, 74, 75);
rain.mFogDayColor = clr(116, 120, 122);
rain.mFogSunsetColor = clr(73, 73, 73);
rain.mFogNightColor = clr(24, 25, 26);
rain.mAmbientSunriseColor = clr(97, 90, 88);
rain.mAmbientDayColor = clr(105, 110, 113);
rain.mAmbientSunsetColor = clr(88, 97, 97);
rain.mAmbientNightColor = clr(50, 55, 67);
rain.mSunSunriseColor = clr(131, 122, 120);
rain.mSunDayColor = clr(149, 157, 170);
rain.mSunSunsetColor = clr(120, 126, 131);
rain.mSunNightColor = clr(50, 62, 101);
rain.mSunDiscSunsetColor = clr(128, 128, 128);
rain.mLandFogDayDepth = 0.8;
rain.mLandFogNightDepth = 0.8;
rain.mWindSpeed = 0.3;
rain.mCloudSpeed = 2;
rain.mGlareView = 0;
rain.mRainLoopSoundID = "rain";
mWeatherSettings["rain"] = rain;
setFallbackWeather(rain,"rain");
Weather overcast;
overcast.mCloudTexture = "tx_sky_overcast.dds";
overcast.mCloudsMaximumPercent = 1.0;
overcast.mTransitionDelta = 0.015;
overcast.mSkySunriseColor = clr(91, 99, 106);
overcast.mSkyDayColor = clr(143, 146, 149);
overcast.mSkySunsetColor = clr(108, 115, 121);
overcast.mSkyNightColor = clr(19, 22, 25);
overcast.mFogSunriseColor = clr(91, 99, 106);
overcast.mFogDayColor = clr(143, 146, 149);
overcast.mFogSunsetColor = clr(108, 115, 121);
overcast.mFogNightColor = clr(19, 22, 25);
overcast.mAmbientSunriseColor = clr(84, 88, 92);
overcast.mAmbientDayColor = clr(93, 96, 105);
overcast.mAmbientSunsetColor = clr(83, 77, 75);
overcast.mAmbientNightColor = clr(57, 60, 66);
overcast.mSunSunriseColor = clr(87, 125, 163);
overcast.mSunDayColor = clr(163, 169, 183);
overcast.mSunSunsetColor = clr(85, 103, 157);
overcast.mSunNightColor = clr(32, 54, 100);
overcast.mSunDiscSunsetColor = clr(128, 128, 128);
overcast.mLandFogDayDepth = 0.7;
overcast.mLandFogNightDepth = 0.7;
overcast.mWindSpeed = 0.2;
overcast.mCloudSpeed = 1.5;
overcast.mGlareView = 0;
mWeatherSettings["overcast"] = overcast;
setFallbackWeather(overcast,"overcast");
Weather ashstorm;
ashstorm.mCloudTexture = "tx_sky_ashstorm.dds";
ashstorm.mCloudsMaximumPercent = 1.0;
ashstorm.mTransitionDelta = 0.035;
ashstorm.mSkySunriseColor = clr(91, 56, 51);
ashstorm.mSkyDayColor = clr(124, 73, 58);
ashstorm.mSkySunsetColor = clr(106, 55, 40);
ashstorm.mSkyNightColor = clr(20, 21, 22);
ashstorm.mFogSunriseColor = clr(91, 56, 51);
ashstorm.mFogDayColor = clr(124, 73, 58);
ashstorm.mFogSunsetColor = clr(106, 55, 40);
ashstorm.mFogNightColor = clr(20, 21, 22);
ashstorm.mAmbientSunriseColor = clr(52, 42, 37);
ashstorm.mAmbientDayColor = clr(75, 49, 41);
ashstorm.mAmbientSunsetColor = clr(48, 39, 35);
ashstorm.mAmbientNightColor = clr(36, 42, 49);
ashstorm.mSunSunriseColor = clr(184, 91, 71);
ashstorm.mSunDayColor = clr(228, 139, 114);
ashstorm.mSunSunsetColor = clr(185, 86, 57);
ashstorm.mSunNightColor = clr(54, 66, 74);
ashstorm.mSunDiscSunsetColor = clr(128, 128, 128);
ashstorm.mLandFogDayDepth = 1.1;
ashstorm.mLandFogNightDepth = 1.2;
ashstorm.mWindSpeed = 0.8;
ashstorm.mCloudSpeed = 7;
ashstorm.mGlareView = 0;
ashstorm.mAmbientLoopSoundID = "ashstorm";
mWeatherSettings["ashstorm"] = ashstorm;
setFallbackWeather(ashstorm,"ashstorm");
Weather blight;
blight.mCloudTexture = "tx_sky_blight.dds";
blight.mCloudsMaximumPercent = 1.0;
blight.mTransitionDelta = 0.04;
blight.mSkySunriseColor = clr(90, 35, 35);
blight.mSkyDayColor = clr(90, 35, 35);
blight.mSkySunsetColor = clr(92, 33, 33);
blight.mSkyNightColor = clr(44, 14, 14);
blight.mFogSunriseColor = clr(90, 35, 35);
blight.mFogDayColor = clr(128, 19, 19);
blight.mFogSunsetColor = clr(92, 33, 33);
blight.mFogNightColor = clr(44, 14, 14);
blight.mAmbientSunriseColor = clr(61, 40, 40);
blight.mAmbientDayColor = clr(79, 54, 54);
blight.mAmbientSunsetColor = clr(61, 40, 40);
blight.mAmbientNightColor = clr(56, 58, 62);
blight.mSunSunriseColor = clr(180, 78, 78);
blight.mSunDayColor = clr(224, 84, 84);
blight.mSunSunsetColor = clr(180, 78, 78);
blight.mSunNightColor = clr(61, 91, 143);
blight.mSunDiscSunsetColor = clr(128, 128, 128);
blight.mLandFogDayDepth = 1.1;
blight.mLandFogNightDepth = 1.2;
blight.mWindSpeed = 0.9;
blight.mCloudSpeed = 9;
blight.mGlareView = 0;
blight.mAmbientLoopSoundID = "blight";
mWeatherSettings["blight"] = blight;
setFallbackWeather(blight,"blight");
/*
Weather snow;
@ -502,7 +365,7 @@ void WeatherManager::update(float duration)
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
{
mCurrentRegion = regionstr;
mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*3600;
mWeatherUpdateTime = mWeatherUpdateTime*3600;
std::string weather = "clear";
@ -681,17 +544,17 @@ void WeatherManager::update(float duration)
// pick a random sound
int sound = rand() % 4;
std::string soundname;
if (sound == 0) soundname = WeatherGlobals::mThunderSoundID0;
else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1;
else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2;
else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3;
if (sound == 0) soundname = mThunderSoundID0;
else if (sound == 1) soundname = mThunderSoundID1;
else if (sound == 2) soundname = mThunderSoundID2;
else if (sound == 3) soundname = mThunderSoundID3;
MWBase::Environment::get().getSoundManager()->playSound(soundname, 1.0, 1.0);
mThunderSoundDelay = 1000;
}
mThunderFlash -= duration;
if (mThunderFlash > 0)
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / WeatherGlobals::mThunderThreshold );
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
else
{
srand(time(NULL));
@ -706,11 +569,11 @@ void WeatherManager::update(float duration)
mThunderChance += duration*4; // chance increases by 4 percent every second
if (mThunderChance >= mThunderChanceNeeded)
{
mThunderFlash = WeatherGlobals::mThunderThreshold;
mThunderFlash = mThunderThreshold;
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / WeatherGlobals::mThunderThreshold );
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay;
mThunderSoundDelay = 0.25;
}
}
}

View file

@ -11,106 +11,6 @@ namespace MWRender
namespace MWWorld
{
/// Global weather manager properties (according to INI)
struct WeatherGlobals
{
/*
[Weather]
EnvReduceColor=255,255,255,255
LerpCloseColor=037,046,048,255
BumpFadeColor=230,239,255,255
AlphaReduce=0.35
Minimum Time Between Environmental Sounds=1.0
Maximum Time Between Environmental Sounds=5.0
Sun Glare Fader Max=0.5
Sun Glare Fader Angle Max=30.0
Sun Glare Fader Color=222,095,039
Timescale Clouds=0
Precip Gravity=575
Hours Between Weather Changes=20
Rain Ripples=1
Rain Ripple Radius=1024
Rain Ripples Per Drop=1
Rain Ripple Scale=0.3
Rain Ripple Speed=1.0
Fog Depth Change Speed=3
Sunrise Time=6
Sunset Time=18
Sunrise Duration=2
Sunset Duration=2
Sky Pre-Sunrise Time=.5
Sky Post-Sunrise Time=1
Sky Pre-Sunset Time=1.5
Sky Post-Sunset Time=.5
Ambient Pre-Sunrise Time=.5
Ambient Post-Sunrise Time=2
Ambient Pre-Sunset Time=1
Ambient Post-Sunset Time=1.25
Fog Pre-Sunrise Time=.5
Fog Post-Sunrise Time=1
Fog Pre-Sunset Time=2
Fog Post-Sunset Time=1
Sun Pre-Sunrise Time=0
Sun Post-Sunrise Time=0
Sun Pre-Sunset Time=1
Sun Post-Sunset Time=1.25
Stars Post-Sunset Start=1
Stars Pre-Sunrise Finish=2
Stars Fading Duration=2
Snow Ripples=0
Snow Ripple Radius=1024
Snow Ripples Per Flake=1
Snow Ripple Scale=0.3
Snow Ripple Speed=1.0
Snow Gravity Scale=0.1
Snow High Kill=700
Snow Low Kill=150
[Moons]
Masser Size=94
Masser Fade In Start=14
Masser Fade In Finish=15
Masser Fade Out Start=7
Masser Fade Out Finish=10
Masser Axis Offset=35
Masser Speed=.5
Masser Daily Increment=1
Masser Fade Start Angle=50
Masser Fade End Angle=40
Masser Moon Shadow Early Fade Angle=0.5
Secunda Size=40
Secunda Fade In Start=14
Secunda Fade In Finish=15
Secunda Fade Out Start=7
Secunda Fade Out Finish=10
Secunda Axis Offset=50
Secunda Speed=.6
Secunda Daily Increment=1.2
Secunda Fade Start Angle=50
Secunda Fade End Angle=30
Secunda Moon Shadow Early Fade Angle=0.5
Script Color=255,20,20
*/
static const float mSunriseTime;
static const float mSunsetTime;
static const float mSunriseDuration;
static const float mSunsetDuration;
static const float mWeatherUpdateTime;
// morrowind sets these per-weather, but since they are only used by 'thunderstorm'
// weather setting anyway, we can just as well set them globally
static const float mThunderFrequency;
static const float mThunderThreshold;
static const float mThunderSoundDelay;
static const std::string mThunderSoundID0;
static const std::string mThunderSoundID1;
static const std::string mThunderSoundID2;
static const std::string mThunderSoundID3;
};
/// Defines the actual weather that results from weather setting (see below), time of day and weather transition
struct WeatherResult
{
@ -212,7 +112,7 @@ namespace MWWorld
class WeatherManager
{
public:
WeatherManager(MWRender::RenderingManager*);
WeatherManager(MWRender::RenderingManager*,const std::map<std::string,std::string>& fallbackMap);
/**
* Change the weather in the specified region
@ -241,7 +141,12 @@ namespace MWWorld
private:
float mHour;
int mDay, mMonth;
std::map<std::string,std::string> mFallback;
std::string getFallback (const std::string& key) const;
std::string getFallbackString(const std::string& fall) const;
float getFallbackFloat(const std::string& fall) const;
Ogre::ColourValue getFallbackColour(const std::string& fall) const;
void setFallbackWeather(Weather& weather,const std::string& name);
MWRender::RenderingManager* mRendering;
std::map<Ogre::String, Weather> mWeatherSettings;
@ -257,14 +162,11 @@ namespace MWWorld
bool mFirstUpdate;
float mWeatherUpdateTime;
float mRemainingTransitionTime;
float mThunderFlash;
float mThunderChance;
float mThunderChanceNeeded;
float mThunderSoundDelay;
double mTimePassed; // time passed since last update
@ -272,6 +174,18 @@ namespace MWWorld
WeatherResult getResult(const Ogre::String& weather);
void setWeather(const Ogre::String& weather, bool instant=false);
float mSunriseTime;
float mSunsetTime;
float mSunriseDuration;
float mSunsetDuration;
float mWeatherUpdateTime;
float mThunderFrequency;
float mThunderThreshold;
float mThunderSoundDelay;
std::string mThunderSoundID0;
std::string mThunderSoundID1;
std::string mThunderSoundID2;
std::string mThunderSoundID3;
};
}

View file

@ -191,7 +191,7 @@ namespace MWWorld
mPhysEngine->setSceneManager(renderer.getScene());
mWeatherManager = new MWWorld::WeatherManager(mRendering);
mWeatherManager = new MWWorld::WeatherManager(mRendering,fallbackMap);
int idx = 0;
// NOTE: We might need to reserve one more for the running game / save.

View file

@ -31,6 +31,32 @@ namespace Files
return iter->second;
}
boost::filesystem::path Collections::getPath(const std::string& file) const
{
for (Files::PathContainer::const_iterator iter = mDirectories.begin();
iter != mDirectories.end(); ++iter)
{
const boost::filesystem::path path = *iter / file;
if (boost::filesystem::exists(path))
return path.string();
}
throw std::runtime_error ("file " + file + " not found");
}
bool Collections::doesExist(const std::string& file) const
{
for (Files::PathContainer::const_iterator iter = mDirectories.begin();
iter != mDirectories.end(); ++iter)
{
const boost::filesystem::path path = *iter / file;
if (boost::filesystem::exists(path))
return true;
}
return false;
}
const Files::PathContainer& Collections::getPaths() const
{
return mDirectories;

View file

@ -19,6 +19,16 @@ namespace Files
/// leading dot and must be all lower-case.
const MultiDirCollection& getCollection(const std::string& extension) const;
boost::filesystem::path getPath(const std::string& file) const;
///< Return full path (including filename) of \a file.
///
/// If the file does not exist in any of the collection's
/// directories, an exception is thrown. \a file must include the
/// extension.
bool doesExist(const std::string& file) const;
///< \return Does a file with the given name exist?
const Files::PathContainer& getPaths() const;
private:

View file

@ -43,6 +43,7 @@ Mark Siewert (mark76)
Manuel Edelmann (vorenon)
Michael Mc Donnell
Michael Papageorgiou (werdanith)
Michał Bień (Glorf)
Nathan Jeffords (blunted2night)
Nikolay Kasyanov (corristo)
Nolan Poe (nopoe)

Binary file not shown.

Before

(image error) Size: 644 B

After

(image error) Size: 590 B

View file

@ -67,6 +67,9 @@
</item>
<item>
<widget class="ProfilesComboBox" name="profilesComboBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -107,6 +110,41 @@
</layout>
</item>
</layout>
<action name="newProfileAction">
<property name="icon">
<iconset theme="document-new"/>
</property>
<property name="text">
<string>New Profile</string>
</property>
<property name="toolTip">
<string>New Profile</string>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
</property>
</action>
<action name="deleteProfileAction">
<property name="icon">
<iconset theme="edit-delete"/>
</property>
<property name="text">
<string>Delete Profile</string>
</property>
<property name="toolTip">
<string>Delete Profile</string>
</property>
</action>
<action name="checkAction">
<property name="text">
<string>Check Selection</string>
</property>
</action>
<action name="uncheckAction">
<property name="text">
<string>Uncheck Selection</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View file

@ -2,25 +2,17 @@
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>575</width>
<height>575</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>575</width>
<height>575</height>
<height>525</height>
</size>
</property>
<property name="windowTitle">
<string>OpenMW Launcher</string>
</property>
<property name="windowIcon">
<iconset resource="../resources.qrc">
<iconset resource="../launcher/launcher.qrc">
<normaloff>:/images/openmw.png</normaloff>:/images/openmw.png</iconset>
</property>
<widget class="QWidget" name="centralwidget">
@ -42,7 +34,7 @@
<property name="styleSheet">
<string notr="true">#iconWidget {
background-image: url(&quot;:/images/openmw-header.png&quot;);
background-color: white;
background-color: palette(base);
background-repeat: no-repeat;
background-attachment: scroll;
background-position: right;
@ -74,7 +66,7 @@
</widget>
</widget>
<resources>
<include location="../resources.qrc"/>
<include location="../launcher/launcher.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -58,6 +58,7 @@
font-size: 12pt;
font-family: &quot;EB Garamond&quot;, &quot;EB Garamond 08&quot;;
color: black;
}
#profilesComboBox::drop-down {
@ -81,11 +82,10 @@
left: 1px;
}
#profilesComboBox QAbstractItemView {
border: 2px solid lightgray;
border-radius: 5px;
}
</string>
border: 0px;
}</string>
</property>
</widget>
</item>
@ -95,6 +95,7 @@
<string notr="true">#profileLabel {
font-size: 18pt;
font-family: &quot;EB Garamond&quot;, &quot;EB Garamond 08&quot;;
color: black;
}
</string>
</property>
@ -185,8 +186,6 @@
</item>
</layout>
</widget>
<resources>
<include location="../resources.qrc"/>
</resources>
<resources/>
<connections/>
</ui>