From 1c54f54ab8a2bd7ecc095e6a226a8c2c6e155e34 Mon Sep 17 00:00:00 2001 From: Allofich Date: Sat, 15 Oct 2016 00:10:36 +0900 Subject: [PATCH 01/14] Fix shadowing warnings --- apps/opencs/model/filter/parser.cpp | 2 +- apps/opencs/view/render/cell.cpp | 6 ++-- apps/opencs/view/world/dialoguesubview.cpp | 3 +- apps/opencs/view/world/dragrecordtable.cpp | 4 +-- apps/openmw/mwdialogue/journalimp.cpp | 8 ++--- apps/openmw/mwrender/animation.cpp | 4 +-- apps/openmw/mwrender/globalmap.cpp | 40 +++++++++++----------- apps/openmw/mwworld/containerstore.cpp | 6 ++-- 8 files changed, 36 insertions(+), 37 deletions(-) diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index 7936a1ae2..c0c089169 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -313,7 +313,7 @@ boost::shared_ptr CSMFilter::Parser::parseNAry (const Token& ke nodes.push_back (node); - Token token = getNextToken(); + token = getNextToken(); if (!token || (token.mType!=Token::Type_Close && token.mType!=Token::Type_Comma)) { diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 395fbf95f..adc038836 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -219,12 +219,12 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, } // add new objects - for (std::map::iterator iter (ids.begin()); iter!=ids.end(); ++iter) + for (std::map::iterator mapIter (ids.begin()); mapIter!=ids.end(); ++mapIter) { - if (!iter->second) + if (!mapIter->second) { mObjects.insert (std::make_pair ( - iter->first, new Object (mData, mCellNode, iter->first, false))); + mapIter->first, new Object (mData, mCellNode, mapIter->first, false))); modified = true; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 03d83f7da..87d5b3d7f 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -658,8 +658,7 @@ void CSVWorld::EditWidget::remake(int row) int displayRole = tree->nestedHeaderData (i, col, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt(); - CSMWorld::ColumnBase::Display display = - static_cast (displayRole); + display = static_cast (displayRole); mNestedTableDispatcher->makeDelegate (display); diff --git a/apps/opencs/view/world/dragrecordtable.cpp b/apps/opencs/view/world/dragrecordtable.cpp index a5f933283..6d980e171 100644 --- a/apps/opencs/view/world/dragrecordtable.cpp +++ b/apps/opencs/view/world/dragrecordtable.cpp @@ -67,8 +67,8 @@ void CSVWorld::DragRecordTable::dropEvent(QDropEvent *event) CSMWorld::ColumnBase::Display display = getIndexDisplayType(index); if (CSVWorld::DragDropUtils::canAcceptData(*event, display)) { - const CSMWorld::TableMimeData *data = CSVWorld::DragDropUtils::getTableMimeData(*event); - if (data->fromDocument(mDocument)) + const CSMWorld::TableMimeData *tableMimeData = CSVWorld::DragDropUtils::getTableMimeData(*event); + if (tableMimeData->fromDocument(mDocument)) { CSMWorld::UniversalId id = CSVWorld::DragDropUtils::getAcceptedData(*event, display); QVariant newIndexData = QString::fromUtf8(id.getId().c_str()); diff --git a/apps/openmw/mwdialogue/journalimp.cpp b/apps/openmw/mwdialogue/journalimp.cpp index 8ea72e3ba..f11ec651d 100644 --- a/apps/openmw/mwdialogue/journalimp.cpp +++ b/apps/openmw/mwdialogue/journalimp.cpp @@ -187,12 +187,12 @@ namespace MWDialogue state.save (writer); writer.endRecord (ESM::REC_QUES); - for (Topic::TEntryIter iter (quest.begin()); iter!=quest.end(); ++iter) + for (Topic::TEntryIter entryIter (quest.begin()); entryIter!=quest.end(); ++entryIter) { ESM::JournalEntry entry; entry.mType = ESM::JournalEntry::Type_Quest; entry.mTopic = quest.getTopic(); - iter->write (entry); + entryIter->write (entry); writer.startRecord (ESM::REC_JOUR); entry.save (writer); writer.endRecord (ESM::REC_JOUR); @@ -213,12 +213,12 @@ namespace MWDialogue { const Topic& topic = iter->second; - for (Topic::TEntryIter iter (topic.begin()); iter!=topic.end(); ++iter) + for (Topic::TEntryIter entryIter (topic.begin()); entryIter!=topic.end(); ++entryIter) { ESM::JournalEntry entry; entry.mType = ESM::JournalEntry::Type_Topic; entry.mTopic = topic.getTopic(); - iter->write (entry); + entryIter->write (entry); writer.startRecord (ESM::REC_JOUR); entry.save (writer); writer.endRecord (ESM::REC_JOUR); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 6091bee71..c2761e25d 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -978,8 +978,8 @@ namespace MWRender { const NifOsg::TextKeyMap &keys = (*animiter)->getTextKeys(); - const AnimSource::ControllerMap& ctrls = (*animiter)->mControllerMap[0]; - for (AnimSource::ControllerMap::const_iterator it = ctrls.begin(); it != ctrls.end(); ++it) + const AnimSource::ControllerMap& ctrls2 = (*animiter)->mControllerMap[0]; + for (AnimSource::ControllerMap::const_iterator it = ctrls2.begin(); it != ctrls2.end(); ++it) { if (Misc::StringUtils::ciEqual(it->first, mAccumRoot->getName())) { diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index d5102b153..6663b8b29 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -172,37 +172,37 @@ namespace MWRender unsigned char r,g,b; - float y = 0; + float y2 = 0; if (landData) - y = (landData->mWnam[vertexY * 9 + vertexX] << 4) / 2048.f; + y2 = (landData->mWnam[vertexY * 9 + vertexX] << 4) / 2048.f; else - y = (SCHAR_MIN << 4) / 2048.f; - if (y < 0) + y2 = (SCHAR_MIN << 4) / 2048.f; + if (y2 < 0) { - r = static_cast(14 * y + 38); - g = static_cast(20 * y + 56); - b = static_cast(18 * y + 51); + r = static_cast(14 * y2 + 38); + g = static_cast(20 * y2 + 56); + b = static_cast(18 * y2 + 51); } - else if (y < 0.3f) + else if (y2 < 0.3f) { - if (y < 0.1f) - y *= 8.f; + if (y2 < 0.1f) + y2 *= 8.f; else { - y -= 0.1f; - y += 0.8f; + y2 -= 0.1f; + y2 += 0.8f; } - r = static_cast(66 - 32 * y); - g = static_cast(48 - 23 * y); - b = static_cast(33 - 16 * y); + r = static_cast(66 - 32 * y2); + g = static_cast(48 - 23 * y2); + b = static_cast(33 - 16 * y2); } else { - y -= 0.3f; - y *= 1.428f; - r = static_cast(34 - 29 * y); - g = static_cast(25 - 20 * y); - b = static_cast(17 - 12 * y); + y2 -= 0.3f; + y2 *= 1.428f; + r = static_cast(34 - 29 * y2); + g = static_cast(25 - 20 * y2); + b = static_cast(17 - 12 * y2); } data[texelY * mWidth * 3 + texelX * 3] = r; diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 54b612a1e..dbdec8081 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -450,10 +450,10 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: } else { - std::string id = MWMechanics::getLevelledItem(ref.getPtr().get()->mBase, false); - if (id.empty()) + std::string itemId = MWMechanics::getLevelledItem(ref.getPtr().get()->mBase, false); + if (itemId.empty()) return; - addInitialItem(id, owner, count, false, levItemList->mId); + addInitialItem(itemId, owner, count, false, levItemList->mId); } } else From 5ccbabc27d7f1ec02447680e4bed28d12333fb77 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 14 Oct 2016 20:59:55 +0200 Subject: [PATCH 02/14] Fix build against bullet with profiler disabled (Fixes #3592) --- apps/openmw/mwgui/debugwindow.cpp | 7 +++++++ apps/openmw/mwphysics/physicssystem.cpp | 3 +++ 2 files changed, 10 insertions(+) diff --git a/apps/openmw/mwgui/debugwindow.cpp b/apps/openmw/mwgui/debugwindow.cpp index 37ea3470d..a29910f00 100644 --- a/apps/openmw/mwgui/debugwindow.cpp +++ b/apps/openmw/mwgui/debugwindow.cpp @@ -7,6 +7,8 @@ #include +#ifndef BT_NO_PROFILE + namespace { void bulletDumpRecursive(CProfileIterator* pit, int spacing, std::stringstream& os) @@ -71,6 +73,7 @@ namespace } } +#endif // BT_NO_PROFILE namespace MWGui { @@ -92,10 +95,13 @@ namespace MWGui MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); mMainWidget->setSize(viewSize); + + } void DebugWindow::onFrame(float dt) { +#ifndef BT_NO_PROFILE if (!isVisible()) return; @@ -115,6 +121,7 @@ namespace MWGui size_t previousPos = mBulletProfilerEdit->getVScrollPosition(); mBulletProfilerEdit->setCaption(stream.str()); mBulletProfilerEdit->setVScrollPosition(std::min(previousPos, mBulletProfilerEdit->getVScrollRange()-1)); +#endif } } diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 954d195dd..e442fbda1 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -14,6 +14,7 @@ #include #include #include + #include #include @@ -1363,8 +1364,10 @@ namespace MWPhysics for (std::set::iterator it = mAnimatedObjects.begin(); it != mAnimatedObjects.end(); ++it) (*it)->animateCollisionShapes(mCollisionWorld); +#ifndef BT_NO_PROFILE CProfileManager::Reset(); CProfileManager::Increment_Frame_Counter(); +#endif } void PhysicsSystem::debugDraw() From 7b59eda13a904ec3fa6630f40cc48f5ad02973c6 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 15 Oct 2016 17:34:03 +0200 Subject: [PATCH 03/14] Import base weather states before loading region modifiers (Fixes #3594) --- apps/openmw/mwworld/weather.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 46991c440..7111edd7d 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -832,17 +832,14 @@ bool WeatherManager::readRecord(ESM::ESMReader& reader, uint32_t type) mQueuedWeather = state.mQueuedWeather; mRegions.clear(); - std::map::iterator it = state.mRegions.begin(); - if(it == state.mRegions.end()) + importRegions(); + + for(std::map::iterator it = state.mRegions.begin(); it != state.mRegions.end(); ++it) { - // When loading an imported save, the region modifiers aren't currently being set, so just reset them. - importRegions(); - } - else - { - for(; it != state.mRegions.end(); ++it) + std::map::iterator found = mRegions.find(it->first); + if (found != mRegions.end()) { - mRegions.insert(std::make_pair(it->first, RegionWeather(it->second))); + found->second = RegionWeather(it->second); } } } From ccacad51bee4db0c1a76541119eff9b3966eb9d9 Mon Sep 17 00:00:00 2001 From: Allofich Date: Sun, 16 Oct 2016 01:34:54 +0900 Subject: [PATCH 04/14] Fix shadowing warnings --- apps/opencs/model/doc/loader.cpp | 8 ++++---- apps/opencs/model/world/infocollection.cpp | 2 -- apps/opencs/model/world/resources.cpp | 6 +++--- apps/opencs/view/filter/filterbox.cpp | 4 ++-- apps/opencs/view/render/instancemode.cpp | 4 ++-- apps/opencs/view/render/pagedworldspacewidget.cpp | 8 ++++---- apps/opencs/view/render/unpagedworldspacewidget.cpp | 8 ++++---- apps/opencs/view/render/worldspacewidget.cpp | 10 +++++----- apps/opencs/view/world/referenceablecreator.cpp | 6 +++--- apps/opencs/view/world/scenesubview.cpp | 12 ++++++------ apps/opencs/view/world/tablesubview.cpp | 8 ++++---- 11 files changed, 37 insertions(+), 39 deletions(-) diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 51b1b5884..44d6883ef 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -73,11 +73,11 @@ void CSMDoc::Loader::load() CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0); { // silence a g++ warning - for (CSMDoc::Messages::Iterator iter (messages.begin()); - iter!=messages.end(); ++iter) + for (CSMDoc::Messages::Iterator messageIter (messages.begin()); + messageIter!=messages.end(); ++messageIter) { - document->getReport (log)->add (*iter); - emit loadMessage (document, iter->mMessage); + document->getReport (log)->add (*messageIter); + emit loadMessage (document, messageIter->mMessage); } } diff --git a/apps/opencs/model/world/infocollection.cpp b/apps/opencs/model/world/infocollection.cpp index f5ec4d458..be73aece6 100644 --- a/apps/opencs/model/world/infocollection.cpp +++ b/apps/opencs/model/world/infocollection.cpp @@ -19,8 +19,6 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base) record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; (base ? record2.mBase : record2.mModified) = record; - int index = -1; - std::string topic = Misc::StringUtils::lowerCase (record2.get().mTopicId); if (!record2.get().mPrev.empty()) diff --git a/apps/opencs/model/world/resources.cpp b/apps/opencs/model/world/resources.cpp index b31e211ee..5fe9194d7 100644 --- a/apps/opencs/model/world/resources.cpp +++ b/apps/opencs/model/world/resources.cpp @@ -25,12 +25,12 @@ CSMWorld::Resources::Resources (const VFS::Manager* vfs, const std::string& base if (extensions) { - std::string::size_type index = filepath.find_last_of ('.'); + std::string::size_type extensionIndex = filepath.find_last_of ('.'); - if (index==std::string::npos) + if (extensionIndex==std::string::npos) continue; - std::string extension = filepath.substr (index+1); + std::string extension = filepath.substr (extensionIndex+1); int i = 0; diff --git a/apps/opencs/view/filter/filterbox.cpp b/apps/opencs/view/filter/filterbox.cpp index c6c6cc6cc..4c252e7d9 100644 --- a/apps/opencs/view/filter/filterbox.cpp +++ b/apps/opencs/view/filter/filterbox.cpp @@ -38,9 +38,9 @@ void CSVFilter::FilterBox::dropEvent (QDropEvent* event) if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped return; - std::vector data = mime->getData(); + std::vector universalIdData = mime->getData(); - emit recordDropped(data, event->proposedAction()); + emit recordDropped(universalIdData, event->proposedAction()); } void CSVFilter::FilterBox::dragEnterEvent (QDragEnterEvent* event) diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index cf51e93b7..3373daa4a 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -259,8 +259,8 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos) mDragMode = DragMode_Scale; // Calculate scale factor - std::vector > selection = getWorldspaceWidget().getEdited (Mask_Reference); - osg::Vec3f center = getScreenCoords(getSelectionCenter(selection)); + std::vector > editedSelection = getWorldspaceWidget().getEdited (Mask_Reference); + osg::Vec3f center = getScreenCoords(getSelectionCenter(editedSelection)); int widgetHeight = getWorldspaceWidget().height(); diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index a9d71626d..261144f8f 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -558,18 +558,18 @@ std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (co } bool CSVRender::PagedWorldspaceWidget::handleDrop ( - const std::vector< CSMWorld::UniversalId >& data, DropType type) + const std::vector< CSMWorld::UniversalId >& universalIdData, DropType type) { - if (WorldspaceWidget::handleDrop (data, type)) + if (WorldspaceWidget::handleDrop (universalIdData, type)) return true; if (type!=Type_CellsExterior) return false; bool selectionChanged = false; - for (unsigned i = 0; i < data.size(); ++i) + for (unsigned i = 0; i < universalIdData.size(); ++i) { - std::pair coordinates(getCoordinatesFromId(data[i].getId())); + std::pair coordinates(getCoordinatesFromId(universalIdData[i].getId())); if (mSelection.add(CSMWorld::CellCoordinates(coordinates.first, coordinates.second))) { selectionChanged = true; diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index d9a85fe35..03a97bf1a 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -80,20 +80,20 @@ void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelI emit closeRequest(); } -bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector& data, DropType type) +bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector& universalIdData, DropType type) { - if (WorldspaceWidget::handleDrop (data, type)) + if (WorldspaceWidget::handleDrop (universalIdData, type)) return true; if (type!=Type_CellsInterior) return false; - mCellId = data.begin()->getId(); + mCellId = universalIdData.begin()->getId(); mCell.reset (new Cell (getDocument().getData(), mRootNode, mCellId)); update(); - emit cellChanged(*data.begin()); + emit cellChanged(*universalIdData.begin()); return true; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index dd2ec1bdd..325fa5f6d 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -303,15 +303,15 @@ CSVRender::WorldspaceWidget::dropRequirments return ignored; } -bool CSVRender::WorldspaceWidget::handleDrop (const std::vector& data, +bool CSVRender::WorldspaceWidget::handleDrop (const std::vector& universalIdData, DropType type) { if (type==Type_DebugProfile) { if (mRun) { - for (std::vector::const_iterator iter (data.begin()); - iter!=data.end(); ++iter) + for (std::vector::const_iterator iter (universalIdData.begin()); + iter!=universalIdData.end(); ++iter) mRun->addProfile (iter->getId()); } @@ -402,9 +402,9 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo continue; } - for (std::vector::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) + for (std::vector::iterator nodeIter = intersection.nodePath.begin(); nodeIter != intersection.nodePath.end(); ++nodeIter) { - osg::Node* node = *it; + osg::Node* node = *nodeIter; if (osg::ref_ptr tag = dynamic_cast(node->getUserData())) { WorldspaceHitResult hit = { true, tag, 0, 0, 0, intersection.getWorldIntersectPoint() }; diff --git a/apps/opencs/view/world/referenceablecreator.cpp b/apps/opencs/view/world/referenceablecreator.cpp index 1357ca46f..836e8ac7d 100644 --- a/apps/opencs/view/world/referenceablecreator.cpp +++ b/apps/opencs/view/world/referenceablecreator.cpp @@ -26,10 +26,10 @@ CSVWorld::ReferenceableCreator::ReferenceableCreator (CSMWorld::Data& data, QUnd for (std::vector::const_iterator iter (types.begin()); iter!=types.end(); ++iter) { - CSMWorld::UniversalId id (*iter, ""); + CSMWorld::UniversalId id2 (*iter, ""); - mType->addItem (QIcon (id.getIcon().c_str()), id.getTypeName().c_str(), - static_cast (id.getType())); + mType->addItem (QIcon (id2.getIcon().c_str()), id2.getTypeName().c_str(), + static_cast (id2.getType())); } insertBeforeButtons (mType, false); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index c84818b37..b14d708da 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -187,18 +187,18 @@ void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection emit updateTitle(); } -void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalId >& data) +void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalId >& universalIdData) { CSVRender::PagedWorldspaceWidget* pagedNewWidget = NULL; CSVRender::UnpagedWorldspaceWidget* unPagedNewWidget = NULL; CSVWidget::SceneToolbar* toolbar = NULL; - CSVRender::WorldspaceWidget::DropType type = CSVRender::WorldspaceWidget::getDropType (data); + CSVRender::WorldspaceWidget::DropType type = CSVRender::WorldspaceWidget::getDropType (universalIdData); switch (mScene->getDropRequirements (type)) { case CSVRender::WorldspaceWidget::canHandle: - mScene->handleDrop (data, type); + mScene->handleDrop (universalIdData, type); break; case CSVRender::WorldspaceWidget::needPaged: @@ -206,15 +206,15 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI toolbar = makeToolbar(pagedNewWidget, widget_Paged); makeConnections(pagedNewWidget); replaceToolbarAndWorldspace(pagedNewWidget, toolbar); - mScene->handleDrop (data, type); + mScene->handleDrop (universalIdData, type); break; case CSVRender::WorldspaceWidget::needUnpaged: - unPagedNewWidget = new CSVRender::UnpagedWorldspaceWidget(data.begin()->getId(), mDocument, this); + unPagedNewWidget = new CSVRender::UnpagedWorldspaceWidget(universalIdData.begin()->getId(), mDocument, this); toolbar = makeToolbar(unPagedNewWidget, widget_Unpaged); makeConnections(unPagedNewWidget); replaceToolbarAndWorldspace(unPagedNewWidget, toolbar); - cellSelectionChanged(*(data.begin())); + cellSelectionChanged(*(universalIdData.begin())); break; case CSVRender::WorldspaceWidget::ignored: diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index 1b25e1c08..fcf66ed81 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -148,14 +148,14 @@ bool CSVWorld::TableSubView::eventFilter (QObject* object, QEvent* event) { if (QDropEvent* drop = dynamic_cast(event)) { - const CSMWorld::TableMimeData* data = dynamic_cast(drop->mimeData()); - if (!data) // May happen when non-records (e.g. plain text) are dragged and dropped + const CSMWorld::TableMimeData* tableMimeData = dynamic_cast(drop->mimeData()); + if (!tableMimeData) // May happen when non-records (e.g. plain text) are dragged and dropped return false; - bool handled = data->holdsType(CSMWorld::UniversalId::Type_Filter); + bool handled = tableMimeData->holdsType(CSMWorld::UniversalId::Type_Filter); if (handled) { - mFilterBox->setRecordFilter(data->returnMatching(CSMWorld::UniversalId::Type_Filter).getId()); + mFilterBox->setRecordFilter(tableMimeData->returnMatching(CSMWorld::UniversalId::Type_Filter).getId()); } return handled; } From 14240cf7a2803919fa685c5c538cbba0a33dc8aa Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 16 Oct 2016 17:27:17 +0200 Subject: [PATCH 05/14] Fix autoEquip to better match vanilla (Fixes #3590) --- apps/openmw/mwworld/inventorystore.cpp | 94 ++++++++++++++------------ 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index aa6880a49..25b9cbf08 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -216,22 +216,33 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { + if (!actor.getClass().isNpc()) + // autoEquip is no-op for creatures + return; + + const MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWWorld::Store &store = world->getStore().get(); + MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor); + + static float fUnarmoredBase1 = store.find("fUnarmoredBase1")->getFloat(); + static float fUnarmoredBase2 = store.find("fUnarmoredBase2")->getFloat(); + int unarmoredSkill = stats.getSkill(ESM::Skill::Unarmored).getModified(); + + float unarmoredRating = static_cast((fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill)); + TSlots slots_; initSlots (slots_); // Disable model update during auto-equip mUpdatesEnabled = false; - for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter) + // Relevant are only clothing and armor items: + // - Equipping lights is handled in Actors::updateEquippedLight based on environment light. + // - Equipping weapons is handled by AiCombat. + for (ContainerStoreIterator iter (begin(ContainerStore::Type_Clothing | ContainerStore::Type_Armor)); iter!=end(); ++iter) { Ptr test = *iter; - // Don't autoEquip lights. Handled in Actors::updateEquippedLight based on environment light. - if (test.getTypeName() == typeid(ESM::Light).name()) - { - continue; - } - // Only autoEquip if we are the original owner of the item. // This stops merchants from auto equipping anything you sell to them. // ...unless this is a companion, he should always equip items given to him. @@ -243,7 +254,20 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { continue; } - int testSkill = test.getClass().getEquipmentSkill (test); + + switch(test.getClass().canBeEquipped (test, actor).first) + { + case 0: + continue; + default: + break; + } + + if (iter.getType() == ContainerStore::Type_Armor && + test.getClass().getEffectiveArmorRating(test, actor) <= std::max(unarmoredRating, 0.f)) + { + continue; + } std::pair, bool> itemsSlots = iter->getClass().getEquipmentSlots (*iter); @@ -251,49 +275,33 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) for (std::vector::const_iterator iter2 (itemsSlots.first.begin()); iter2!=itemsSlots.first.end(); ++iter2) { - if (*iter2 == Slot_CarriedRight) // Items in right hand are situational use, so don't equip them. - // Equipping weapons is handled by AiCombat. Anything else (lockpicks, probes) can't be used by NPCs anyway (yet) - continue; - - if (iter.getType() == MWWorld::ContainerStore::Type_Weapon) - continue; - if (slots_.at (*iter2)!=end()) { Ptr old = *slots_.at (*iter2); - // check skill - int oldSkill = old.getClass().getEquipmentSkill (old); - - bool use = false; - if (testSkill!=-1 && oldSkill==-1) - use = true; - else if (testSkill!=-1 && oldSkill!=-1 && testSkill!=oldSkill) + if (iter.getType() == ContainerStore::Type_Armor) { - if (actor.getClass().getSkill(actor, oldSkill) > actor.getClass().getSkill (actor, testSkill)) - continue; // rejected, because old item better matched the NPC's skills. - - if (actor.getClass().getSkill(actor, oldSkill) < actor.getClass().getSkill (actor, testSkill)) - use = true; - } - - if (!use) - { - // check value - if (old.getClass().getValue (old)>= - test.getClass().getValue (test)) + if (old.getTypeName() == typeid(ESM::Armor).name()) { - continue; + if (old.getClass().getEffectiveArmorRating(old, actor) >= test.getClass().getEffectiveArmorRating(test, actor)) + // old armor had better armor rating + continue; } + // suitable armor should replace already equipped clothing + } + else if (iter.getType() == ContainerStore::Type_Clothing) + { + if (old.getTypeName() == typeid(ESM::Clothing).name()) + { + // check value + if (old.getClass().getValue (old) > test.getClass().getValue (test)) + // old clothing was more valuable + continue; + } + else + // suitable clothing should NOT replace already equipped armor + continue; } - } - - switch(test.getClass().canBeEquipped (test, actor).first) - { - case 0: - continue; - default: - break; } if (!itemsSlots.second) // if itemsSlots.second is true, item can stay stacked when equipped From 77bc80730534d6a61838dc6c4880381b71b95038 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 17 Oct 2016 15:01:10 +0200 Subject: [PATCH 06/14] Attenuate the light ambient in lighting.glsl (Fixes #3597) --- files/shaders/lighting.glsl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/files/shaders/lighting.glsl b/files/shaders/lighting.glsl index 08b369b5b..d62b61b52 100644 --- a/files/shaders/lighting.glsl +++ b/files/shaders/lighting.glsl @@ -20,9 +20,7 @@ vec4 doLighting(vec3 viewPos, vec3 viewNormal, vec4 vertexColor) d = length(lightDir); lightDir = normalize(lightDir); - lightResult.xyz += ambient * gl_LightSource[i].ambient.xyz; - lightResult.xyz += diffuse.xyz * gl_LightSource[i].diffuse.xyz * clamp(1.0 / (gl_LightSource[i].constantAttenuation + gl_LightSource[i].linearAttenuation * d + gl_LightSource[i].quadraticAttenuation * d * d), 0.0, 1.0) - * max(dot(viewNormal.xyz, lightDir), 0.0); + lightResult.xyz += (ambient * gl_LightSource[i].ambient.xyz + diffuse.xyz * gl_LightSource[i].diffuse.xyz * max(dot(viewNormal.xyz, lightDir), 0.0)) * clamp(1.0 / (gl_LightSource[i].constantAttenuation + gl_LightSource[i].linearAttenuation * d + gl_LightSource[i].quadraticAttenuation * d * d), 0.0, 1.0); } lightResult.xyz += gl_LightModel.ambient.xyz * ambient; From 1d3008594d934b1ce8dd42991ead94240574d8d1 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Tue, 18 Oct 2016 13:57:35 +0200 Subject: [PATCH 07/14] Autoequip weapons (Fixes #3562) --- apps/openmw/mwworld/inventorystore.cpp | 96 +++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 25b9cbf08..6620a991e 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -236,9 +236,9 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) // Disable model update during auto-equip mUpdatesEnabled = false; - // Relevant are only clothing and armor items: - // - Equipping lights is handled in Actors::updateEquippedLight based on environment light. - // - Equipping weapons is handled by AiCombat. + // Autoequip clothing, armor and weapons. + // Equipping lights is handled in Actors::updateEquippedLight based on environment light. + for (ContainerStoreIterator iter (begin(ContainerStore::Type_Clothing | ContainerStore::Type_Armor)); iter!=end(); ++iter) { Ptr test = *iter; @@ -318,6 +318,96 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) } } + static const ESM::Skill::SkillEnum weaponSkills[] = + { + ESM::Skill::LongBlade, + ESM::Skill::Axe, + ESM::Skill::Spear, + ESM::Skill::ShortBlade, + ESM::Skill::Marksman, + ESM::Skill::BluntWeapon + }; + const size_t weaponSkillsLength = sizeof(weaponSkills) / sizeof(weaponSkills[0]); + + bool weaponSkillVisited[weaponSkillsLength] = { false }; + + for (int i = 0; i < static_cast(weaponSkillsLength) - 1; ++i) + { + int max = 0; + int maxWeaponSkill = -1; + + for (int j = 0; j < static_cast(weaponSkillsLength) - 1; ++j) + { + int skillValue = stats.getSkill(static_cast(weaponSkills[j])).getModified(); + + if (skillValue > max && !weaponSkillVisited[j]) + { + max = skillValue; + maxWeaponSkill = j; + } + } + + if (maxWeaponSkill == -1) + break; + + max = 0; + ContainerStoreIterator weapon(end()); + + for (ContainerStoreIterator iter(begin(ContainerStore::Type_Weapon)); iter!=end(); ++iter) + { + const ESM::Weapon* esmWeapon = iter->get()->mBase; + + if (esmWeapon->mData.mType == ESM::Weapon::Arrow || esmWeapon->mData.mType == ESM::Weapon::Bolt) + continue; + + if (iter->getClass().getEquipmentSkill(*iter) == weaponSkills[maxWeaponSkill]) + { + if (esmWeapon->mData.mChop[1] >= max) + { + max = esmWeapon->mData.mChop[1]; + weapon = iter; + } + + if (esmWeapon->mData.mSlash[1] >= max) + { + max = esmWeapon->mData.mSlash[1]; + weapon = iter; + } + + if (esmWeapon->mData.mThrust[1] >= max) + { + max = esmWeapon->mData.mThrust[1]; + weapon = iter; + } + } + } + + if (weapon != end() && weapon->getClass().canBeEquipped(*weapon, actor).first) + { + std::pair, bool> itemsSlots = + weapon->getClass().getEquipmentSlots (*weapon); + + for (std::vector::const_iterator slot (itemsSlots.first.begin()); + slot!=itemsSlots.first.end(); ++slot) + { + if (!itemsSlots.second) + { + if (weapon->getRefData().getCount() > 1) + { + unstack(*weapon, actor); + } + } + + slots_[*slot] = weapon; + break; + } + + break; + } + + weaponSkillVisited[maxWeaponSkill] = true; + } + bool changed = false; for (std::size_t i=0; i Date: Tue, 18 Oct 2016 23:51:45 +0200 Subject: [PATCH 08/14] Properly handle moved references in respawning code (Fixes #3600) --- apps/openmw/mwworld/cellstore.cpp | 16 ++++++++++++---- apps/openmw/mwworld/cellstore.hpp | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index db3707441..5e65bad7c 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -204,6 +204,14 @@ namespace MWWorld return (ref.mRef.mRefnum == pRefnum); } + Ptr CellStore::getCurrentPtr(LiveCellRefBase *ref) + { + MovedRefTracker::iterator found = mMovedToAnotherCell.find(ref); + if (found != mMovedToAnotherCell.end()) + return Ptr(ref, found->second); + return Ptr(ref, this); + } + void CellStore::moveFrom(const Ptr &object, CellStore *from) { if (mState != State_Loaded) @@ -964,26 +972,26 @@ namespace MWWorld mLastRespawn = MWBase::Environment::get().getWorld()->getTimeStamp(); for (CellRefList::List::iterator it (mContainers.mList.begin()); it!=mContainers.mList.end(); ++it) { - Ptr ptr (&*it, this); + Ptr ptr = getCurrentPtr(&*it); ptr.getClass().respawn(ptr); } } for (CellRefList::List::iterator it (mCreatures.mList.begin()); it!=mCreatures.mList.end(); ++it) { - Ptr ptr (&*it, this); + Ptr ptr = getCurrentPtr(&*it); clearCorpse(ptr); ptr.getClass().respawn(ptr); } for (CellRefList::List::iterator it (mNpcs.mList.begin()); it!=mNpcs.mList.end(); ++it) { - Ptr ptr (&*it, this); + Ptr ptr = getCurrentPtr(&*it); clearCorpse(ptr); ptr.getClass().respawn(ptr); } for (CellRefList::List::iterator it (mCreatureLists.mList.begin()); it!=mCreatureLists.mList.end(); ++it) { - Ptr ptr (&*it, this); + Ptr ptr = getCurrentPtr(&*it); // no need to clearCorpse, handled as part of mCreatures ptr.getClass().respawn(ptr); } diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 1aee13132..aa7d68d8c 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -111,6 +111,9 @@ namespace MWWorld // Merged list of ref's currently in this cell - i.e. with added refs from mMovedHere, removed refs from mMovedToAnotherCell std::vector mMergedRefs; + // Get the Ptr for the given ref which originated from this cell (possibly moved to another cell at this point). + Ptr getCurrentPtr(MWWorld::LiveCellRefBase* ref); + /// Moves object from the given cell to this cell. void moveFrom(const MWWorld::Ptr& object, MWWorld::CellStore* from); From 76ddd9bebb34da8421901739fe2fec67ef431b84 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Tue, 18 Oct 2016 14:03:11 +0200 Subject: [PATCH 09/14] Add a setting for merchant auto-equipping prevention --- apps/openmw/mwworld/inventorystore.cpp | 35 ++++++++++++++++++-------- apps/openmw/mwworld/inventorystore.hpp | 2 ++ files/settings-default.cfg | 3 +++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 6620a991e..cf2a88c1d 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -214,6 +215,26 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) return mSlots[slot]; } +bool MWWorld::InventoryStore::canActorAutoEquip(const MWWorld::Ptr& actor, const MWWorld::Ptr& item) +{ + if (!Settings::Manager::getBool("prevent merchant equipping", "Game")) + return true; + + // Only autoEquip if we are the original owner of the item. + // This stops merchants from auto equipping anything you sell to them. + // ...unless this is a companion, he should always equip items given to him. + if (!Misc::StringUtils::ciEqual(item.getCellRef().getOwner(), actor.getCellRef().getRefId()) && + (actor.getClass().getScript(actor).empty() || + !actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion")) + && !actor.getClass().getCreatureStats(actor).isDead() // Corpses can be dressed up by the player as desired + ) + { + return false; + } + + return true; +} + void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { if (!actor.getClass().isNpc()) @@ -243,17 +264,8 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) { Ptr test = *iter; - // Only autoEquip if we are the original owner of the item. - // This stops merchants from auto equipping anything you sell to them. - // ...unless this is a companion, he should always equip items given to him. - if (!Misc::StringUtils::ciEqual(test.getCellRef().getOwner(), actor.getCellRef().getRefId()) && - (actor.getClass().getScript(actor).empty() || - !actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion")) - && !actor.getClass().getCreatureStats(actor).isDead() // Corpses can be dressed up by the player as desired - ) - { + if (!canActorAutoEquip(actor, test)) continue; - } switch(test.getClass().canBeEquipped (test, actor).first) { @@ -355,6 +367,9 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) for (ContainerStoreIterator iter(begin(ContainerStore::Type_Weapon)); iter!=end(); ++iter) { + if (!canActorAutoEquip(actor, *iter)) + continue; + const ESM::Weapon* esmWeapon = iter->get()->mBase; if (esmWeapon->mData.mType == ESM::Weapon::Arrow || esmWeapon->mData.mType == ESM::Weapon::Bolt) diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 9e0a8d5b6..7e6a259c4 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -115,6 +115,8 @@ namespace MWWorld virtual void storeEquipmentState (const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const; virtual void readEquipmentState (const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory); + bool canActorAutoEquip(const MWWorld::Ptr& actor, const MWWorld::Ptr& item); + public: InventoryStore(); diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 3d2cd49bf..9813cb166 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -145,6 +145,9 @@ difficulty = 0 # Show duration of magic effect and lights in the spells window. show effect duration = false +# Prevents merchants from equipping items that are sold to them. +prevent merchant equipping = false + [General] # Anisotropy reduces distortion in textures at low angles (e.g. 0 to 16). From a5ca33ad0b2f87dac81e955d2527ca1af28d3f60 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 19 Oct 2016 21:59:49 +0200 Subject: [PATCH 10/14] Disable failing OSX build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 574fe1ba8..4f811ee0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ os: - linux - - osx +# - osx osx_image: xcode7.2 language: cpp sudo: required From 407abc605f17bb7b6e84fa33f8d4ba5c66149fe4 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Wed, 19 Oct 2016 22:37:45 +0200 Subject: [PATCH 11/14] Fix auto-equipping of blunt weapons --- apps/openmw/mwworld/inventorystore.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index cf2a88c1d..98cbad742 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -343,12 +343,12 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) bool weaponSkillVisited[weaponSkillsLength] = { false }; - for (int i = 0; i < static_cast(weaponSkillsLength) - 1; ++i) + for (int i = 0; i < static_cast(weaponSkillsLength); ++i) { int max = 0; int maxWeaponSkill = -1; - for (int j = 0; j < static_cast(weaponSkillsLength) - 1; ++j) + for (int j = 0; j < static_cast(weaponSkillsLength); ++j) { int skillValue = stats.getSkill(static_cast(weaponSkills[j])).getModified(); From 301dd77efb444da863aea35fdca93e5899e52471 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Thu, 20 Oct 2016 02:12:01 +0200 Subject: [PATCH 12/14] Save controls state (Fixes #3598) --- apps/openmw/mwbase/inputmanager.hpp | 17 ++++++++++ apps/openmw/mwinput/inputmanagerimp.cpp | 41 +++++++++++++++++++++++ apps/openmw/mwinput/inputmanagerimp.hpp | 4 +++ apps/openmw/mwstate/statemanagerimp.cpp | 8 ++++- components/CMakeLists.txt | 2 +- components/esm/controlsstate.cpp | 43 +++++++++++++++++++++++++ components/esm/controlsstate.hpp | 39 ++++++++++++++++++++++ components/esm/defs.hpp | 1 + 8 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 components/esm/controlsstate.cpp create mode 100644 components/esm/controlsstate.hpp diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 75c55e028..0eb06ee3d 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -5,6 +5,19 @@ #include #include +#include + +namespace Loading +{ + class Listener; +} + +namespace ESM +{ + class ESMReader; + class ESMWriter; +} + namespace MWBase { /// \brief Interface for input manager (implemented in MWInput) @@ -56,6 +69,10 @@ namespace MWBase /// Returns if the last used input device was a joystick or a keyboard /// @return true if joystick, false otherwise virtual bool joystickLastUsed() = 0; + + virtual int countSavedGameRecords() const = 0; + virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; + virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 6c2e695e6..2f49d3463 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -16,6 +16,9 @@ #include #include +#include +#include +#include #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" @@ -1574,6 +1577,44 @@ namespace MWInput mInputBinder->removeJoystickButtonBinding (mFakeDeviceID, mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE)); } + int InputManager::countSavedGameRecords() const + { + return 1; + } + + void InputManager::write(ESM::ESMWriter& writer, Loading::Listener& /*progress*/) + { + ESM::ControlsState controls; + controls.mViewSwitchDisabled = !getControlSwitch("playerviewswitch"); + controls.mControlsDisabled = !getControlSwitch("playercontrols"); + controls.mJumpingDisabled = !getControlSwitch("playerjumping"); + controls.mLookingDisabled = !getControlSwitch("playerlooking"); + controls.mVanityModeDisabled = !getControlSwitch("vanitymode"); + controls.mWeaponDrawingDisabled = !getControlSwitch("playerfighting"); + controls.mSpellDrawingDisabled = !getControlSwitch("playermagic"); + + writer.startRecord (ESM::REC_INPU); + controls.save(writer); + writer.endRecord (ESM::REC_INPU); + } + + void InputManager::readRecord(ESM::ESMReader& reader, uint32_t type) + { + if (type == ESM::REC_INPU) + { + ESM::ControlsState controls; + controls.load(reader); + + toggleControlSwitch("playerviewswitch", !controls.mViewSwitchDisabled); + toggleControlSwitch("playercontrols", !controls.mControlsDisabled); + toggleControlSwitch("playerjumping", !controls.mJumpingDisabled); + toggleControlSwitch("playerlooking", !controls.mLookingDisabled); + toggleControlSwitch("vanitymode", !controls.mVanityModeDisabled); + toggleControlSwitch("playerfighting", !controls.mWeaponDrawingDisabled); + toggleControlSwitch("playermagic", !controls.mSpellDrawingDisabled); + } + } + void InputManager::resetToDefaultKeyBindings() { loadKeyDefaults(true); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 644391688..8809f44cd 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -149,6 +149,10 @@ namespace MWInput void clearAllKeyBindings (ICS::Control* control); void clearAllControllerBindings (ICS::Control* control); + virtual int countSavedGameRecords() const; + virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress); + virtual void readRecord(ESM::ESMReader& reader, uint32_t type); + private: SDL_Window* mWindow; bool mWindowVisible; diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 48cc37935..58d85fe5b 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -249,7 +249,8 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot +MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() +MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() +MWBase::Environment::get().getWindowManager()->countSavedGameRecords() - +MWBase::Environment::get().getMechanicsManager()->countSavedGameRecords(); + +MWBase::Environment::get().getMechanicsManager()->countSavedGameRecords() + +MWBase::Environment::get().getInputManager()->countSavedGameRecords(); writer.setRecordCount (recordCount); writer.save (stream); @@ -271,6 +272,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot MWBase::Environment::get().getScriptManager()->getGlobalScripts().write (writer, listener); MWBase::Environment::get().getWindowManager()->write(writer, listener); MWBase::Environment::get().getMechanicsManager()->write(writer, listener); + MWBase::Environment::get().getInputManager()->write(writer, listener); // Ensure we have written the number of records that was estimated if (writer.getRecordCount() != recordCount+1) // 1 extra for TES3 record @@ -462,6 +464,10 @@ void MWState::StateManager::loadGame (const Character *character, const std::str MWBase::Environment::get().getMechanicsManager()->readRecord(reader, n.intval); break; + case ESM::REC_INPU: + MWBase::Environment::get().getInputManager()->readRecord(reader, n.intval); + break; + default: // ignore invalid records diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index d6063c230..51faaba1d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -77,7 +77,7 @@ add_component_dir (esm loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap inventorystate containerstate npcstate creaturestate dialoguestate statstate npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile - aisequence magiceffects util custommarkerstate stolenitems transport animationstate + aisequence magiceffects util custommarkerstate stolenitems transport animationstate controlsstate ) add_component_dir (esmterrain diff --git a/components/esm/controlsstate.cpp b/components/esm/controlsstate.cpp new file mode 100644 index 000000000..ae4e1dff1 --- /dev/null +++ b/components/esm/controlsstate.cpp @@ -0,0 +1,43 @@ +#include "controlsstate.hpp" + +#include "esmreader.hpp" +#include "esmwriter.hpp" + +ESM::ControlsState::ControlsState() + : mViewSwitchDisabled(false), + mControlsDisabled(false), + mJumpingDisabled(false), + mLookingDisabled(false), + mVanityModeDisabled(false), + mWeaponDrawingDisabled(false), + mSpellDrawingDisabled(false) +{ +} + +void ESM::ControlsState::load(ESM::ESMReader& esm) +{ + int flags; + esm.getHNT(flags, "CFLG"); + + mViewSwitchDisabled = flags & ViewSwitchDisabled; + mControlsDisabled = flags & ControlsDisabled; + mJumpingDisabled = flags & JumpingDisabled; + mLookingDisabled = flags & LookingDisabled; + mVanityModeDisabled = flags & VanityModeDisabled; + mWeaponDrawingDisabled = flags & WeaponDrawingDisabled; + mSpellDrawingDisabled = flags & SpellDrawingDisabled; +} + +void ESM::ControlsState::save(ESM::ESMWriter& esm) const +{ + int flags = 0; + if (mViewSwitchDisabled) flags |= ViewSwitchDisabled; + if (mControlsDisabled) flags |= ControlsDisabled; + if (mJumpingDisabled) flags |= JumpingDisabled; + if (mLookingDisabled) flags |= LookingDisabled; + if (mVanityModeDisabled) flags |= VanityModeDisabled; + if (mWeaponDrawingDisabled) flags |= WeaponDrawingDisabled; + if (mSpellDrawingDisabled) flags |= SpellDrawingDisabled; + + esm.writeHNT("CFLG", flags); +} diff --git a/components/esm/controlsstate.hpp b/components/esm/controlsstate.hpp new file mode 100644 index 000000000..b9654ea1a --- /dev/null +++ b/components/esm/controlsstate.hpp @@ -0,0 +1,39 @@ +#ifndef OPENMW_ESM_CONTROLSSTATE_H +#define OPENMW_ESM_CONTROLSSTATE_H + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + // format 0, saved games only + + struct ControlsState + { + ControlsState(); + + enum Flags + { + ViewSwitchDisabled = 0x1, + ControlsDisabled = 0x4, + JumpingDisabled = 0x1000, + LookingDisabled = 0x2000, + VanityModeDisabled = 0x4000, + WeaponDrawingDisabled = 0x8000, + SpellDrawingDisabled = 0x10000 + }; + + bool mViewSwitchDisabled; + bool mControlsDisabled; + bool mJumpingDisabled; + bool mLookingDisabled; + bool mVanityModeDisabled; + bool mWeaponDrawingDisabled; + bool mSpellDrawingDisabled; + + void load (ESMReader &esm); + void save (ESMWriter &esm) const; + }; +} + +#endif diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index 8066b622a..0f0478faa 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -127,6 +127,7 @@ enum RecNameInts REC_ENAB = FourCC<'E','N','A','B'>::value, REC_CAM_ = FourCC<'C','A','M','_'>::value, REC_STLN = FourCC<'S','T','L','N'>::value, + REC_INPU = FourCC<'I','N','P','U'>::value, // format 1 REC_FILT = FourCC<'F','I','L','T'>::value, From f3ce0840be09f1efff55b7768a5a690c5eaeece6 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Thu, 20 Oct 2016 02:14:36 +0200 Subject: [PATCH 13/14] Import controls state from vanilla savegames --- apps/essimporter/converter.hpp | 2 +- apps/essimporter/convertplayer.cpp | 16 ++++++++++++---- apps/essimporter/convertplayer.hpp | 3 ++- apps/essimporter/importer.cpp | 4 ++++ apps/essimporter/importercontext.hpp | 3 +++ apps/essimporter/importplayer.hpp | 21 ++++++++++++--------- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 11f966446..5e46e4309 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -278,7 +278,7 @@ public: PCDT pcdt; pcdt.load(esm); - convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam); + convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam, mContext->mControlsState); } virtual void write(ESM::ESMWriter &esm) { diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index 55aaad1c5..c7bd8526c 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam) + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, ESM::ControlsState& controls) { out.mBirthsign = pcdt.mBirthsign; out.mObject.mNpcStats.mBounty = pcdt.mBounty; @@ -25,18 +25,26 @@ namespace ESSImport out.mObject.mNpcStats.mSkills[i].mProgress = pcdt.mPNAM.mSkillProgress[i]; out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress; - if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon) + if (pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_WeaponDrawn) out.mObject.mCreatureStats.mDrawState = 1; - if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell) + if (pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_SpellDrawn) out.mObject.mCreatureStats.mDrawState = 2; - firstPersonCam = !(pcdt.mPNAM.mCameraFlags & PCDT::CameraFlag_ThirdPerson); + firstPersonCam = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ThirdPerson); for (std::vector::const_iterator it = pcdt.mKnownDialogueTopics.begin(); it != pcdt.mKnownDialogueTopics.end(); ++it) { outDialogueTopics.push_back(Misc::StringUtils::lowerCase(*it)); } + + controls.mViewSwitchDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ViewSwitchDisabled; + controls.mControlsDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ControlsDisabled; + controls.mJumpingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_JumpingDisabled; + controls.mLookingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_LookingDisabled; + controls.mVanityModeDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_VanityModeDisabled; + controls.mWeaponDrawingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_WeaponDrawingDisabled; + controls.mSpellDrawingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_SpellDrawingDisabled; } } diff --git a/apps/essimporter/convertplayer.hpp b/apps/essimporter/convertplayer.hpp index f6731eed7..2e4565d8d 100644 --- a/apps/essimporter/convertplayer.hpp +++ b/apps/essimporter/convertplayer.hpp @@ -4,11 +4,12 @@ #include "importplayer.hpp" #include +#include namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam); + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, ESM::ControlsState& controls); } diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index f17db309f..1c255c56f 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -422,6 +422,10 @@ namespace ESSImport writer.startRecord (ESM::REC_DIAS); context.mDialogueState.save(writer); writer.endRecord(ESM::REC_DIAS); + + writer.startRecord(ESM::REC_INPU); + context.mControlsState.save(writer); + writer.endRecord(ESM::REC_INPU); } diff --git a/apps/essimporter/importercontext.hpp b/apps/essimporter/importercontext.hpp index c93dff269..fde247ebf 100644 --- a/apps/essimporter/importercontext.hpp +++ b/apps/essimporter/importercontext.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "importnpcc.hpp" #include "importcrec.hpp" @@ -32,6 +33,8 @@ namespace ESSImport ESM::DialogueState mDialogueState; + ESM::ControlsState mControlsState; + // cells which should show an explored overlay on the global map std::set > mExploredCells; diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 3baab1cd8..42881fcfd 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -38,14 +38,18 @@ struct PCDT std::vector mKnownDialogueTopics; - enum DrawState_ + enum PlayerFlags { - DrawState_Weapon = 0x80, - DrawState_Spell = 0x100 - }; - enum CameraFlags - { - CameraFlag_ThirdPerson = 0x2 + PlayerFlags_ViewSwitchDisabled = 0x1, + PlayerFlags_ControlsDisabled = 0x4, + PlayerFlags_WeaponDrawn = 0x80, + PlayerFlags_SpellDrawn = 0x100, + PlayerFlags_JumpingDisabled = 0x1000, + PlayerFlags_LookingDisabled = 0x2000, + PlayerFlags_VanityModeDisabled = 0x4000, + PlayerFlags_WeaponDrawingDisabled = 0x8000, + PlayerFlags_SpellDrawingDisabled = 0x10000, + PlayerFlags_ThirdPerson = 0x20000 }; #pragma pack(push) @@ -62,8 +66,7 @@ struct PCDT struct PNAM { - short mDrawState; // DrawState - short mCameraFlags; // CameraFlags + int mPlayerFlags; // controls, camera and draw state unsigned int mLevelProgress; float mSkillProgress[27]; // skill progress, non-uniform scaled unsigned char mSkillIncreases[8]; // number of skill increases for each attribute From cd9de94c0cfc6576c4a18121204f70f204d0f81d Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Thu, 20 Oct 2016 14:38:18 +0200 Subject: [PATCH 14/14] Import teleporting and levitation disabled state from vanilla savegames (Fixes #3420) --- apps/essimporter/converter.hpp | 15 +++++++++++++-- apps/essimporter/convertplayer.cpp | 4 +++- apps/essimporter/convertplayer.hpp | 2 +- apps/essimporter/importplayer.hpp | 4 +++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 5e46e4309..b05337aea 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -271,23 +271,34 @@ private: class ConvertPCDT : public Converter { public: - ConvertPCDT() : mFirstPersonCam(true) {} + ConvertPCDT() + : mFirstPersonCam(true), + mTeleportingEnabled(true), + mLevitationEnabled(true) + {} virtual void read(ESM::ESMReader &esm) { PCDT pcdt; pcdt.load(esm); - convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam, mContext->mControlsState); + convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam, mTeleportingEnabled, mLevitationEnabled, mContext->mControlsState); } virtual void write(ESM::ESMWriter &esm) { + esm.startRecord(ESM::REC_ENAB); + esm.writeHNT("TELE", mTeleportingEnabled); + esm.writeHNT("LEVT", mLevitationEnabled); + esm.endRecord(ESM::REC_ENAB); + esm.startRecord(ESM::REC_CAM_); esm.writeHNT("FIRS", mFirstPersonCam); esm.endRecord(ESM::REC_CAM_); } private: bool mFirstPersonCam; + bool mTeleportingEnabled; + bool mLevitationEnabled; }; class ConvertCNTC : public Converter diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index c7bd8526c..9d82af022 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, ESM::ControlsState& controls) + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls) { out.mBirthsign = pcdt.mBirthsign; out.mObject.mNpcStats.mBounty = pcdt.mBounty; @@ -31,6 +31,8 @@ namespace ESSImport out.mObject.mCreatureStats.mDrawState = 2; firstPersonCam = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ThirdPerson); + teleportingEnabled = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_TeleportingDisabled); + levitationEnabled = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_LevitationDisabled); for (std::vector::const_iterator it = pcdt.mKnownDialogueTopics.begin(); it != pcdt.mKnownDialogueTopics.end(); ++it) diff --git a/apps/essimporter/convertplayer.hpp b/apps/essimporter/convertplayer.hpp index 2e4565d8d..1d2fdc87a 100644 --- a/apps/essimporter/convertplayer.hpp +++ b/apps/essimporter/convertplayer.hpp @@ -9,7 +9,7 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, ESM::ControlsState& controls); + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls); } diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 42881fcfd..9f6b055c0 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -49,7 +49,9 @@ struct PCDT PlayerFlags_VanityModeDisabled = 0x4000, PlayerFlags_WeaponDrawingDisabled = 0x8000, PlayerFlags_SpellDrawingDisabled = 0x10000, - PlayerFlags_ThirdPerson = 0x20000 + PlayerFlags_ThirdPerson = 0x20000, + PlayerFlags_TeleportingDisabled = 0x40000, + PlayerFlags_LevitationDisabled = 0x80000 }; #pragma pack(push)