From 9ea092927fca60c1b92b8d4fbc7305eda672c8db Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 28 Sep 2013 09:25:54 +0200 Subject: [PATCH 01/62] added basic scene subview (no functionality yet) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/universalid.cpp | 1 + apps/opencs/model/world/universalid.hpp | 5 +- apps/opencs/view/doc/view.cpp | 9 ++++ apps/opencs/view/doc/view.hpp | 2 + apps/opencs/view/world/scenesubview.cpp | 72 +++++++++++++++++++++++++ apps/opencs/view/world/scenesubview.hpp | 37 +++++++++++++ apps/opencs/view/world/scenetoolbar.cpp | 8 +++ apps/opencs/view/world/scenetoolbar.hpp | 20 +++++++ apps/opencs/view/world/subviews.cpp | 2 + 10 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 apps/opencs/view/world/scenesubview.cpp create mode 100644 apps/opencs/view/world/scenesubview.hpp create mode 100644 apps/opencs/view/world/scenetoolbar.cpp create mode 100644 apps/opencs/view/world/scenetoolbar.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 00547a2ba6..2fbceac962 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -59,7 +59,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator - cellcreator referenceablecreator referencecreator + cellcreator referenceablecreator referencecreator scenesubview scenetoolbar ) opencs_units_noqt (view/world diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 60a8485f86..c9edd0c162 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -87,6 +87,7 @@ namespace static const TypeData sIndexArg[] = { { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 }, + { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index aa0cdacc06..2466407331 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -86,10 +86,11 @@ namespace CSMWorld Type_Reference, Type_RegionMap, Type_Filter, - Type_Filters + Type_Filters, + Type_Scene }; - enum { NumberOfTypes = Type_Filters+1 }; + enum { NumberOfTypes = Type_Scene+1 }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 7183753e18..b29250d204 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -115,6 +115,10 @@ void CSVDoc::View::setupWorldMenu() world->addSeparator(); // items that don't represent single record lists follow here + QAction *scene = new QAction (tr ("Scene"), this); + connect (scene, SIGNAL (triggered()), this, SLOT (addSceneSubView())); + world->addAction (scene); + QAction *regionMap = new QAction (tr ("Region Map"), this); connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView())); world->addAction (regionMap); @@ -403,6 +407,11 @@ void CSVDoc::View::addFiltersSubView() addSubView (CSMWorld::UniversalId::Type_Filters); } +void CSVDoc::View::addSceneSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Scene); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 29a1d52f7b..6f3c38daaa 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -164,6 +164,8 @@ namespace CSVDoc void addFiltersSubView(); + void addSceneSubView(); + void toggleShowStatusBar (bool show); }; } diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp new file mode 100644 index 0000000000..bb77fec2ee --- /dev/null +++ b/apps/opencs/view/world/scenesubview.cpp @@ -0,0 +1,72 @@ + +#include "scenesubview.hpp" + +#include +#include +#include + +#include "../../model/doc/document.hpp" + +#include "../filter/filterbox.hpp" + +#include "tablebottombox.hpp" +#include "creator.hpp" +#include "scenetoolbar.hpp" + +CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) +: SubView (id) +{ + QVBoxLayout *layout = new QVBoxLayout; + + layout->setContentsMargins (QMargins (0, 0, 0, 0)); + + layout->addWidget (mBottom = + new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id, + this), 0); + + QHBoxLayout *layout2 = new QHBoxLayout; + + layout2->setContentsMargins (QMargins (0, 0, 0, 0)); + + SceneToolbar *toolbar = new SceneToolbar (this); + layout2->addWidget (toolbar, 0); + + /// \todo replace with rendering widget + QPalette palette2 (palette()); + palette2.setColor (QPalette::Background, Qt::white); + QLabel *placeholder = new QLabel ("Here goes the 3D scene", this); + placeholder->setAutoFillBackground (true); + placeholder->setPalette (palette2); + placeholder->setAlignment (Qt::AlignHCenter); + + layout2->addWidget (placeholder, 1); + + layout->insertLayout (0, layout2, 1); + + CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this); + + layout->insertWidget (0, filterBox); + + QWidget *widget = new QWidget; + + widget->setLayout (layout); + + setWidget (widget); +} + +void CSVWorld::SceneSubView::setEditLock (bool locked) +{ + + +} + +void CSVWorld::SceneSubView::updateEditorSetting(const QString &settingName, const QString &settingValue) +{ + + +} + +void CSVWorld::SceneSubView::setStatusBar (bool show) +{ + mBottom->setStatusBar (show); +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp new file mode 100644 index 0000000000..a0fed908df --- /dev/null +++ b/apps/opencs/view/world/scenesubview.hpp @@ -0,0 +1,37 @@ +#ifndef CSV_WORLD_SCENESUBVIEW_H +#define CSV_WORLD_SCENESUBVIEW_H + +#include "../doc/subview.hpp" + +class QModelIndex; + +namespace CSMDoc +{ + class Document; +} + +namespace CSVWorld +{ + class Table; + class TableBottomBox; + class CreatorFactoryBase; + + class SceneSubView : public CSVDoc::SubView + { + Q_OBJECT + + TableBottomBox *mBottom; + + public: + + SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + + virtual void setEditLock (bool locked); + + virtual void updateEditorSetting (const QString& key, const QString& value); + + virtual void setStatusBar (bool show); + }; +} + +#endif diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp new file mode 100644 index 0000000000..6ced03a9f7 --- /dev/null +++ b/apps/opencs/view/world/scenetoolbar.cpp @@ -0,0 +1,8 @@ + +#include "scenetoolbar.hpp" + +CSVWorld::SceneToolbar::SceneToolbar (QWidget *parent) : QWidget (parent) +{ + setFixedWidth (52); + +} diff --git a/apps/opencs/view/world/scenetoolbar.hpp b/apps/opencs/view/world/scenetoolbar.hpp new file mode 100644 index 0000000000..2fb288100a --- /dev/null +++ b/apps/opencs/view/world/scenetoolbar.hpp @@ -0,0 +1,20 @@ +#ifndef CSV_WORLD_SCENETOOLBAR_H +#define CSV_WORLD_SCENETOOLBAR_H + +#include + +namespace CSVWorld +{ + class SceneToolbar : public QWidget + { + Q_OBJECT + + public: + + SceneToolbar (QWidget *parent); + + + }; +} + +#endif diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index d22e07d89c..0e3465b388 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -13,6 +13,7 @@ #include "cellcreator.hpp" #include "referenceablecreator.hpp" #include "referencecreator.hpp" +#include "scenesubview.hpp" void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) { @@ -62,4 +63,5 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator >); + manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); } \ No newline at end of file From 84cadc10f4a32a752426f106d75db9078f160c10 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 28 Sep 2013 11:06:56 +0200 Subject: [PATCH 02/62] added scene toolbar buttons (still not doing anything) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/world/scenesubview.cpp | 5 +++++ apps/opencs/view/world/scenetool.cpp | 9 +++++++++ apps/opencs/view/world/scenetool.hpp | 19 +++++++++++++++++++ apps/opencs/view/world/scenetoolbar.cpp | 17 ++++++++++++++++- apps/opencs/view/world/scenetoolbar.hpp | 8 +++++++- 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 apps/opencs/view/world/scenetool.cpp create mode 100644 apps/opencs/view/world/scenetool.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 2fbceac962..2bb31be9f4 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -59,7 +59,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator - cellcreator referenceablecreator referencecreator scenesubview scenetoolbar + cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index bb77fec2ee..3b15326abe 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -12,6 +12,7 @@ #include "tablebottombox.hpp" #include "creator.hpp" #include "scenetoolbar.hpp" +#include "scenetool.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id) @@ -29,6 +30,10 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); SceneToolbar *toolbar = new SceneToolbar (this); +toolbar->addTool (new SceneTool (this)); // test +toolbar->addTool (new SceneTool (this)); +toolbar->addTool (new SceneTool (this)); +toolbar->addTool (new SceneTool (this)); layout2->addWidget (toolbar, 0); /// \todo replace with rendering widget diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp new file mode 100644 index 0000000000..12743c52c1 --- /dev/null +++ b/apps/opencs/view/world/scenetool.cpp @@ -0,0 +1,9 @@ + +#include "scenetool.hpp" + +CSVWorld::SceneTool::SceneTool (QWidget *parent) : QPushButton (parent) +{ + setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + setFixedSize (48, 48); + +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp new file mode 100644 index 0000000000..ae440b579f --- /dev/null +++ b/apps/opencs/view/world/scenetool.hpp @@ -0,0 +1,19 @@ +#ifndef CSV_WORLD_SCENETOOL_H +#define CSV_WORLD_SCENETOOL_H + +#include + +namespace CSVWorld +{ + class SceneTool : public QPushButton + { + Q_OBJECT + + public: + + SceneTool (QWidget *parent = 0); + + }; +} + +#endif diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp index 6ced03a9f7..7c716b5fce 100644 --- a/apps/opencs/view/world/scenetoolbar.cpp +++ b/apps/opencs/view/world/scenetoolbar.cpp @@ -1,8 +1,23 @@ #include "scenetoolbar.hpp" +#include + +#include "scenetool.hpp" + CSVWorld::SceneToolbar::SceneToolbar (QWidget *parent) : QWidget (parent) { - setFixedWidth (52); + setFixedWidth (48); + + mLayout = new QVBoxLayout (this); + mLayout->setAlignment (Qt::AlignTop); + mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + + setLayout (mLayout); } + +void CSVWorld::SceneToolbar::addTool (SceneTool *tool) +{ + mLayout->addWidget (tool, 0, Qt::AlignTop); +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolbar.hpp b/apps/opencs/view/world/scenetoolbar.hpp index 2fb288100a..00631c360c 100644 --- a/apps/opencs/view/world/scenetoolbar.hpp +++ b/apps/opencs/view/world/scenetoolbar.hpp @@ -3,17 +3,23 @@ #include +class QVBoxLayout; + namespace CSVWorld { + class SceneTool; + class SceneToolbar : public QWidget { Q_OBJECT + QVBoxLayout *mLayout; + public: SceneToolbar (QWidget *parent); - + void addTool (SceneTool *tool); }; } From 0c5f07a65addf90c4fd033b2d4e4e03424f26e24 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 28 Sep 2013 11:27:24 +0200 Subject: [PATCH 03/62] added SceneToolMode class --- apps/opencs/CMakeLists.txt | 1 + apps/opencs/view/world/scenesubview.cpp | 10 +++++----- apps/opencs/view/world/scenetool.cpp | 1 - apps/opencs/view/world/scenetool.hpp | 1 + apps/opencs/view/world/scenetoolmode.cpp | 6 ++++++ apps/opencs/view/world/scenetoolmode.hpp | 19 +++++++++++++++++++ 6 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 apps/opencs/view/world/scenetoolmode.cpp create mode 100644 apps/opencs/view/world/scenetoolmode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 2bb31be9f4..f918cfebfb 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,6 +60,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool + scenetoolmode ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 3b15326abe..8f3ecab21a 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -12,7 +12,7 @@ #include "tablebottombox.hpp" #include "creator.hpp" #include "scenetoolbar.hpp" -#include "scenetool.hpp" +#include "scenetoolmode.hpp" CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id) @@ -30,10 +30,10 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); SceneToolbar *toolbar = new SceneToolbar (this); -toolbar->addTool (new SceneTool (this)); // test -toolbar->addTool (new SceneTool (this)); -toolbar->addTool (new SceneTool (this)); -toolbar->addTool (new SceneTool (this)); +toolbar->addTool (new SceneToolMode (this)); // test +toolbar->addTool (new SceneToolMode (this)); +toolbar->addTool (new SceneToolMode (this)); +toolbar->addTool (new SceneToolMode (this)); layout2->addWidget (toolbar, 0); /// \todo replace with rendering widget diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index 12743c52c1..f67e4fa455 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -5,5 +5,4 @@ CSVWorld::SceneTool::SceneTool (QWidget *parent) : QPushButton (parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); setFixedSize (48, 48); - } \ No newline at end of file diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp index ae440b579f..c3e9e3b4bf 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/world/scenetool.hpp @@ -5,6 +5,7 @@ namespace CSVWorld { + ///< \brief Tool base class class SceneTool : public QPushButton { Q_OBJECT diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp new file mode 100644 index 0000000000..a6b9b5a28f --- /dev/null +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -0,0 +1,6 @@ + +#include "scenetoolmode.hpp" + +CSVWorld::SceneToolMode::SceneToolMode (QWidget *parent) +: SceneTool (parent) +{} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolmode.hpp b/apps/opencs/view/world/scenetoolmode.hpp new file mode 100644 index 0000000000..d54ec76b2c --- /dev/null +++ b/apps/opencs/view/world/scenetoolmode.hpp @@ -0,0 +1,19 @@ +#ifndef CSV_WORLD_SCENETOOL_MODE_H +#define CSV_WORLD_SCENETOOL_MODE_H + +#include "scenetool.hpp" + +namespace CSVWorld +{ + ///< \brief Mode selector tool + class SceneToolMode : public SceneTool + { + Q_OBJECT + + public: + + SceneToolMode (QWidget *parent = 0); + }; +} + +#endif From 7be1f1afc2a9e5ce7f6e0d95d22483fc544d90ac Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 28 Sep 2013 13:10:42 +0200 Subject: [PATCH 04/62] implemented SceneToolMode as a horizontal panel with radiobutton-type buttons --- apps/opencs/view/world/scenesubview.cpp | 7 +++- apps/opencs/view/world/scenetool.cpp | 14 ++++++- apps/opencs/view/world/scenetool.hpp | 9 +++++ apps/opencs/view/world/scenetoolmode.cpp | 47 +++++++++++++++++++++++- apps/opencs/view/world/scenetoolmode.hpp | 20 ++++++++++ 5 files changed, 94 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 8f3ecab21a..36ace68f0e 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -30,7 +30,12 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); SceneToolbar *toolbar = new SceneToolbar (this); -toolbar->addTool (new SceneToolMode (this)); // test +// test +SceneToolMode *tool = new SceneToolMode (this); +tool->addButton (":door.png", "a"); +tool->addButton (":GMST.png", "b"); +tool->addButton (":Info.png", "c"); +toolbar->addTool (tool); toolbar->addTool (new SceneToolMode (this)); toolbar->addTool (new SceneToolMode (this)); toolbar->addTool (new SceneToolMode (this)); diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index f67e4fa455..d7d37c98f6 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -5,4 +5,16 @@ CSVWorld::SceneTool::SceneTool (QWidget *parent) : QPushButton (parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); setFixedSize (48, 48); -} \ No newline at end of file + + connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); +} + +void CSVWorld::SceneTool::updateIcon (const QIcon& icon) +{ + setIcon (icon); +} + +void CSVWorld::SceneTool::openRequest() +{ + showPanel (parentWidget()->mapToGlobal (pos())); +} diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp index c3e9e3b4bf..d5c9dd5d2f 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/world/scenetool.hpp @@ -14,6 +14,15 @@ namespace CSVWorld SceneTool (QWidget *parent = 0); + virtual void showPanel (const QPoint& position) = 0; + + protected slots: + + void updateIcon (const QIcon& icon); + + private slots: + + void openRequest(); }; } diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp index a6b9b5a28f..b4277bcbe7 100644 --- a/apps/opencs/view/world/scenetoolmode.cpp +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -1,6 +1,51 @@ #include "scenetoolmode.hpp" +#include +#include +#include + CSVWorld::SceneToolMode::SceneToolMode (QWidget *parent) : SceneTool (parent) -{} \ No newline at end of file +{ + mPanel = new QFrame (this, Qt::Popup); + + mLayout = new QHBoxLayout (mPanel); + + mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + + mPanel->setLayout (mLayout); +} + +void CSVWorld::SceneToolMode::showPanel (const QPoint& position) +{ + mPanel->move (position); + mPanel->show(); +} + +void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::string& id) +{ + QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel); + button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setFixedSize (48, 48); + + mLayout->addWidget (button); + + mButtons.insert (std::make_pair (button, id)); + + connect (button, SIGNAL (clicked()), this, SLOT (selected())); +} + +void CSVWorld::SceneToolMode::selected() +{ + std::map::const_iterator iter = + mButtons.find (dynamic_cast (sender())); + + if (iter!=mButtons.end()) + { + mPanel->hide(); + + emit updateIcon (iter->first->icon()); + emit modeChanged (iter->second); + } +} \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolmode.hpp b/apps/opencs/view/world/scenetoolmode.hpp index d54ec76b2c..feee78376b 100644 --- a/apps/opencs/view/world/scenetoolmode.hpp +++ b/apps/opencs/view/world/scenetoolmode.hpp @@ -3,6 +3,10 @@ #include "scenetool.hpp" +#include + +class QHBoxLayout; + namespace CSVWorld { ///< \brief Mode selector tool @@ -10,9 +14,25 @@ namespace CSVWorld { Q_OBJECT + QWidget *mPanel; + QHBoxLayout *mLayout; + std::map mButtons; // widget, id + public: SceneToolMode (QWidget *parent = 0); + + virtual void showPanel (const QPoint& position); + + void addButton (const std::string& icon, const std::string& id); + + signals: + + void modeChanged (const std::string& id); + + private slots: + + void selected(); }; } From fd169c2399ba2ccc103361696b61c662d88b901b Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 29 Sep 2013 15:49:47 +0100 Subject: [PATCH 05/62] fixed issue with cds where subfolders of Data Files were contained outside the Data Files folder --- apps/launcher/unshieldthread.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 6ddad7a21e..33bdf44f4a 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -268,6 +268,27 @@ namespace strptime(time, "%d %B %Y", &tms); return mktime(&tms); } + + // Some cds have cab files which have the Data Files subfolders outside the Data Files folder + void install_dfiles_outside(const bfs::path& from, const bfs::path& dFiles) + { + bfs::path fonts = findFile(from, "fonts", false); + if(fonts.string() != "") + installToPath(fonts, dFiles / "Fonts"); + + bfs::path music = findFile(from, "music", false); + if(music.string() != "") + installToPath(music, dFiles / "Music"); + + bfs::path sound = findFile(from, "sound", false); + if(sound.string() != "") + installToPath(sound, dFiles / "Sound"); + + bfs::path splash = findFile(from, "splash", false); + if(splash.string() != "") + installToPath(splash, dFiles / "Splash"); + } + } bool UnshieldThread::SetMorrowindPath(const std::string& path) @@ -365,6 +386,8 @@ bool UnshieldThread::extract() installToPath(dFilesDir, outputDataFilesDir); + install_dfiles_outside(mwExtractPath, outputDataFilesDir); + // Videos are often kept uncompressed on the cd bfs::path videosPath = findFile(mMorrowindPath.parent_path(), "video", false); if(videosPath.string() != "") @@ -399,6 +422,8 @@ bool UnshieldThread::extract() installToPath(dFilesDir, outputDataFilesDir); + install_dfiles_outside(tbExtractPath, outputDataFilesDir); + // Mt GOTY CD has Sounds in a seperate folder from the rest of the data files bfs::path soundsPath = findFile(tbExtractPath, "sounds", false); if(soundsPath.string() != "") @@ -426,6 +451,8 @@ bool UnshieldThread::extract() bfs::path dFilesDir = findFile(bmExtractPath, "bloodmoon.esm").parent_path(); installToPath(dFilesDir, outputDataFilesDir); + + install_dfiles_outside(bmExtractPath, outputDataFilesDir); // My GOTY CD contains a folder within cab files called Tribunal patch, // which contains Tribunal.esm From dd0a41624970b657a4159cffdb7b2a120636a023 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 29 Sep 2013 16:59:52 +0100 Subject: [PATCH 06/62] cleaned up bloodmoon_fix_ini --- apps/launcher/unshieldthread.cpp | 143 ++++++++++++++++--------------- 1 file changed, 72 insertions(+), 71 deletions(-) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 33bdf44f4a..69b241365c 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -77,6 +77,8 @@ namespace ini.insert(loc, setting + "=" + val + "\r\n"); } + #define FIX(setting) add_setting(category, setting, get_setting(category, setting, inx), ini) + void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath) { std::string inx = read_to_string(inxPath); @@ -88,95 +90,94 @@ namespace ini.erase(start, end-start); std::string category; - std::string setting; category = "General"; { - setting = "Werewolf FOV"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Werewolf FOV"); } category = "Moons"; { - setting = "Script Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Script Color"); } category = "Weather"; { - setting = "Snow Ripples"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Radius"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripples Per Flake"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Gravity Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow High Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Low Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Snow Ripples"); + FIX("Snow Ripple Radius"); + FIX("Snow Ripples Per Flake"); + FIX("Snow Ripple Scale"); + FIX("Snow Ripple Speed"); + FIX("Snow Gravity Scale"); + FIX("Snow High Kill"); + FIX("Snow Low Kill"); } category = "Weather Blight"; { - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Ambient Loop Sound ID"); } category = "Weather Snow"; { - setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Diameter"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Height Min"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Height Max"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Entrance Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Max Snowflakes"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Sky Sunrise Color"); + FIX("Sky Day Color"); + FIX("Sky Sunset Color"); + FIX("Sky Night Color"); + FIX("Fog Sunrise Color"); + FIX("Fog Day Color"); + FIX("Fog Sunset Color"); + FIX("Fog Night Color"); + FIX("Ambient Sunrise Color"); + FIX("Ambient Day Color"); + FIX("Ambient Sunset Color"); + FIX("Ambient Night Color"); + FIX("Sun Sunrise Color"); + FIX("Sun Day Color"); + FIX("Sun Sunset Color"); + FIX("Sun Night Color"); + FIX("Sun Disc Sunset Color"); + FIX("Transition Delta"); + FIX("Land Fog Day Depth"); + FIX("Land Fog Night Depth"); + FIX("Clouds Maximum Percent"); + FIX("Wind Speed"); + FIX("Cloud Speed"); + FIX("Glare View"); + FIX("Cloud Texture"); + FIX("Ambient Loop Sound ID"); + FIX("Snow Threshold"); + FIX("Snow Diameter"); + FIX("Snow Height Min"); + FIX("Snow Height Max"); + FIX("Snow Entrance Speed"); + FIX("Max Snowflakes"); } category = "Weather Blizzard"; { - setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Storm Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); + FIX("Sky Sunrise Color"); + FIX("Sky Day Color"); + FIX("Sky Sunset Color"); + FIX("Sky Night Color"); + FIX("Fog Sunrise Color"); + FIX("Fog Day Color"); + FIX("Fog Sunset Color"); + FIX("Fog Night Color"); + FIX("Ambient Sunrise Color"); + FIX("Ambient Day Color"); + FIX("Ambient Sunset Color"); + FIX("Ambient Night Color"); + FIX("Sun Sunrise Color"); + FIX("Sun Day Color"); + FIX("Sun Sunset Color"); + FIX("Sun Night Color"); + FIX("Sun Disc Sunset Color"); + FIX("Transition Delta"); + FIX("Land Fog Day Depth"); + FIX("Land Fog Night Depth"); + FIX("Clouds Maximum Percent"); + FIX("Wind Speed"); + FIX("Cloud Speed"); + FIX("Glare View"); + FIX("Cloud Texture"); + FIX("Ambient Loop Sound ID"); + FIX("Storm Threshold"); } } From bffbfff41c791c18a182e49d1f11710b6c46a3b2 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Mon, 30 Sep 2013 00:32:06 -0400 Subject: [PATCH 07/62] My own fix to make it hackily compile --- apps/launcher/main.cpp | 16 ++++++++++++++++ apps/opencs/view/doc/adjusterwidget.cpp | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index f67f5edcff..a5cda76476 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -62,3 +62,19 @@ int main(int argc, char *argv[]) return returnValue; } + +#include +#include + +#ifdef __GNUC__ +#define _stdcall __attribute__((stdcall)) +#endif + +int _stdcall +WinMain (struct HINSTANCE__ *hInstance, + struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, + int nCmdShow) +{ + return main (__argc, __argv); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index 9108197006..c97f066725 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -61,7 +61,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) if (path.parent_path().string()==mLocalData.string()) { // path already points to the local data directory - message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; mValid = true; } @@ -70,7 +70,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) // path points somewhere else or is a leaf name. path = mLocalData / path.filename(); - message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; mValid = true; From 4cdb57e3883051b9dc4dcc6ca16668aa4961ee28 Mon Sep 17 00:00:00 2001 From: greye Date: Mon, 30 Sep 2013 10:30:40 +0400 Subject: [PATCH 08/62] workaround segfault on --new-game switch --- apps/openmw/engine.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a2eccbaf9a..e1fd3a0af3 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -399,8 +399,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding); mEnvironment.setWindowManager (window); - if (mNewGame) - mEnvironment.getWindowManager()->setNewGame(true); // Create the world mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins, @@ -410,6 +408,10 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) input->setPlayer(&mEnvironment.getWorld()->getPlayer()); window->initUI(); + if (mNewGame) + // still redundant work here: recreate CharacterCreation(), + // double update visibility etc. + window->setNewGame(true); window->renderWorldMap(); //Load translation data From 00a776a1a8585c2205c86f958bbe2dc7ba9e64c6 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Mon, 30 Sep 2013 02:54:20 -0400 Subject: [PATCH 09/62] Fixed compilation failure on my machine Fixed shared records not being populated before the player record is moved. --- apps/openmw/mwworld/worldimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f3d4c81b76..8e8f68f70e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -225,8 +225,8 @@ namespace MWWorld if (mEsm[0].getFormat() == 0) ensureNeededRecords(); - mStore.movePlayerRecord(); mStore.setUp(); + mStore.movePlayerRecord(); mGlobalVariables = new Globals (mStore); From eae02ea00dc9823fed63366709ef9c857f4e1956 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Mon, 30 Sep 2013 03:33:31 -0400 Subject: [PATCH 10/62] Cleaned up my hackish code for WinMain --- apps/launcher/main.cpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index a5cda76476..73bdb95dae 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -62,19 +62,14 @@ int main(int argc, char *argv[]) return returnValue; } - -#include -#include - -#ifdef __GNUC__ -#define _stdcall __attribute__((stdcall)) -#endif - -int _stdcall -WinMain (struct HINSTANCE__ *hInstance, - struct HINSTANCE__ *hPrevInstance, - char *lpszCmdLine, - int nCmdShow) +#ifdef _WINDOWS +// If the system compiles for main(), then main will be used. +// If it wants WinMain, this will call main anyways. +int _stdcall WinMain(struct HINSTANCE__ *hInstance, + struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, + int nCmdShow) { - return main (__argc, __argv); -} \ No newline at end of file + return main(__argc, __argv); +} +#endif From 4496244b1428cb43d9d5d41d191360b7b98e2cb0 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Tue, 1 Oct 2013 05:36:13 -0400 Subject: [PATCH 11/62] Tabs to spaces My own code uses only tabs - I forgot to change the setting on my IDE, sorry! --- apps/launcher/main.cpp | 2 +- apps/opencs/view/doc/adjusterwidget.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 73bdb95dae..df7aa11d47 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -72,4 +72,4 @@ int _stdcall WinMain(struct HINSTANCE__ *hInstance, { return main(__argc, __argv); } -#endif +#endif \ No newline at end of file diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index c97f066725..9e01f685ca 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -61,7 +61,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) if (path.parent_path().string()==mLocalData.string()) { // path already points to the local data directory - message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; mValid = true; } @@ -70,7 +70,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) // path points somewhere else or is a leaf name. path = mLocalData / path.filename(); - message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); + message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; mValid = true; From 296abfd48faec66aa77490f58d6f0e868bb4f17f Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Tue, 1 Oct 2013 10:48:34 -0400 Subject: [PATCH 12/62] Bug #840, First Person Sneaking Camera Height Also, added comments to existing code in the area. --- apps/openmw/mwrender/npcanimation.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 13b5971e2a..7b5a105c0a 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -443,11 +443,31 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) Ogre::Vector3 ret = Animation::runAnimation(timepassed); Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton(); + + // We have to make a few adjustments to the first person animation, since the armature + // is partly driven by code. if(mViewMode == VM_FirstPerson && mCamera) { + // Bend his neck and shoulders so his eyes don't go into his torso. float pitch = mCamera->getPitch(); Ogre::Node *node = baseinst->getBone("Bip01 Neck"); node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD); + + // If NPC is sneaking, his head and shoulders must lower to adjust his camera. + const MWWorld::Class *npcClass = &MWWorld::Class::get(mPtr); + const MWBase::World *world = MWBase::Environment::get().getWorld(); + + bool isSneaking = npcClass->getStance(mPtr, MWWorld::Class::Sneak); + bool isInAir = !world->isOnGround(mPtr); + bool isSwimming = world->isSwimming(mPtr); + + if(isSneaking && !(isSwimming || isInAir)) + { + Ogre::Node *headNode = baseinst->getBone("Bip01 Neck"); + Ogre::Vector3 position = headNode->getPosition(); + position.x -= 9.5f; + headNode->setPosition(position); + } } for(size_t i = 0;i < ESM::PRT_Count;i++) From 0ddb5097fc48f5e4f87ac08121fa6c02b3f25c16 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Tue, 1 Oct 2013 11:44:45 -0400 Subject: [PATCH 13/62] Revert "Bug #840, First Person Sneaking Camera Height" This reverts commit 296abfd48faec66aa77490f58d6f0e868bb4f17f. --- apps/openmw/mwrender/npcanimation.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 7b5a105c0a..13b5971e2a 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -443,31 +443,11 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) Ogre::Vector3 ret = Animation::runAnimation(timepassed); Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton(); - - // We have to make a few adjustments to the first person animation, since the armature - // is partly driven by code. if(mViewMode == VM_FirstPerson && mCamera) { - // Bend his neck and shoulders so his eyes don't go into his torso. float pitch = mCamera->getPitch(); Ogre::Node *node = baseinst->getBone("Bip01 Neck"); node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD); - - // If NPC is sneaking, his head and shoulders must lower to adjust his camera. - const MWWorld::Class *npcClass = &MWWorld::Class::get(mPtr); - const MWBase::World *world = MWBase::Environment::get().getWorld(); - - bool isSneaking = npcClass->getStance(mPtr, MWWorld::Class::Sneak); - bool isInAir = !world->isOnGround(mPtr); - bool isSwimming = world->isSwimming(mPtr); - - if(isSneaking && !(isSwimming || isInAir)) - { - Ogre::Node *headNode = baseinst->getBone("Bip01 Neck"); - Ogre::Vector3 position = headNode->getPosition(); - position.x -= 9.5f; - headNode->setPosition(position); - } } for(size_t i = 0;i < ESM::PRT_Count;i++) From b8c60dabb3cc1d2e6c377d9807d5b1c654d6918b Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 1 Oct 2013 23:35:34 +0200 Subject: [PATCH 14/62] Reintroduce Acrobatics changes made by Glorf Advance Acrobatics skill on jump and on landing, apply fall damage on landing. --- apps/openmw/mwclass/npc.cpp | 28 ++++++++++++++++ apps/openmw/mwclass/npc.hpp | 3 ++ apps/openmw/mwmechanics/character.cpp | 47 ++++++++++++++++++++++++++- apps/openmw/mwmechanics/character.hpp | 3 ++ apps/openmw/mwworld/class.cpp | 5 +++ apps/openmw/mwworld/class.hpp | 3 ++ 6 files changed, 88 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 073d1b1b92..505c902db5 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -769,6 +769,34 @@ namespace MWClass return x; } + float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const + { + const float fallDistanceMin = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDamageDistanceMin")->getFloat(); + + if (fallHeight>=fallDistanceMin) + { + const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified(); + const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); + const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude; + const float fallAcroBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFallAcroBase")->getFloat(); + const float fallAcroMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFallAcroMult")->getFloat(); + const float fallDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDistanceBase")->getFloat(); + const float fallDistanceMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDistanceMult")->getFloat(); + + float x = fallHeight - fallDistanceMin; + x -= (1.5 * acrobaticsSkill) + jumpSpellBonus; + x = std::max(0.0f, x); + + float a = fallAcroBase + fallAcroMult * (100 - acrobaticsSkill); + x = fallDistanceBase + fallDistanceMult * x; + x *= a; + + return x; + } + + return 0; + } + MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const { ensureCustomData (ptr); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 3591d7c688..c39ca42ef4 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -97,6 +97,9 @@ namespace MWClass virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) + virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const; + ///< Return amount of health points lost when falling + virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; ///< Return desired movement. diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index ec2bb1b59e..2753b09c21 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -767,10 +767,17 @@ void CharacterController::update(float duration) } if(sneak || inwater || flying) + { vec.z = 0.0f; + mFallHeight = 0.0f; + } if(!onground && !flying && !inwater) { + // The player is in the air (either getting up —ascending part of jump— or falling). + + mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]); + const MWWorld::Store &gmst = world->getStore().get(); forcestateupdate = (mJumpState != JumpState_Falling); @@ -794,6 +801,8 @@ void CharacterController::update(float duration) } else if(vec.z > 0.0f && mJumpState == JumpState_None) { + // The player has started a jump. + float z = cls.getJump(mPtr); if(vec.x == 0 && vec.y == 0) vec = Ogre::Vector3(0.0f, 0.0f, z); @@ -803,13 +812,49 @@ void CharacterController::update(float duration) vec = Ogre::Vector3(lat.x, lat.y, 1.0f) * z * 0.707f; } - //decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult; + // advance acrobatics + MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); + + // decrease fatigue + const float fatigueJumpBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFatigueJumpBase")->getFloat(); + const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFatigueJumpMult")->getFloat(); + const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); + const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult; + DynamicStat fatigue = cls.getCreatureStats(mPtr).getDynamic(2); + fatigue.setModified(fatigue.getModified() - fatigueDecrease, 0); + fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); + cls.getCreatureStats(mPtr).setDynamic(2, fatigue); } else if(mJumpState == JumpState_Falling) { + // The player is landing. + forcestateupdate = true; mJumpState = JumpState_Landing; vec.z = 0.0f; + + float healthLost = cls.getFallDamage(mPtr, mFallHeight - mPtr.getRefData().getPosition().pos[2]); + if (healthLost > 0.0f) + { + // inflict fall damages + DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); + int current = health.getCurrent(); + int realHealthLost = healthLost * (1.0f - 0.25 * 1.25f /* * fatigueTerm */); + health.setModified(health.getModified() - realHealthLost, 0); + health.setCurrent(current - realHealthLost); + cls.getCreatureStats(mPtr).setHealth(health); + + // report acrobatics progression + cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); + + const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified(); + if (healthLost > (acrobaticsSkill * 1.25f /* * fatigueTerm */)) + { + //TODO: actor falls over + } + } + + mFallHeight = 0; } else { diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index c943b95977..7b9dda49aa 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -154,6 +154,9 @@ class CharacterController float mSecondsOfSwimming; float mSecondsOfRunning; + // used for acrobatics progress and fall damages + float mFallHeight; + std::string mAttackType; // slash, chop or thrust void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index c739ea831c..de50935471 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -167,6 +167,11 @@ namespace MWWorld throw std::runtime_error ("class does not support enchanting"); } + float Class::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const + { + return 0; + } + MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const { throw std::runtime_error ("movement settings not supported by class"); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 28e37cbf3c..1db09647e4 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -175,6 +175,9 @@ namespace MWWorld virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) + virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const; + ///< Return amount of health points lost when falling + virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const; ///< Return desired movement. From ed0c31b4854cc19d474402127d434ea379c374c1 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Wed, 2 Oct 2013 05:16:52 -0400 Subject: [PATCH 15/62] Refactored, moved logic out of NpcAnimation The logic is now handled by RenderingManager, and Camera sets its animation's first person offset height. Due to how NpcAnimation seems to be updated, it has to be the one to actually set its own nodes, in the case of the hands. Otherwise, the hands would not move without a messier hack. --- apps/openmw/mwrender/camera.cpp | 6 ++++++ apps/openmw/mwrender/camera.hpp | 6 ++++++ apps/openmw/mwrender/npcanimation.cpp | 13 ++++++++++++- apps/openmw/mwrender/npcanimation.hpp | 7 +++++++ apps/openmw/mwrender/renderingmanager.cpp | 9 +++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 36f53c0fea..232b95c699 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -187,6 +187,12 @@ namespace MWRender rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false); } + void Camera::setSneakOffset() + { + if(mAnimation) + mAnimation->addFirstPersonOffset(Ogre::Vector3(-9.8f, 0.f, 0.f)); + } + float Camera::getYaw() { if(mVanity.enabled || mPreviewMode) diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index dc552371e6..baf2f3685a 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -79,6 +79,12 @@ namespace MWRender void togglePreviewMode(bool enable); + /// \brief Lowers the camera for sneak. + /// As animation is tied to the camera, this needs + /// to be set each frame after the animation is + /// applied. + void setSneakOffset(); + bool isFirstPerson() const { return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 13b5971e2a..84e89773c2 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -84,7 +84,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor mWeapon(inv.end()), mShield(inv.end()), mViewMode(viewMode), - mShowWeapons(false) + mShowWeapons(false), + mFirstPersonOffset(0.f, 0.f, 0.f) { mNpc = mPtr.get()->mBase; @@ -392,6 +393,11 @@ void NpcAnimation::updateParts(bool forceupdate) } } +void NpcAnimation::addFirstPersonOffset(const Ogre::Vector3 &offset) +{ + mFirstPersonOffset += offset; +} + class SetObjectGroup { int mGroup; @@ -448,7 +454,12 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) float pitch = mCamera->getPitch(); Ogre::Node *node = baseinst->getBone("Bip01 Neck"); node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD); + + // This has to be done before this function ends; + // updateSkeletonInstance, below, touches the hands. + node->translate(mFirstPersonOffset); } + mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame. for(size_t i = 0;i < ESM::PRT_Count;i++) { diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 24205acafd..b1abf97af0 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -64,6 +64,8 @@ private: int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty int mPartPriorities[ESM::PRT_Count]; + Ogre::Vector3 mFirstPersonOffset; + void updateNpcBase(); NifOgre::ObjectList insertBoundedPart(const std::string &model, int group, const std::string &bonename); @@ -89,6 +91,11 @@ public: void updateParts(bool forceupdate = false); + /// \brief Applies a translation to the arms and hands. + /// This may be called multiple times before the animation + /// is updated to add additional offsets. + void addFirstPersonOffset(const Ogre::Vector3 &offset); + /// Rebuilds the NPC, updating their root model, animation sources, and equipment. void rebuild(); }; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e03b2ccfcf..261fd45c88 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -354,6 +354,15 @@ void RenderingManager::update (float duration, bool paused) mCamera->setCameraDistance(test.second * orig.distance(dest), false, false); } + // Sink the camera while sneaking + bool isSneaking = MWWorld::Class::get(player).getStance(player, MWWorld::Class::Sneak); + bool isInAir = !world->isOnGround(player); + bool isSwimming = world->isSwimming(player); + + if(isSneaking && !(isSwimming || isInAir)) + mCamera->setSneakOffset(); + + mOcclusionQuery->update(duration); mVideoPlayer->update (); From f1b4c2e400743dfb207f8b9bbad19e50af6b95ed Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Wed, 2 Oct 2013 07:03:39 -0400 Subject: [PATCH 16/62] Fixed first person offset to use world transform It slipped my mind that some necks might not be perfectly vertical. --- apps/openmw/mwrender/camera.cpp | 2 +- apps/openmw/mwrender/npcanimation.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 232b95c699..9af3987a8e 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -190,7 +190,7 @@ namespace MWRender void Camera::setSneakOffset() { if(mAnimation) - mAnimation->addFirstPersonOffset(Ogre::Vector3(-9.8f, 0.f, 0.f)); + mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -9.8f)); } float Camera::getYaw() diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 84e89773c2..9ffe53eabb 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -457,7 +457,7 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) // This has to be done before this function ends; // updateSkeletonInstance, below, touches the hands. - node->translate(mFirstPersonOffset); + node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD); } mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame. From 496f786c2a6e5c202027429b5cc14af0f089c2a0 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 15:12:41 +0200 Subject: [PATCH 17/62] Implement Disable/EnableLevitation script functions Totally copied on Disable/EnableTeleporting implementation. Thanks KittyCat! --- apps/openmw/mwbase/world.hpp | 6 ++++++ apps/openmw/mwscript/docs/vmformat.txt | 4 +++- apps/openmw/mwscript/miscextensions.cpp | 15 ++++++++++++++- apps/openmw/mwworld/worldimp.cpp | 10 ++++++++++ apps/openmw/mwworld/worldimp.hpp | 7 +++++++ components/compiler/extensions0.cpp | 2 ++ components/compiler/opcodes.hpp | 2 ++ 7 files changed, 44 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f8453afed6..d7b013a845 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -389,6 +389,12 @@ namespace MWBase /// Returns true if teleport spell effects are allowed. virtual bool isTeleportingEnabled() const = 0; + /// Enables or disables use of levitation spell effect. + virtual void enableLevitation(bool enable) = 0; + + /// Returns true if levitation spell effect is allowed. + virtual bool isLevitationEnabled() const = 0; + /// Turn actor into werewolf or normal form. virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index ff3b60ca68..7bbb336999 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -352,5 +352,7 @@ op 0x200021c: SetWerewolfAcrobaticsExplicit op 0x200021d: ShowVars op 0x200021e: ShowVarsExplicit op 0x200021f: ToggleGodMode +op 0x2000220: DisableLevitation +op 0x2000221: EnableLevitation -opcodes 0x2000220-0x3ffffff unused +opcodes 0x2000222-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a8d8a5f2bb..4ae1136e22 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -635,7 +635,18 @@ namespace MWScript world->enableTeleporting(Enable); } }; - + + template + class OpEnableLevitation : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->enableLevitation(Enable); + } + }; template class OpShowVars : public Interpreter::Opcode0 @@ -789,6 +800,8 @@ namespace MWScript interpreter.installSegment5 (Compiler::Misc::opcodeShowVars, new OpShowVars); interpreter.installSegment5 (Compiler::Misc::opcodeShowVarsExplicit, new OpShowVars); interpreter.installSegment5 (Compiler::Misc::opcodeToggleGodMode, new OpToggleGodMode); + interpreter.installSegment5 (Compiler::Misc::opcodeDisableLevitation, new OpEnableLevitation); + interpreter.installSegment5 (Compiler::Misc::opcodeEnableLevitation, new OpEnableLevitation); } } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f3d4c81b76..1ba209663b 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1877,6 +1877,16 @@ namespace MWWorld return mTeleportEnabled; } + void World::enableLevitation(bool enable) + { + mLevitationEnabled = enable; + } + + bool World::isLevitationEnabled() const + { + return mLevitationEnabled; + } + void World::setWerewolf(const MWWorld::Ptr& actor, bool werewolf) { MWMechanics::NpcStats& npcStats = Class::get(actor).getNpcStats(actor); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 53b01f1abf..8f80d90d66 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -116,6 +116,7 @@ namespace MWWorld int mPlayIntro; bool mTeleportEnabled; + bool mLevitationEnabled; public: @@ -438,6 +439,12 @@ namespace MWWorld /// Returns true if teleport spell effects are allowed. virtual bool isTeleportingEnabled() const; + /// Enables or disables use of levitation spell effect. + virtual void enableLevitation(bool enable); + + /// Returns true if levitation spell effect is allowed. + virtual bool isLevitationEnabled() const; + virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf); virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor); diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index 415f8d1686..65f6e112a3 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -260,6 +260,8 @@ namespace Compiler extensions.registerInstruction ("sv", "", opcodeShowVars, opcodeShowVarsExplicit); extensions.registerInstruction("tgm", "", opcodeToggleGodMode); extensions.registerInstruction("togglegodmode", "", opcodeToggleGodMode); + extensions.registerInstruction ("disablelevitation", "", opcodeDisableLevitation); + extensions.registerInstruction ("enablelevitation", "", opcodeEnableLevitation); } } diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index 5eb54208af..aca24e0d30 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -222,6 +222,8 @@ namespace Compiler const int opcodeShowVars = 0x200021d; const int opcodeShowVarsExplicit = 0x200021e; const int opcodeToggleGodMode = 0x200021f; + const int opcodeDisableLevitation = 0x2000220; + const int opcodeEnableLevitation = 0x2000221; } namespace Sky From 073f64c8bb4abf7cc8653f3fa0b70a6d69f241e7 Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Wed, 2 Oct 2013 13:46:33 -0400 Subject: [PATCH 18/62] stop weapon condition degredation (for the player) with tgm on --- apps/openmw/mwclass/npc.cpp | 7 ++++--- apps/openmw/mwmechanics/actors.cpp | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 073d1b1b92..3d8bdf16f9 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -396,9 +396,10 @@ namespace MWClass MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}"); MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f); } - weapon.getCellRef().mCharge -= std::min(std::max(1, - (int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), - weapon.getCellRef().mCharge); + + if (!MWBase::Environment::get().getWorld()->getGodModeState()) + weapon.getCellRef().mCharge -= std::min(std::max(1, + (int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge); } healthdmg = true; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ca26e88ce1..f9b5b695ae 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -276,7 +276,8 @@ namespace MWMechanics } // If it's the player and God Mode is turned on, keep it alive - if(iter->first.getRefData().getHandle()=="player" && MWBase::Environment::get().getWorld()->getGodModeState()) + if(iter->first.getRefData().getHandle()=="player" && + MWBase::Environment::get().getWorld()->getGodModeState()) { MWMechanics::DynamicStat stat(stats.getHealth()); From 486051486599e80bc0731252a7191095226b1eaf Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 12:58:34 +0200 Subject: [PATCH 19/62] Acrobatics: cosmetic changes --- apps/openmw/mwclass/npc.cpp | 18 +++++++++++------- apps/openmw/mwmechanics/character.cpp | 14 +++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 505c902db5..0110bef88e 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -7,6 +7,7 @@ #include +#include #include #include "../mwbase/environment.hpp" @@ -771,17 +772,20 @@ namespace MWClass float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const { - const float fallDistanceMin = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDamageDistanceMin")->getFloat(); + MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWWorld::Store &gmst = world->getStore().get(); + + const float fallDistanceMin = gmst.find("fFallDamageDistanceMin")->getFloat(); - if (fallHeight>=fallDistanceMin) + if (fallHeight >= fallDistanceMin) { const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified(); const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); - const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude; - const float fallAcroBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFallAcroBase")->getFloat(); - const float fallAcroMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFallAcroMult")->getFloat(); - const float fallDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDistanceBase")->getFloat(); - const float fallDistanceMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFallDistanceMult")->getFloat(); + const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Jump)).mMagnitude; + const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat(); + const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat(); + const float fallDistanceBase = gmst.find("fFallDistanceBase")->getFloat(); + const float fallDistanceMult = gmst.find("fFallDistanceMult")->getFloat(); float x = fallHeight - fallDistanceMin; x -= (1.5 * acrobaticsSkill) + jumpSpellBonus; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 2753b09c21..efd3b94cc2 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -813,17 +813,18 @@ void CharacterController::update(float duration) } // advance acrobatics - MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); + cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); // decrease fatigue - const float fatigueJumpBase = MWBase::Environment::get().getWorld()->getStore().get().find("fFatigueJumpBase")->getFloat(); - const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get().find("fFatigueJumpMult")->getFloat(); + const MWWorld::Store &gmst = world->getStore().get(); + const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat(); + const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat(); const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult; - DynamicStat fatigue = cls.getCreatureStats(mPtr).getDynamic(2); + DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); fatigue.setModified(fatigue.getModified() - fatigueDecrease, 0); fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); - cls.getCreatureStats(mPtr).setDynamic(2, fatigue); + cls.getCreatureStats(mPtr).setFatigue(fatigue); } else if(mJumpState == JumpState_Falling) { @@ -838,10 +839,9 @@ void CharacterController::update(float duration) { // inflict fall damages DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); - int current = health.getCurrent(); int realHealthLost = healthLost * (1.0f - 0.25 * 1.25f /* * fatigueTerm */); health.setModified(health.getModified() - realHealthLost, 0); - health.setCurrent(current - realHealthLost); + health.setCurrent(health.getCurrent() - realHealthLost); cls.getCreatureStats(mPtr).setHealth(health); // report acrobatics progression From 4c151e59a26caed2d77d1f74e446472b3e78863c Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 13:00:47 +0200 Subject: [PATCH 20/62] Acrobatics: do not touch modified stats --- apps/openmw/mwmechanics/character.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index efd3b94cc2..14eed2641a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -822,7 +822,6 @@ void CharacterController::update(float duration) const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult; DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); - fatigue.setModified(fatigue.getModified() - fatigueDecrease, 0); fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); cls.getCreatureStats(mPtr).setFatigue(fatigue); } @@ -840,7 +839,6 @@ void CharacterController::update(float duration) // inflict fall damages DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); int realHealthLost = healthLost * (1.0f - 0.25 * 1.25f /* * fatigueTerm */); - health.setModified(health.getModified() - realHealthLost, 0); health.setCurrent(health.getCurrent() - realHealthLost); cls.getCreatureStats(mPtr).setHealth(health); From 2b992ef3b5e8dd27c5b4edee3e98323be230079e Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 13:02:14 +0200 Subject: [PATCH 21/62] Acrobatics: use calculated fatigueTerm --- apps/openmw/mwmechanics/character.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 14eed2641a..5b4d316e51 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -836,9 +836,11 @@ void CharacterController::update(float duration) float healthLost = cls.getFallDamage(mPtr, mFallHeight - mPtr.getRefData().getPosition().pos[2]); if (healthLost > 0.0f) { + const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm(); + // inflict fall damages DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); - int realHealthLost = healthLost * (1.0f - 0.25 * 1.25f /* * fatigueTerm */); + int realHealthLost = healthLost * (1.0f - 0.25 * fatigueTerm); health.setCurrent(health.getCurrent() - realHealthLost); cls.getCreatureStats(mPtr).setHealth(health); @@ -846,7 +848,7 @@ void CharacterController::update(float duration) cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified(); - if (healthLost > (acrobaticsSkill * 1.25f /* * fatigueTerm */)) + if (healthLost > (acrobaticsSkill * fatigueTerm)) { //TODO: actor falls over } From 6e09a5fb4af2ac97330020f92172c5a712b84356 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 22:36:28 +0200 Subject: [PATCH 22/62] Acrobatics: reinit fall height at current height rather than zero To prevent problems. --- apps/openmw/mwmechanics/character.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 5b4d316e51..0924e36b9a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -769,7 +769,7 @@ void CharacterController::update(float duration) if(sneak || inwater || flying) { vec.z = 0.0f; - mFallHeight = 0.0f; + mFallHeight = mPtr.getRefData().getPosition().pos[2]; } if(!onground && !flying && !inwater) @@ -854,7 +854,7 @@ void CharacterController::update(float duration) } } - mFallHeight = 0; + mFallHeight = mPtr.getRefData().getPosition().pos[2]; } else { From 4265dddc40923d1fbcdbb848a0e06a5df4e66308 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 22:53:29 +0200 Subject: [PATCH 23/62] Add MWWorld::isSlowFalling(Ptr) --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwworld/worldimp.cpp | 13 +++++++++++++ apps/openmw/mwworld/worldimp.hpp | 1 + 3 files changed, 15 insertions(+) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f8453afed6..db03cb7bf8 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -324,6 +324,7 @@ namespace MWBase virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0; virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0; + virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0; virtual bool isSwimming(const MWWorld::Ptr &object) const = 0; ///Is the head of the creature underwater? virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f3d4c81b76..34ac011027 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1582,6 +1582,19 @@ namespace MWWorld return false; } + bool + World::isSlowFalling(const MWWorld::Ptr &ptr) const + { + if(!ptr.getClass().isActor()) + return false; + + const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr); + if(stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::SlowFall)).mMagnitude > 0) + return true; + + return false; + } + bool World::isSubmerged(const MWWorld::Ptr &object) const { float *fpos = object.getRefData().getPosition().pos; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 53b01f1abf..333beb8314 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -355,6 +355,7 @@ namespace MWWorld virtual void processChangedSettings(const Settings::CategorySettingVector& settings); virtual bool isFlying(const MWWorld::Ptr &ptr) const; + virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const; ///Is the head of the creature underwater? virtual bool isSubmerged(const MWWorld::Ptr &object) const; virtual bool isSwimming(const MWWorld::Ptr &object) const; From 2abe5c1c9a304bae549d4591f0c11ccd84286c9b Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Wed, 2 Oct 2013 22:54:36 +0200 Subject: [PATCH 24/62] Acrobatics: do not apply fall damages when slowfalling spell effect is active If spell effect ends up in mid-air, calculate fall height from then. --- apps/openmw/mwmechanics/character.cpp | 10 +++++++++- apps/openmw/mwmechanics/character.hpp | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 0924e36b9a..c4260d907d 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -776,7 +776,15 @@ void CharacterController::update(float duration) { // The player is in the air (either getting up —ascending part of jump— or falling). - mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]); + if (world->isSlowFalling(mPtr)) + { + // SlowFalling spell effect is active, do not keep previous fall height + mFallHeight = mPtr.getRefData().getPosition().pos[2]; + } + else + { + mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]); + } const MWWorld::Store &gmst = world->getStore().get(); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 7b9dda49aa..8670b385e3 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -3,6 +3,8 @@ #include +#include + #include "../mwworld/ptr.hpp" namespace MWWorld From 75991fedfdc17eacaf0e08c5032ecee550434d16 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 4 Oct 2013 12:33:55 +0200 Subject: [PATCH 25/62] removed some garbage --- issue912 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 issue912 diff --git a/issue912 b/issue912 deleted file mode 100644 index 604cc392c8..0000000000 --- a/issue912 +++ /dev/null @@ -1 +0,0 @@ -branch for issue912 From 6983a55a16db58c882c654766006ac98a83bc7b3 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Sun, 6 Oct 2013 19:32:40 -0500 Subject: [PATCH 26/62] Magic effect display improvement. Related to Bug #794. Show the "x INT" notation for Fortify Max. Magicka. Show "%" notation for weakness / resistance effects. --- apps/openmw/mwgui/spellicons.cpp | 25 ++++++++++++++++++++----- apps/openmw/mwgui/widgets.cpp | 29 ++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 9812c0f8a9..e7a1f32a4d 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -171,11 +171,26 @@ namespace MWGui if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) { - std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); - std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); - - sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); - sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); + if (it->first == 84) // special handling for fortify maximum magicka + { + std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); + sourcesDescription += " " + boost::lexical_cast(effectIt->mMagnitude / 10.0f) + timesInt; + } + else + { + std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); + std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); + std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); + const bool usePct = ( + (it->first >= 28 && it->first <= 36) || // Weakness effects + (it->first >= 90 && it->first <= 99) ); // Resistance effects + + sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude) + " "; + if ( usePct ) + sourcesDescription += pct; + else + sourcesDescription += ((effectIt->mMagnitude > 1) ? pts : pt); + } } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index dea64ae8cf..d435dd6f93 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -405,6 +405,7 @@ namespace MWGui std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); + std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); std::string to = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "") + " "; std::string sec = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", ""); std::string secs = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", ""); @@ -423,11 +424,33 @@ namespace MWGui if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) { - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts); + // Fortify Maximum Magicka display rules: + if ( mEffectParams.mEffectID == 84 ) + { + std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); + std::string times = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimes", ""); + if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin / 10.0f) + timesInt; + else + { + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin / 10.0f) + times + " " + to + boost::lexical_cast(mEffectParams.mMagnMax / 10.0f) + timesInt; + } + } else { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " " + pts; + const bool usePct = ( + (mEffectParams.mEffectID >= 28 && mEffectParams.mEffectID <= 36) || // Weakness effects + (mEffectParams.mEffectID >= 90 && mEffectParams.mEffectID <= 99) ); // Resistance effects + if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " "; + else + { + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " "; + } + if ( usePct ) + spellLine += pct; + else + spellLine += ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); } } From 707f45aa8e758ef34da14cffc83dbf6c992f4008 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Sun, 6 Oct 2013 19:46:04 -0500 Subject: [PATCH 27/62] Magic Effect Display improvement. Related to Bug #794. Always show one decimal point precision for Fortify Max. Magicka effect. --- apps/openmw/mwgui/spellicons.cpp | 7 ++++++- apps/openmw/mwgui/widgets.cpp | 17 +++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index e7a1f32a4d..93727ed7fa 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -2,6 +2,9 @@ #include +#include +#include + #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -174,7 +177,9 @@ namespace MWGui if (it->first == 84) // special handling for fortify maximum magicka { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); - sourcesDescription += " " + boost::lexical_cast(effectIt->mMagnitude / 10.0f) + timesInt; + std::stringstream formatter; + formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt; + sourcesDescription += formatter.str(); } else { diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index d435dd6f93..e46838a647 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -2,6 +2,9 @@ #include +#include +#include + #include #include #include @@ -429,12 +432,14 @@ namespace MWGui { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); std::string times = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimes", ""); - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin / 10.0f) + timesInt; - else - { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin / 10.0f) + times + " " + to + boost::lexical_cast(mEffectParams.mMagnMax / 10.0f) + timesInt; - } + std::stringstream formatter; + + formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f); + if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) + formatter << times << " " << to << " " << (mEffectParams.mMagnMax / 10.0f); + formatter << timesInt; + + spellLine += formatter.str(); } else { From 6303e56ce4521fda92bc25dc6bc32b8ad4bdfcbb Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Sun, 6 Oct 2013 20:35:59 -0500 Subject: [PATCH 28/62] Magic Effect Display cleanup: Don't put spaces in percentages. --- apps/openmw/mwgui/spellicons.cpp | 4 ++-- apps/openmw/mwgui/widgets.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 93727ed7fa..3b30572485 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -190,11 +190,11 @@ namespace MWGui (it->first >= 28 && it->first <= 36) || // Weakness effects (it->first >= 90 && it->first <= 99) ); // Resistance effects - sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude) + " "; + sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); if ( usePct ) sourcesDescription += pct; else - sourcesDescription += ((effectIt->mMagnitude > 1) ? pts : pt); + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); } } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index e46838a647..e942aa703e 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -447,15 +447,15 @@ namespace MWGui (mEffectParams.mEffectID >= 28 && mEffectParams.mEffectID <= 36) || // Weakness effects (mEffectParams.mEffectID >= 90 && mEffectParams.mEffectID <= 99) ); // Resistance effects if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + " "; + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin); else { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax) + " "; + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax); } if ( usePct ) spellLine += pct; else - spellLine += ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); + spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); } } From 4d6c3cdf09faf49cd36f9d0607c657f17c8e10b1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 7 Oct 2013 08:55:04 +0200 Subject: [PATCH 29/62] removed more garbage --- apps/opencs/ocspropertywidget.cpp | 6 ------ apps/opencs/ocspropertywidget.hpp | 18 ------------------ 2 files changed, 24 deletions(-) delete mode 100644 apps/opencs/ocspropertywidget.cpp delete mode 100644 apps/opencs/ocspropertywidget.hpp diff --git a/apps/opencs/ocspropertywidget.cpp b/apps/opencs/ocspropertywidget.cpp deleted file mode 100644 index 68315201ae..0000000000 --- a/apps/opencs/ocspropertywidget.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "ocspropertywidget.hpp" - -OcsPropertyWidget::OcsPropertyWidget(QObject *parent) : - QObject(parent) -{ -} diff --git a/apps/opencs/ocspropertywidget.hpp b/apps/opencs/ocspropertywidget.hpp deleted file mode 100644 index fc64a0a692..0000000000 --- a/apps/opencs/ocspropertywidget.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef OCSPROPERTYWIDGET_HPP -#define OCSPROPERTYWIDGET_HPP - -#include - -class OcsPropertyWidget : public QObject -{ - Q_OBJECT -public: - explicit OcsPropertyWidget(QObject *parent = 0); - -signals: - -public slots: - -}; - -#endif // OCSPROPERTYWIDGET_HPP From 74cee662731d0004adbfdaa657eed3bdc8c45986 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 7 Oct 2013 11:14:11 +0200 Subject: [PATCH 30/62] consolidated magic numbers for button size --- apps/opencs/view/world/scenesubview.cpp | 10 +++++----- apps/opencs/view/world/scenetool.cpp | 6 ++++-- apps/opencs/view/world/scenetool.hpp | 4 +++- apps/opencs/view/world/scenetoolbar.cpp | 10 ++++++++-- apps/opencs/view/world/scenetoolbar.hpp | 5 ++++- apps/opencs/view/world/scenetoolmode.cpp | 8 +++++--- apps/opencs/view/world/scenetoolmode.hpp | 5 ++++- 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 36ace68f0e..e3618c5493 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -29,16 +29,16 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D layout2->setContentsMargins (QMargins (0, 0, 0, 0)); - SceneToolbar *toolbar = new SceneToolbar (this); + SceneToolbar *toolbar = new SceneToolbar (48, this); // test -SceneToolMode *tool = new SceneToolMode (this); +SceneToolMode *tool = new SceneToolMode (toolbar); tool->addButton (":door.png", "a"); tool->addButton (":GMST.png", "b"); tool->addButton (":Info.png", "c"); toolbar->addTool (tool); -toolbar->addTool (new SceneToolMode (this)); -toolbar->addTool (new SceneToolMode (this)); -toolbar->addTool (new SceneToolMode (this)); +toolbar->addTool (new SceneToolMode (toolbar)); +toolbar->addTool (new SceneToolMode (toolbar)); +toolbar->addTool (new SceneToolMode (toolbar)); layout2->addWidget (toolbar, 0); /// \todo replace with rendering widget diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index d7d37c98f6..2140cd1e02 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -1,10 +1,12 @@ #include "scenetool.hpp" -CSVWorld::SceneTool::SceneTool (QWidget *parent) : QPushButton (parent) +#include "scenetoolbar.hpp" + +CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent) { setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - setFixedSize (48, 48); + setFixedSize (parent->getButtonSize(), parent->getButtonSize()); connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); } diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp index d5c9dd5d2f..2e83b0c6d7 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/world/scenetool.hpp @@ -5,6 +5,8 @@ namespace CSVWorld { + class SceneToolbar; + ///< \brief Tool base class class SceneTool : public QPushButton { @@ -12,7 +14,7 @@ namespace CSVWorld public: - SceneTool (QWidget *parent = 0); + SceneTool (SceneToolbar *parent); virtual void showPanel (const QPoint& position) = 0; diff --git a/apps/opencs/view/world/scenetoolbar.cpp b/apps/opencs/view/world/scenetoolbar.cpp index 7c716b5fce..2972c53913 100644 --- a/apps/opencs/view/world/scenetoolbar.cpp +++ b/apps/opencs/view/world/scenetoolbar.cpp @@ -5,9 +5,10 @@ #include "scenetool.hpp" -CSVWorld::SceneToolbar::SceneToolbar (QWidget *parent) : QWidget (parent) +CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent) +: QWidget (parent), mButtonSize (buttonSize) { - setFixedWidth (48); + setFixedWidth (mButtonSize); mLayout = new QVBoxLayout (this); mLayout->setAlignment (Qt::AlignTop); @@ -20,4 +21,9 @@ CSVWorld::SceneToolbar::SceneToolbar (QWidget *parent) : QWidget (parent) void CSVWorld::SceneToolbar::addTool (SceneTool *tool) { mLayout->addWidget (tool, 0, Qt::AlignTop); +} + +int CSVWorld::SceneToolbar::getButtonSize() const +{ + return mButtonSize; } \ No newline at end of file diff --git a/apps/opencs/view/world/scenetoolbar.hpp b/apps/opencs/view/world/scenetoolbar.hpp index 00631c360c..f713ca3dff 100644 --- a/apps/opencs/view/world/scenetoolbar.hpp +++ b/apps/opencs/view/world/scenetoolbar.hpp @@ -14,12 +14,15 @@ namespace CSVWorld Q_OBJECT QVBoxLayout *mLayout; + int mButtonSize; public: - SceneToolbar (QWidget *parent); + SceneToolbar (int buttonSize, QWidget *parent = 0); void addTool (SceneTool *tool); + + int getButtonSize() const; }; } diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp index b4277bcbe7..2435a8e357 100644 --- a/apps/opencs/view/world/scenetoolmode.cpp +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -5,8 +5,10 @@ #include #include -CSVWorld::SceneToolMode::SceneToolMode (QWidget *parent) -: SceneTool (parent) +#include "scenetoolbar.hpp" + +CSVWorld::SceneToolMode::SceneToolMode (SceneToolbar *parent) +: SceneTool (parent), mButtonSize (parent->getButtonSize()) { mPanel = new QFrame (this, Qt::Popup); @@ -27,7 +29,7 @@ void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::str { QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel); button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - button->setFixedSize (48, 48); + button->setFixedSize (mButtonSize, mButtonSize); mLayout->addWidget (button); diff --git a/apps/opencs/view/world/scenetoolmode.hpp b/apps/opencs/view/world/scenetoolmode.hpp index feee78376b..a8fe2b5a6c 100644 --- a/apps/opencs/view/world/scenetoolmode.hpp +++ b/apps/opencs/view/world/scenetoolmode.hpp @@ -9,6 +9,8 @@ class QHBoxLayout; namespace CSVWorld { + class SceneToolbar; + ///< \brief Mode selector tool class SceneToolMode : public SceneTool { @@ -17,10 +19,11 @@ namespace CSVWorld QWidget *mPanel; QHBoxLayout *mLayout; std::map mButtons; // widget, id + int mButtonSize; public: - SceneToolMode (QWidget *parent = 0); + SceneToolMode (SceneToolbar *parent); virtual void showPanel (const QPoint& position); From 065f435225c66bb9b51dd4eb0660d8f081b1b6a4 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Mon, 7 Oct 2013 20:02:20 -0500 Subject: [PATCH 31/62] Format fix: remove extra spaces from ranged TimesINT formatting. --- apps/openmw/mwgui/widgets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index e942aa703e..9278c1a564 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -436,7 +436,7 @@ namespace MWGui formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f); if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) - formatter << times << " " << to << " " << (mEffectParams.mMagnMax / 10.0f); + formatter << times << to << (mEffectParams.mMagnMax / 10.0f); formatter << timesInt; spellLine += formatter.str(); From 6ab7002908b66098afc260d6ef3a8f235f58ce17 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Mon, 7 Oct 2013 22:28:55 -0500 Subject: [PATCH 32/62] MagicEffect: Put magnitude type into ESM::MagicEffect helper. --- apps/openmw/mwgui/spellicons.cpp | 41 ++++++++++++++------------------ apps/openmw/mwgui/widgets.cpp | 28 ++++++++-------------- components/esm/loadmgef.cpp | 11 +++++++++ components/esm/loadmgef.hpp | 8 +++++++ 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 3b30572485..0e59230c73 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -172,30 +172,25 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->getGameSettingString( ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")"; - if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) + int displayType = effect->getMagnitudeDisplayType(); + if (displayType == ESM::MagicEffect::MDT_TimesInt) { - if (it->first == 84) // special handling for fortify maximum magicka - { - std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); - std::stringstream formatter; - formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt; - sourcesDescription += formatter.str(); - } - else - { - std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); - std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); - std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); - const bool usePct = ( - (it->first >= 28 && it->first <= 36) || // Weakness effects - (it->first >= 90 && it->first <= 99) ); // Resistance effects - - sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); - if ( usePct ) - sourcesDescription += pct; - else - sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); - } + std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); + std::stringstream formatter; + formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt; + sourcesDescription += formatter.str(); + } + else if ( displayType != ESM::MagicEffect::MDT_None ) + { + std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); + std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); + std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); + + sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); + if ( displayType == ESM::MagicEffect::MDT_Percentage ) + sourcesDescription += pct; + else // ESM::MagicEffect::MDT_Points + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 9278c1a564..f3eda4b226 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -425,11 +425,9 @@ namespace MWGui spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], ""); } - if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) - { - // Fortify Maximum Magicka display rules: - if ( mEffectParams.mEffectID == 84 ) - { + if (mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) { + int displayType = magicEffect->getMagnitudeDisplayType(); + if ( displayType == ESM::MagicEffect::MDT_TimesInt ) { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); std::string times = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimes", ""); std::stringstream formatter; @@ -441,20 +439,14 @@ namespace MWGui spellLine += formatter.str(); } - else - { - const bool usePct = ( - (mEffectParams.mEffectID >= 28 && mEffectParams.mEffectID <= 36) || // Weakness effects - (mEffectParams.mEffectID >= 90 && mEffectParams.mEffectID <= 99) ); // Resistance effects - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin); - else - { - spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin) + to + boost::lexical_cast(mEffectParams.mMagnMax); - } - if ( usePct ) + else if ( displayType != ESM::MagicEffect::MDT_None ) { + spellLine += " " + boost::lexical_cast(mEffectParams.mMagnMin); + if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) + spellLine += to + boost::lexical_cast(mEffectParams.mMagnMax); + + if ( displayType == ESM::MagicEffect::MDT_Percentage ) spellLine += pct; - else + else // ESM::MagicEffect::MDT_Points spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); } } diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 060645b5f4..0dfc2be9c7 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -274,5 +274,16 @@ short MagicEffect::effectStringToId(const std::string &effect) return name->first; } +MagicEffect::MagnitudeDisplayType MagicEffect::getMagnitudeDisplayType() const { + if ( mData.mFlags & NoMagnitude ) + return MDT_None; + if ( mIndex == 84 ) + return MDT_TimesInt; + if ( ( mIndex >= 28 && mIndex <= 36 ) + || ( mIndex >= 90 && mIndex <= 99 ) ) + return MDT_Percentage; + + return MDT_Points; +} } diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index b74efb4662..c3af56e3af 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -32,6 +32,13 @@ struct MagicEffect Negative = 0x0800 // A harmful effect. Will determine whether // eg. NPCs regard this spell as an attack. (same as 0x10?) }; + enum MagnitudeDisplayType + { + MDT_None, + MDT_Points, + MDT_Percentage, + MDT_TimesInt + }; struct MEDTstruct { @@ -47,6 +54,7 @@ struct MagicEffect static const std::string &effectIdToString(short effectID); static short effectStringToId(const std::string &effect); + MagnitudeDisplayType getMagnitudeDisplayType() const; MEDTstruct mData; From 296b2ab87025c0d26d5010dd38a8b3cb01e2ecda Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Tue, 8 Oct 2013 23:55:14 -0500 Subject: [PATCH 33/62] Magic Effect: Recognize other display types. Fill out the list of effects which use percentage formatting. Add in types which use Feet and level labels. --- components/esm/loadmgef.cpp | 9 ++++++++- components/esm/loadmgef.hpp | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 0dfc2be9c7..19d535600b 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -279,8 +279,15 @@ MagicEffect::MagnitudeDisplayType MagicEffect::getMagnitudeDisplayType() const { return MDT_None; if ( mIndex == 84 ) return MDT_TimesInt; + if ( mIndex == 59 || + ( mIndex >= 64 && mIndex <= 66) ) + return MDT_Feet; + if ( mIndex == 118 || mIndex == 119 ) + return MDT_Level; if ( ( mIndex >= 28 && mIndex <= 36 ) - || ( mIndex >= 90 && mIndex <= 99 ) ) + || ( mIndex >= 90 && mIndex <= 99 ) + || mIndex == 40 || mIndex == 47 + || mIndex == 57 || mIndex == 68 ) return MDT_Percentage; return MDT_Points; diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index c3af56e3af..f139fa32c7 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -35,8 +35,10 @@ struct MagicEffect enum MagnitudeDisplayType { MDT_None, - MDT_Points, + MDT_Feet, + MDT_Level, MDT_Percentage, + MDT_Points, MDT_TimesInt }; From 6e4978643c7e209e0b2a82af0fdf04aa44c50bf4 Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Wed, 9 Oct 2013 00:08:11 -0500 Subject: [PATCH 34/62] Magic Effect descriptions: support feet / level modes. Show proper suffixes for all magnitudes. Drop extra 'times' symbol in 'timesInt format (not consistent with other magnitude displays). --- apps/openmw/mwgui/spellicons.cpp | 23 ++++++++++++++++------- apps/openmw/mwgui/widgets.cpp | 12 +++++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 0e59230c73..0c303485af 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -172,7 +172,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->getGameSettingString( ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")"; - int displayType = effect->getMagnitudeDisplayType(); + ESM::MagicEffect::MagnitudeDisplayType displayType = effect->getMagnitudeDisplayType(); if (displayType == ESM::MagicEffect::MDT_TimesInt) { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); @@ -182,15 +182,24 @@ namespace MWGui } else if ( displayType != ESM::MagicEffect::MDT_None ) { - std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); - std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); - std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); - sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); + if ( displayType == ESM::MagicEffect::MDT_Percentage ) - sourcesDescription += pct; + sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); + else if ( displayType == ESM::MagicEffect::MDT_Feet ) + sourcesDescription += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", ""); + else if ( displayType == ESM::MagicEffect::MDT_Level ) + { + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? + MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", "") : + MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", "") ); + } else // ESM::MagicEffect::MDT_Points - sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); + { + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? + MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "") : + MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "") ); + } } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index f3eda4b226..3fc3187e80 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -409,6 +409,9 @@ namespace MWGui std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", ""); + std::string ft = MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", ""); + std::string lvl = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", ""); + std::string lvls = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", ""); std::string to = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "") + " "; std::string sec = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", ""); std::string secs = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", ""); @@ -426,15 +429,14 @@ namespace MWGui } if (mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) { - int displayType = magicEffect->getMagnitudeDisplayType(); + ESM::MagicEffect::MagnitudeDisplayType displayType = magicEffect->getMagnitudeDisplayType(); if ( displayType == ESM::MagicEffect::MDT_TimesInt ) { std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", ""); - std::string times = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimes", ""); std::stringstream formatter; formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f); if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) - formatter << times << to << (mEffectParams.mMagnMax / 10.0f); + formatter << to << (mEffectParams.mMagnMax / 10.0f); formatter << timesInt; spellLine += formatter.str(); @@ -446,6 +448,10 @@ namespace MWGui if ( displayType == ESM::MagicEffect::MDT_Percentage ) spellLine += pct; + else if ( displayType == ESM::MagicEffect::MDT_Feet ) + spellLine += " " + ft; + else if ( displayType == ESM::MagicEffect::MDT_Level ) + spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? lvl : lvls ); else // ESM::MagicEffect::MDT_Points spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts ); } From 5ce1f50fab6456afcd5adc781a0e141ea13e6e5b Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Thu, 10 Oct 2013 23:06:37 +0200 Subject: [PATCH 35/62] Cleanup in MWGui::WindowManager constructor initialzation list. Corrected order of initialization list, and added missing member field initializations - without this openmw crashes when installer is interrupted and there are no valid data path in openmw.cfg, as reported by BrotherBrick in: https://forum.openmw.org/viewtopic.php?f=20&p=19501#p19499 Signed-off-by: Lukasz Gromanowski --- apps/openmw/mwgui/windowmanagerimp.cpp | 33 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index bf8b664daa..4b4d2dfd19 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -61,20 +61,23 @@ namespace MWGui const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding) - : mGuiManager(NULL) - , mConsoleOnlyScripts(consoleOnlyScripts) + : mConsoleOnlyScripts(consoleOnlyScripts) + , mGuiManager(NULL) , mRendering(ogre) , mHud(NULL) , mMap(NULL) , mMenu(NULL) - , mStatsWindow(NULL) , mToolTips(NULL) + , mStatsWindow(NULL) , mMessageBoxManager(NULL) , mConsole(NULL) , mJournal(NULL) , mDialogueWindow(NULL) - , mBookWindow(NULL) + , mContainerWindow(NULL) + , mDragAndDrop(NULL) + , mInventoryWindow(NULL) , mScrollWindow(NULL) + , mBookWindow(NULL) , mCountDialog(NULL) , mTradeWindow(NULL) , mSpellBuyingWindow(NULL) @@ -83,27 +86,37 @@ namespace MWGui , mConfirmationDialog(NULL) , mAlchemyWindow(NULL) , mSpellWindow(NULL) + , mQuickKeysMenu(NULL) , mLoadingScreen(NULL) - , mCharGen(NULL) , mLevelupDialog(NULL) , mWaitDialog(NULL) , mSpellCreationDialog(NULL) , mEnchantingDialog(NULL) , mTrainingWindow(NULL) , mMerchantRepair(NULL) - , mRepair(NULL) , mSoulgemDialog(NULL) + , mRepair(NULL) , mCompanionWindow(NULL) + , mTranslationDataStorage (translationDataStorage) + , mSoftwareCursor(NULL) + , mCharGen(NULL) + , mInputBlocker(NULL) + , mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD")) + , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) + , mHudEnabled(true) + , mCursorVisible(true) , mPlayerName() , mPlayerRaceId() , mPlayerAttributes() - , mPlayerMajorSkills() , mPlayerMinorSkills() + , mPlayerMajorSkills() , mPlayerSkillValues() , mPlayerHealth() , mPlayerMagicka() , mPlayerFatigue() , mGui(NULL) + , mGuiModes() + , mCursorManager(NULL) , mGarbageDialogs() , mShown(GW_ALL) , mForceHidden(GW_None) @@ -113,13 +126,7 @@ namespace MWGui , mFPS(0.0f) , mTriangleCount(0) , mBatchCount(0) - , mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD")) - , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) - , mHudEnabled(true) - , mTranslationDataStorage (translationDataStorage) - , mCursorManager(NULL) , mUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI")) - , mCursorVisible(true) { // Set up the GUI system mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath); From a77044cda43e368789bfd036978eb2aa78bb8e66 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 12 Oct 2013 16:15:47 +0200 Subject: [PATCH 36/62] fixed column numbering --- apps/opencs/model/world/columns.cpp | 2 +- apps/opencs/model/world/columns.hpp | 214 ++++++++++++++-------------- 2 files changed, 108 insertions(+), 108 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 25047807ab..ca37840ad6 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -51,7 +51,7 @@ namespace CSMWorld { ColumnId_FactionIndex, "Faction Index" }, { ColumnId_Charges, "Charges" }, { ColumnId_Enchantment, "Enchantment" }, - { ColumnId_Value, "Coin Value" }, + { ColumnId_CoinValue, "Coin Value" }, { ColumnId_Teleport, "Teleport" }, { ColumnId_TeleportCell, "Teleport Cell" }, { ColumnId_LockLevel, "Lock Level" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 582f5102b9..9b26cac4c7 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -45,113 +45,113 @@ namespace CSMWorld ColumnId_Charges = 32, ColumnId_Enchantment = 33, ColumnId_CoinValue = 34, - ColumnId_Teleport = 25, - ColumnId_TeleportCell = 26, - ColumnId_LockLevel = 27, - ColumnId_Key = 28, - ColumnId_Trap = 29, - ColumnId_BeastRace = 30, - ColumnId_AutoCalc = 31, - ColumnId_StarterSpell = 32, - ColumnId_AlwaysSucceeds = 33, - ColumnId_SleepForbidden = 34, - ColumnId_InteriorWater = 35, - ColumnId_InteriorSky = 36, - ColumnId_Model = 37, - ColumnId_Script = 38, - ColumnId_Icon = 39, - ColumnId_Weight = 40, - ColumnId_EnchantmentPoints = 31, - ColumnId_Quality = 32, - ColumnId_Ai = 33, - ColumnId_AiHello = 34, - ColumnId_AiFlee = 35, - ColumnId_AiFight = 36, - ColumnId_AiAlarm = 37, - ColumnId_BuysWeapons = 38, - ColumnId_BuysArmor = 39, - ColumnId_BuysClothing = 40, - ColumnId_BuysBooks = 41, - ColumnId_BuysIngredients = 42, - ColumnId_BuysLockpicks = 43, - ColumnId_BuysProbes = 44, - ColumnId_BuysLights = 45, - ColumnId_BuysApparati = 46, - ColumnId_BuysRepairItems = 47, - ColumnId_BuysMiscItems = 48, - ColumnId_BuysPotions = 49, - ColumnId_BuysMagicItems = 50, - ColumnId_SellsSpells = 51, - ColumnId_Trainer = 52, - ColumnId_Spellmaking = 53, - ColumnId_EnchantingService = 54, - ColumnId_RepairService = 55, - ColumnId_ApparatusType = 56, - ColumnId_ArmorType = 57, - ColumnId_Health = 58, - ColumnId_ArmorValue = 59, - ColumnId_Scroll = 60, - ColumnId_ClothingType = 61, - ColumnId_WeightCapacity = 62, - ColumnId_OrganicContainer = 63, - ColumnId_Respawn = 64, - ColumnId_CreatureType = 65, - ColumnId_SoulPoints = 66, - ColumnId_OriginalCreature = 67, - ColumnId_Biped = 68, - ColumnId_HasWeapon = 69, - ColumnId_NoMovement = 70, - ColumnId_Swims = 71, - ColumnId_Flies = 72, - ColumnId_Walks = 73, - ColumnId_Essential = 74, - ColumnId_SkeletonBlood = 75, - ColumnId_MetalBlood = 76, - ColumnId_OpenSound = 77, - ColumnId_CloseSound = 78, - ColumnId_Duration = 79, - ColumnId_Radius = 80, - ColumnId_Colour = 81, - ColumnId_Sound = 82, - ColumnId_Dynamic = 83, - ColumnId_Portable = 84, - ColumnId_NegativeLight = 85, - ColumnId_Flickering = 86, - ColumnId_SlowFlickering = 87, - ColumnId_Pulsing = 88, - ColumnId_SlowPulsing = 89, - ColumnId_Fire = 90, - ColumnId_OffByDefault = 91, - ColumnId_IsKey = 92, - ColumnId_Race = 93, - ColumnId_Class = 94, - Columnid_Hair = 95, - ColumnId_Head = 96, - ColumnId_Female = 97, - ColumnId_WeaponType = 98, - ColumnId_WeaponSpeed = 99, - ColumnId_WeaponReach = 100, - ColumnId_MinChop = 101, - ColumnId_MaxChip = 102, - Columnid_MinSlash = 103, - ColumnId_MaxSlash = 104, - ColumnId_MinThrust = 105, - ColumnId_MaxThrust = 106, - ColumnId_Magical = 107, - ColumnId_Silver = 108, - ColumnId_Filter = 109, - ColumnId_PositionXPos = 110, - ColumnId_PositionYPos = 111, - ColumnId_PositionZPos = 112, - ColumnId_PositionXRot = 113, - ColumnId_PositionYRot = 114, - ColumnId_PositionZRot = 115, - ColumnId_DoorPositionXPos = 116, - ColumnId_DoorPositionYPos = 117, - ColumnId_DoorPositionZPos = 118, - ColumnId_DoorPositionXRot = 119, - ColumnId_DoorPositionYRot = 120, - ColumnId_DoorPositionZRot = 121, + ColumnId_Teleport = 35, + ColumnId_TeleportCell = 36, + ColumnId_LockLevel = 37, + ColumnId_Key = 38, + ColumnId_Trap = 39, + ColumnId_BeastRace = 40, + ColumnId_AutoCalc = 41, + ColumnId_StarterSpell = 42, + ColumnId_AlwaysSucceeds = 43, + ColumnId_SleepForbidden = 44, + ColumnId_InteriorWater = 45, + ColumnId_InteriorSky = 46, + ColumnId_Model = 47, + ColumnId_Script = 48, + ColumnId_Icon = 49, + ColumnId_Weight = 50, + ColumnId_EnchantmentPoints = 51, + ColumnId_Quality = 52, + ColumnId_Ai = 53, + ColumnId_AiHello = 54, + ColumnId_AiFlee = 55, + ColumnId_AiFight = 56, + ColumnId_AiAlarm = 57, + ColumnId_BuysWeapons = 58, + ColumnId_BuysArmor = 59, + ColumnId_BuysClothing = 60, + ColumnId_BuysBooks = 61, + ColumnId_BuysIngredients = 62, + ColumnId_BuysLockpicks = 63, + ColumnId_BuysProbes = 64, + ColumnId_BuysLights = 65, + ColumnId_BuysApparati = 66, + ColumnId_BuysRepairItems = 67, + ColumnId_BuysMiscItems = 68, + ColumnId_BuysPotions = 69, + ColumnId_BuysMagicItems = 70, + ColumnId_SellsSpells = 71, + ColumnId_Trainer = 72, + ColumnId_Spellmaking = 73, + ColumnId_EnchantingService = 74, + ColumnId_RepairService = 75, + ColumnId_ApparatusType = 76, + ColumnId_ArmorType = 77, + ColumnId_Health = 78, + ColumnId_ArmorValue = 79, + ColumnId_Scroll = 80, + ColumnId_ClothingType = 81, + ColumnId_WeightCapacity = 82, + ColumnId_OrganicContainer = 83, + ColumnId_Respawn = 84, + ColumnId_CreatureType = 85, + ColumnId_SoulPoints = 86, + ColumnId_OriginalCreature = 87, + ColumnId_Biped = 88, + ColumnId_HasWeapon = 89, + ColumnId_NoMovement = 90, + ColumnId_Swims = 91, + ColumnId_Flies = 92, + ColumnId_Walks = 93, + ColumnId_Essential = 94, + ColumnId_SkeletonBlood = 95, + ColumnId_MetalBlood = 96, + ColumnId_OpenSound = 97, + ColumnId_CloseSound = 98, + ColumnId_Duration = 99, + ColumnId_Radius = 100, + ColumnId_Colour = 101, + ColumnId_Sound = 102, + ColumnId_Dynamic = 103, + ColumnId_Portable = 104, + ColumnId_NegativeLight = 105, + ColumnId_Flickering = 106, + ColumnId_SlowFlickering = 107, + ColumnId_Pulsing = 108, + ColumnId_SlowPulsing = 109, + ColumnId_Fire = 110, + ColumnId_OffByDefault = 111, + ColumnId_IsKey = 112, + ColumnId_Race = 113, + ColumnId_Class = 114, + Columnid_Hair = 115, + ColumnId_Head = 116, + ColumnId_Female = 117, + ColumnId_WeaponType = 118, + ColumnId_WeaponSpeed = 119, + ColumnId_WeaponReach = 120, + ColumnId_MinChop = 121, + ColumnId_MaxChip = 122, + Columnid_MinSlash = 123, + ColumnId_MaxSlash = 124, + ColumnId_MinThrust = 125, + ColumnId_MaxThrust = 126, + ColumnId_Magical = 127, + ColumnId_Silver = 128, + ColumnId_Filter = 129, + ColumnId_PositionXPos = 130, + ColumnId_PositionYPos = 131, + ColumnId_PositionZPos = 132, + ColumnId_PositionXRot = 133, + ColumnId_PositionYRot = 134, + ColumnId_PositionZRot = 135, + ColumnId_DoorPositionXPos = 136, + ColumnId_DoorPositionYPos = 137, + ColumnId_DoorPositionZPos = 138, + ColumnId_DoorPositionXRot = 139, + ColumnId_DoorPositionYRot = 140, + ColumnId_DoorPositionZRot = 141, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. From a29b8667efc3485e33e83d63ccf680d300ddc6a6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 12 Oct 2013 16:29:36 +0200 Subject: [PATCH 37/62] fixed string filter on boolean columns when testing against the value false --- apps/opencs/model/filter/textnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index f3d98ce535..133208b315 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -47,7 +47,7 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, } else if (data.type()==QVariant::Bool) { - string = data.toBool() ? "true" : " false"; + string = data.toBool() ? "true" : "false"; } else return false; From b5d620a8dcb9ea6a9cdcacab70784ebfce78d3f8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 12 Oct 2013 16:35:59 +0200 Subject: [PATCH 38/62] fixed string filter on enum column when column is empty --- apps/opencs/model/filter/textnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index 133208b315..e335f7ea72 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -34,7 +34,7 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, { string = data.toString(); } - else if (data.type()==QVariant::Int || data.type()==QVariant::UInt || + else if ((data.type()==QVariant::Int || data.type()==QVariant::UInt) && CSMWorld::Columns::hasEnums (static_cast (mColumnId))) { int value = data.toInt(); From cfc30933202a7804be0c5ff5a5de23f908175218 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Sat, 12 Oct 2013 10:46:44 -0400 Subject: [PATCH 39/62] Reverted conditional compiling --- apps/launcher/main.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index df7aa11d47..f67f5edcff 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -62,14 +62,3 @@ int main(int argc, char *argv[]) return returnValue; } -#ifdef _WINDOWS -// If the system compiles for main(), then main will be used. -// If it wants WinMain, this will call main anyways. -int _stdcall WinMain(struct HINSTANCE__ *hInstance, - struct HINSTANCE__ *hPrevInstance, - char *lpszCmdLine, - int nCmdShow) -{ - return main(__argc, __argv); -} -#endif \ No newline at end of file From 141382b8c0b879803bffa0e41f54556b2f9f3d6c Mon Sep 17 00:00:00 2001 From: Jordan Ayers Date: Sat, 12 Oct 2013 14:48:37 -0500 Subject: [PATCH 40/62] COC Command: Exterior cell selection fix. Return the northernmost cell of the easternmost matching column for Ext. cells. --- apps/openmw/mwworld/store.hpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 2ee23dbd61..90452f6614 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -656,26 +656,38 @@ namespace MWWorld return iterator(mSharedExt.end()); } - /// \todo implement appropriate index + // Return the northernmost cell in the easternmost column. const ESM::Cell *searchExtByName(const std::string &id) const { + ESM::Cell *cell = 0; std::vector::const_iterator it = mSharedExt.begin(); for (; it != mSharedExt.end(); ++it) { if (Misc::StringUtils::ciEqual((*it)->mName, id)) { - return *it; + if ( cell == 0 || + ( (*it)->mData.mX > cell->mData.mX ) || + ( (*it)->mData.mX == cell->mData.mX && (*it)->mData.mY > cell->mData.mY ) ) + { + cell = *it; + } } } - return 0; + return cell; } - /// \todo implement appropriate index + // Return the northernmost cell in the easternmost column. const ESM::Cell *searchExtByRegion(const std::string &id) const { + ESM::Cell *cell = 0; std::vector::const_iterator it = mSharedExt.begin(); for (; it != mSharedExt.end(); ++it) { if (Misc::StringUtils::ciEqual((*it)->mRegion, id)) { - return *it; + if ( cell == 0 || + ( (*it)->mData.mX > cell->mData.mX ) || + ( (*it)->mData.mX == cell->mData.mX && (*it)->mData.mY > cell->mData.mY ) ) + { + cell = *it; + } } } - return 0; + return cell; } size_t getSize() const { From dcfff7946064b47610b9c88b4133b4cce2cc524f Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Sun, 13 Oct 2013 00:32:28 +0200 Subject: [PATCH 41/62] Regenerate fatigue over time --- apps/openmw/mwmechanics/actors.cpp | 52 +++++++++++++++++------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index f9b5b695ae..70b820f8c0 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -31,11 +31,14 @@ namespace MWMechanics calculateDynamicStats (ptr); calculateCreatureStatModifiers (ptr); - // AI if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) { + // AI CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); creatureStats.getAiSequence().execute (ptr); + + // fatigue restoration + calculateRestoration(ptr, duration); } } @@ -93,39 +96,29 @@ namespace MWMechanics void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration) { CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); + const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); + + int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); + + float capacity = MWWorld::Class::get(ptr).getCapacity(ptr); + float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr); + float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity); + if (normalizedEncumbrance > 1) + normalizedEncumbrance = 1; if (duration == 3600) { - bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0; + // the actor is sleeping, restore health and magicka - int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); + bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0; DynamicStat health = stats.getHealth(); health.setCurrent (health.getCurrent() + 0.1 * endurance); stats.setHealth (health); - const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - - float fFatigueReturnBase = store.get().find("fFatigueReturnBase")->getFloat (); - float fFatigueReturnMult = store.get().find("fFatigueReturnMult")->getFloat (); - float fEndFatigueMult = store.get().find("fEndFatigueMult")->getFloat (); - - float capacity = MWWorld::Class::get(ptr).getCapacity(ptr); - float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr); - float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity); - if (normalizedEncumbrance > 1) - normalizedEncumbrance = 1; - - float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); - x *= fEndFatigueMult * endurance; - - DynamicStat fatigue = stats.getFatigue(); - fatigue.setCurrent (fatigue.getCurrent() + 3600 * x); - stats.setFatigue (fatigue); - if (!stunted) { - float fRestMagicMult = store.get().find("fRestMagicMult")->getFloat (); + float fRestMagicMult = settings.find("fRestMagicMult")->getFloat (); DynamicStat magicka = stats.getMagicka(); magicka.setCurrent (magicka.getCurrent() @@ -133,6 +126,19 @@ namespace MWMechanics stats.setMagicka (magicka); } } + + // restore fatigue + + float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat (); + float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat (); + float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat (); + + float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); + x *= fEndFatigueMult * endurance; + + DynamicStat fatigue = stats.getFatigue(); + fatigue.setCurrent (fatigue.getCurrent() + duration * x); + stats.setFatigue (fatigue); } void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr) From c8d0fb8c4e6a5a1230261c661b3c7b1fda47537b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 13 Oct 2013 14:43:59 +0200 Subject: [PATCH 42/62] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 6e8e366124..bd0c6ca743 100644 --- a/credits.txt +++ b/credits.txt @@ -12,6 +12,7 @@ Marc Zinnschlag (Zini) - Lead Programmer/Project Manager Adam Hogan (aurix) Aleksandar Jovanov +Alex Haddad (rainChu) Alex McKibben (WeirdSexy) Alexander Nadeau (wareya) Alexander Olofsson (Ace) From 4624bed899568f8465399048502b1e0ef9aa073c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 13 Oct 2013 15:41:48 +0200 Subject: [PATCH 43/62] changed handling of scene toolbar button icons --- apps/opencs/view/world/scenetool.cpp | 5 ----- apps/opencs/view/world/scenetool.hpp | 4 ---- apps/opencs/view/world/scenetoolmode.cpp | 5 ++++- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/opencs/view/world/scenetool.cpp b/apps/opencs/view/world/scenetool.cpp index 2140cd1e02..320deb1ba9 100644 --- a/apps/opencs/view/world/scenetool.cpp +++ b/apps/opencs/view/world/scenetool.cpp @@ -11,11 +11,6 @@ CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent) connect (this, SIGNAL (clicked()), this, SLOT (openRequest())); } -void CSVWorld::SceneTool::updateIcon (const QIcon& icon) -{ - setIcon (icon); -} - void CSVWorld::SceneTool::openRequest() { showPanel (parentWidget()->mapToGlobal (pos())); diff --git a/apps/opencs/view/world/scenetool.hpp b/apps/opencs/view/world/scenetool.hpp index 2e83b0c6d7..07e8b58d72 100644 --- a/apps/opencs/view/world/scenetool.hpp +++ b/apps/opencs/view/world/scenetool.hpp @@ -18,10 +18,6 @@ namespace CSVWorld virtual void showPanel (const QPoint& position) = 0; - protected slots: - - void updateIcon (const QIcon& icon); - private slots: void openRequest(); diff --git a/apps/opencs/view/world/scenetoolmode.cpp b/apps/opencs/view/world/scenetoolmode.cpp index 2435a8e357..281d703b65 100644 --- a/apps/opencs/view/world/scenetoolmode.cpp +++ b/apps/opencs/view/world/scenetoolmode.cpp @@ -36,6 +36,9 @@ void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::str mButtons.insert (std::make_pair (button, id)); connect (button, SIGNAL (clicked()), this, SLOT (selected())); + + if (mButtons.size()==1) + setIcon (button->icon()); } void CSVWorld::SceneToolMode::selected() @@ -47,7 +50,7 @@ void CSVWorld::SceneToolMode::selected() { mPanel->hide(); - emit updateIcon (iter->first->icon()); + setIcon (iter->first->icon()); emit modeChanged (iter->second); } } \ No newline at end of file From f504ab42feb40382228390b4b3a62874303b3de0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 Oct 2013 17:52:14 +0200 Subject: [PATCH 44/62] Turn off vsync while in the loading screen --- apps/openmw/mwgui/loadingscreen.cpp | 22 +++++++++++++++++++++- apps/openmw/mwgui/loadingscreen.hpp | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 9b63dfa76d..d2ebcd109d 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -23,6 +23,7 @@ namespace MWGui , mLastWallpaperChangeTime(0.f) , mFirstLoad(true) , mProgress(0) + , mVSyncWasEnabled(false) { getWidget(mLoadingText, "LoadingText"); getWidget(mProgressBar, "ProgressBar"); @@ -67,6 +68,14 @@ namespace MWGui void LoadingScreen::loadingOn() { + // Temporarily turn off VSync, we want to do actual loading rather than waiting for the screen to sync. + // Threaded loading would be even better, of course - especially because some drivers force VSync to on and we can't change it. + // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/ + mVSyncWasEnabled = mWindow->isVSyncEnabled(); + #if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + mWindow->setVSyncEnabled(false); + #endif + setVisible(true); if (mFirstLoad) @@ -83,6 +92,12 @@ namespace MWGui void LoadingScreen::loadingOff() { + // Re-enable vsync now. + // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/ + #if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + mWindow->setVSyncEnabled(mVSyncWasEnabled); + #endif + setVisible(false); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading); @@ -212,7 +227,12 @@ namespace MWGui // caused a sync / flush and would be expensive). // We're doing this so we can do some actual loading while the GPU is busy with the render. // This means the render is lagging a frame behind, but this is hardly noticable. - mWindow->swapBuffers(false); // never Vsync, makes no sense here +#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + mWindow->swapBuffers(); +#else + // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged when using GLX. Not much we can do :/ + mWindow->swapBuffers(false); +#endif mWindow->update(false); if (!hasCompositor) diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index dde8ff63aa..2d1d7431f8 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -57,6 +57,8 @@ namespace MWGui Ogre::StringVector mResources; + bool mVSyncWasEnabled; + void changeWallpaper(); void draw(); From fa264935ff2ff9d05a7da8334e8836fa53a088ea Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 Oct 2013 17:56:26 +0200 Subject: [PATCH 45/62] We can apply vsync at runtime now that the Ogre bug is fixed. --- apps/openmw/mwgui/settingswindow.cpp | 4 ++++ apps/openmw/mwrender/renderingmanager.cpp | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 3dfa17badc..923b9d01d6 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -363,8 +363,12 @@ namespace MWGui else if (_sender == mVSyncButton) { Settings::Manager::setBool("vsync", "Video", newState); + // Ogre::Window::setVSyncEnabled is bugged in 1.8 +#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0) MWBase::Environment::get().getWindowManager()-> messageBox("VSync will be applied after a restart", std::vector()); +#endif + apply(); } else { diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e03b2ccfcf..8396e70d78 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -760,6 +760,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec || it->second == "resolution y" || it->second == "fullscreen")) changeRes = true; + else if (it->first == "Video" && it->second == "vsync") + { + // setVSyncEnabled is bugged in 1.8 +#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) + mRendering.getWindow()->setVSyncEnabled(Settings::Manager::getBool("vsync", "Video")); +#endif + } else if (it->second == "field of view" && it->first == "General") mRendering.setFov(Settings::Manager::getFloat("field of view", "General")); else if ((it->second == "texture filtering" && it->first == "General") From 2fb059e2fa067f34efc88b8cfb23aafe3f138e55 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 Oct 2013 18:20:55 +0200 Subject: [PATCH 46/62] Don't destroy the SDL window twice --- extern/sdl4ogre/sdlinputwrapper.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 931d6aca30..df74bba3b6 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -30,9 +30,6 @@ namespace SFO InputWrapper::~InputWrapper() { - if(mSDLWindow != NULL) - SDL_DestroyWindow(mSDLWindow); - mSDLWindow = NULL; } void InputWrapper::capture(bool windowEventsOnly) From 683ad40e219f30650440ddee577cec14cf30e4fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 13 Oct 2013 18:28:22 +0200 Subject: [PATCH 47/62] No need for this ifdef since there is a default argument. --- apps/openmw/mwgui/loadingscreen.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index d2ebcd109d..4bd383c2f3 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -227,12 +227,8 @@ namespace MWGui // caused a sync / flush and would be expensive). // We're doing this so we can do some actual loading while the GPU is busy with the render. // This means the render is lagging a frame behind, but this is hardly noticable. -#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) mWindow->swapBuffers(); -#else - // In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged when using GLX. Not much we can do :/ - mWindow->swapBuffers(false); -#endif + mWindow->update(false); if (!hasCompositor) From 4905f1c8ab0291be80f5546177318cba266e1633 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 13 Oct 2013 21:54:36 +0200 Subject: [PATCH 48/62] make testing empty cells against an empty string yield true --- apps/opencs/model/filter/textnode.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index e335f7ea72..7d1a4845f6 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -49,6 +49,8 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, { string = data.toBool() ? "true" : "false"; } + else if (mText.empty() && !data.isValid()) + return true; else return false; From 9b0766b6789434e8134b1c0551972223e79e7890 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 14 Oct 2013 10:58:11 +0200 Subject: [PATCH 49/62] minor fix in ValueNode::toString --- apps/opencs/model/filter/valuenode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp index 7eeb6beab0..464fc8ec44 100644 --- a/apps/opencs/model/filter/valuenode.cpp +++ b/apps/opencs/model/filter/valuenode.cpp @@ -68,7 +68,7 @@ std::string CSMFilter::ValueNode::toString (bool numericColumns) const << CSMWorld::Columns::getName (static_cast (mColumnId)) << "\""; - stream << ", \""; + stream << ", "; if (mLower==mUpper && mLowerType!=Type_Infinite && mUpperType!=Type_Infinite) stream << mLower; From 679754b305070ac17a81250f7e6d59aa2d54e374 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 14 Oct 2013 11:06:59 +0200 Subject: [PATCH 50/62] corrected an error message --- apps/opencs/model/filter/valuenode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp index 464fc8ec44..66f76efcbb 100644 --- a/apps/opencs/model/filter/valuenode.cpp +++ b/apps/opencs/model/filter/valuenode.cpp @@ -17,7 +17,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row, const std::map::const_iterator iter = columns.find (mColumnId); if (iter==columns.end()) - throw std::logic_error ("invalid column in test value test"); + throw std::logic_error ("invalid column in value node test"); if (iter->second==-1) return true; From db7ea30483f126047c014dfdce807994c0ceb4e7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 14 Oct 2013 11:15:36 +0200 Subject: [PATCH 51/62] allow float values in cell for value tests --- apps/opencs/model/filter/valuenode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp index 66f76efcbb..fdcce00ab3 100644 --- a/apps/opencs/model/filter/valuenode.cpp +++ b/apps/opencs/model/filter/valuenode.cpp @@ -27,7 +27,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row, QVariant data = table.data (index); if (data.type()!=QVariant::Double && data.type()!=QVariant::Bool && data.type()!=QVariant::Int && - data.type()!=QVariant::UInt) + data.type()!=QVariant::UInt && data.type()!=static_cast (QMetaType::Float)) return false; double value = data.toDouble(); From ba4b8a37e2301f1ecb0633c361b3cb5c73bd1cdc Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Mon, 14 Oct 2013 11:15:23 +0200 Subject: [PATCH 52/62] Remember pressed message box button longer Remember which button was pressed until a new interactive message box is displayed or until the pressed button number is read. Before that, it was not possible to get the pressed button after the message box was hidden/destroyed. --- apps/openmw/mwgui/messagebox.cpp | 15 +++++++-------- apps/openmw/mwgui/messagebox.hpp | 1 + 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 45da1bf17e..48d7ec1717 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -14,6 +14,7 @@ namespace MWGui mMessageBoxSpeed = 0.1; mInterMessageBoxe = NULL; mStaticMessageBox = NULL; + mLastButtonPressed = -1; } void MessageBoxManager::onFrame (float frameDuration) @@ -62,6 +63,7 @@ namespace MWGui } if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { + mLastButtonPressed = mInterMessageBoxe->readPressedButton(); delete mInterMessageBoxe; mInterMessageBoxe = NULL; MWBase::Environment::get().getInputManager()->changeInputMode( @@ -107,6 +109,7 @@ namespace MWGui } mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons); + mLastButtonPressed = -1; return true; } @@ -154,11 +157,9 @@ namespace MWGui int MessageBoxManager::readPressedButton () { - if(mInterMessageBoxe != NULL) - { - return mInterMessageBoxe->readPressedButton(); - } - return -1; + int pressed = mLastButtonPressed; + mLastButtonPressed = -1; + return pressed; } @@ -421,9 +422,7 @@ namespace MWGui int InteractiveMessageBox::readPressedButton () { - int pressed = mButtonPressed; - mButtonPressed = -1; - return pressed; + return mButtonPressed; } } diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index 4ef645f5e6..63840cfe2c 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -56,6 +56,7 @@ namespace MWGui MessageBox* mStaticMessageBox; std::vector mTimers; float mMessageBoxSpeed; + int mLastButtonPressed; }; class MessageBox : public OEngine::GUI::Layout From 30ee3c5cf6e98982743de01cff0d1c8adbd57cb5 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Tue, 15 Oct 2013 15:23:42 -0400 Subject: [PATCH 53/62] Equipped torches and lights run out of fuel --- apps/openmw/mwclass/light.cpp | 47 ++++++++++++++++++++++++++++++ apps/openmw/mwclass/light.hpp | 8 +++++ apps/openmw/mwmechanics/actors.cpp | 32 ++++++++++++++++++++ apps/openmw/mwmechanics/actors.hpp | 2 ++ apps/openmw/mwworld/class.cpp | 10 +++++++ apps/openmw/mwworld/class.hpp | 8 +++++ 6 files changed, 107 insertions(+) diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 7eefc6167c..21d83d62ec 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -16,12 +16,27 @@ #include "../mwworld/inventorystore.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/physicssystem.hpp" +#include "../mwworld/customdata.hpp" #include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" +namespace +{ + struct CustomData : public MWWorld::CustomData + { + float mTime; + ///< Time remaining + + virtual MWWorld::CustomData *clone() const + { + return new CustomData (*this); + } + }; +} + namespace MWClass { void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -182,6 +197,24 @@ namespace MWClass return action; } + void Light::setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const + { + ensureCustomData(ptr); + + float &timeCharge = dynamic_cast (*ptr.getRefData().getCustomData()).mTime; + + // TODO time it in vanilla, see if 1 second is really one unit. + timeCharge = duration; + } + + float Light::getRemainingUsageTime (const MWWorld::Ptr& ptr) const + { + ensureCustomData(ptr); + + ESM::CellRef &ref = ptr.getCellRef(); + return dynamic_cast (*ptr.getRefData().getCustomData()).mTime; + } + MWWorld::Ptr Light::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const { @@ -191,6 +224,20 @@ namespace MWClass return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell); } + void Light::ensureCustomData (const MWWorld::Ptr& ptr) const + { + if (!ptr.getRefData().getCustomData()) + { + MWWorld::LiveCellRef *ref = ptr.get(); + + CustomData *data = new CustomData; + + data->mTime = ref->mBase->mData.mTime; + + ptr.getRefData().setCustomData(data); + } + } + bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const { return npcServices & ESM::NPC::Lights; diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 79d662763b..c15228a6a0 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -10,6 +10,8 @@ namespace MWClass virtual MWWorld::Ptr copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const; + void ensureCustomData (const MWWorld::Ptr& ptr) const; + public: virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; @@ -56,6 +58,12 @@ namespace MWClass const; ///< Generate action for using via inventory menu + virtual void setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const; + ///< Sets the remaining duration of the object. + + virtual float getRemainingUsageTime (const MWWorld::Ptr& ptr) const; + ///< Returns the remaining duration of the object. + virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual float getWeight (const MWWorld::Ptr& ptr) const; diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ca26e88ce1..fb632159c4 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -42,7 +42,13 @@ namespace MWMechanics void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) { if(!paused) + { updateDrowning(ptr, duration); + + // Only update the light of the player. + if(ptr.getRefData().getHandle()=="player") + updateEquippedLight(ptr, duration); + } } void Actors::adjustMagicEffects (const MWWorld::Ptr& creature) @@ -196,6 +202,32 @@ namespace MWMechanics stats.setTimeToStartDrowning(20); } + void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration) + { + //If holding a light... + MWWorld::InventoryStore &inventoryStore = MWWorld::Class::get(ptr).getInventoryStore(ptr); + MWWorld::ContainerStoreIterator heldIter = + inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + + if(heldIter.getType() == MWWorld::ContainerStore::Type_Light) + { + // ... then use some "fuel" from the timer + float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter); + + // If it's already -1, then it should be an infinite light. + // TODO see what happens for other negative values. + if(timeRemaining >= 0.0f) + { + timeRemaining -= duration; + + if(timeRemaining > 0.0f) + heldIter->getClass().setRemainingUsageTime(*heldIter, timeRemaining); + else + heldIter->getRefData().setCount(0); // remove it + } + } + } + Actors::Actors() : mDuration (0) {} void Actors::addActor (const MWWorld::Ptr& ptr) diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 69878a000e..a77e52ba30 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -44,6 +44,8 @@ namespace MWMechanics void updateDrowning (const MWWorld::Ptr& ptr, float duration); + void updateEquippedLight (const MWWorld::Ptr& ptr, float duration); + public: Actors(); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index c739ea831c..c73662bb19 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -132,6 +132,16 @@ namespace MWWorld throw std::runtime_error ("class does not support unlocking"); } + void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const + { + throw std::runtime_error ("class does not support time-based uses."); + } + + float Class::getRemainingUsageTime (const Ptr& ptr) const + { + throw std::runtime_error ("class does not support time-based uses."); + } + std::string Class::getScript (const Ptr& ptr) const { return ""; diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 28e37cbf3c..1b7b8518ab 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -156,6 +156,14 @@ namespace MWWorld virtual void unlock (const Ptr& ptr) const; ///< Unlock object (default implementation: throw an exception) + virtual void setRemainingUsageTime (const Ptr& ptr, float duration) const; + ///< Sets the remaining duration of the object, such as an equippable light + /// source. (default implementation: throw an exception) + + virtual float getRemainingUsageTime (const Ptr& ptr) const; + ///< Returns the remaining duration of the object, such as an equippable light + /// source. (default implementation: throw an exception) + virtual std::string getScript (const Ptr& ptr) const; ///< Return name of the script attached to ptr (default implementation: return an empty /// string). From 2643214ca6370a102ce69cb9788b9ef656006c50 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Tue, 15 Oct 2013 20:56:42 -0400 Subject: [PATCH 54/62] Lights extinguish underwater --- apps/openmw/mwclass/light.cpp | 6 ++--- apps/openmw/mwmechanics/actors.cpp | 42 ++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 21d83d62ec..4cf4ae37e1 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -201,10 +201,8 @@ namespace MWClass { ensureCustomData(ptr); - float &timeCharge = dynamic_cast (*ptr.getRefData().getCustomData()).mTime; - - // TODO time it in vanilla, see if 1 second is really one unit. - timeCharge = duration; + float &timeRemaining = dynamic_cast (*ptr.getRefData().getCustomData()).mTime; + timeRemaining = duration; } float Light::getRemainingUsageTime (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index fb632159c4..0adc97606c 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -44,10 +44,7 @@ namespace MWMechanics if(!paused) { updateDrowning(ptr, duration); - - // Only update the light of the player. - if(ptr.getRefData().getHandle()=="player") - updateEquippedLight(ptr, duration); + updateEquippedLight(ptr, duration); } } @@ -211,19 +208,36 @@ namespace MWMechanics if(heldIter.getType() == MWWorld::ContainerStore::Type_Light) { - // ... then use some "fuel" from the timer - float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter); + // Use time from the player's light + bool isPlayer = ptr.getRefData().getHandle()=="player"; + if(isPlayer) + { + float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter); + + // -1 is infinite light source. Other negative values are treated as 0. + if(timeRemaining != -1.0f) + { + timeRemaining -= duration; + + if(timeRemaining > 0.0f) + heldIter->getClass().setRemainingUsageTime(*heldIter, timeRemaining); + else + { + heldIter->getRefData().setCount(0); // remove it + return; + } + } + } - // If it's already -1, then it should be an infinite light. - // TODO see what happens for other negative values. - if(timeRemaining >= 0.0f) + // Both NPC and player lights extinguish in water. + if(MWBase::Environment::get().getWorld()->isSwimming(ptr)) { - timeRemaining -= duration; + heldIter->getRefData().setCount(0); // remove it - if(timeRemaining > 0.0f) - heldIter->getClass().setRemainingUsageTime(*heldIter, timeRemaining); - else - heldIter->getRefData().setCount(0); // remove it + // ...But, only the player makes a sound. + if(isPlayer) + MWBase::Environment::get().getSoundManager()->playSound("torch out", + 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoEnv); } } } From 8d8ba0257e17a34fb959c7e6bd420301540a7bb9 Mon Sep 17 00:00:00 2001 From: jeaye Date: Tue, 15 Oct 2013 22:17:50 -0700 Subject: [PATCH 55/62] Added common untracked files to .gitignore --- .gitignore | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.gitignore b/.gitignore index 9f2cba3bfd..4a3545f2c7 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,20 @@ CMakeLists.txt.user .project .settings/ .directory +*.install +*.desktop +*.cfg +*.cxx_parameters +*qrc_launcher.cxx +*qrc_resources.cxx +*__* +*ui_datafilespage.h +*ui_graphicspage.h +*ui_mainwindow.h +*ui_playpage.h +resources +esmtool +mwiniimport +omwlauncher +openmw +opencs From 5f4e2d2cf2da826c79acb2c07cce21a880564408 Mon Sep 17 00:00:00 2001 From: jeaye Date: Tue, 15 Oct 2013 22:29:51 -0700 Subject: [PATCH 56/62] Organize .gitignore to make it easier to add to --- .gitignore | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 4a3545f2c7..c460743e7a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,29 +1,43 @@ -build -*~ -Doxygen -prebuilt -apps/openmw/config.hpp -Docs/mainpage.hpp +## make CMakeFiles */CMakeFiles CMakeCache.txt -moc_*.cxx cmake_install.cmake -*.[ao] +CMakeLists.txt.user Makefile makefile -data +build +prebuilt + +## doxygen +Doxygen + +## ides/editors +*~ *.kdev4 -CMakeLists.txt.user *.swp *.swo *.kate-swp .cproject .project -.settings/ +.settings .directory -*.install -*.desktop + +## resources +data +resources + +## binaries +esmtool +mwiniimport +omwlauncher +openmw +opencs + +## generated objects +apps/openmw/config.hpp +Docs/mainpage.hpp +moc_*.cxx *.cfg *.cxx_parameters *qrc_launcher.cxx @@ -33,9 +47,7 @@ CMakeLists.txt.user *ui_graphicspage.h *ui_mainwindow.h *ui_playpage.h -resources -esmtool -mwiniimport -omwlauncher -openmw -opencs +*.install +*.desktop +*.[ao] +*.so From 8995cd8543ebdeb903b78afe1f6f1cb0c4df7b6b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 16 Oct 2013 20:35:39 +0200 Subject: [PATCH 57/62] reverted gitignore changes --- .gitignore | 51 +++++++++++---------------------------------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/.gitignore b/.gitignore index c460743e7a..9f2cba3bfd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,53 +1,24 @@ -## make +build +*~ +Doxygen +prebuilt +apps/openmw/config.hpp +Docs/mainpage.hpp CMakeFiles */CMakeFiles CMakeCache.txt +moc_*.cxx cmake_install.cmake -CMakeLists.txt.user +*.[ao] Makefile makefile -build -prebuilt - -## doxygen -Doxygen - -## ides/editors -*~ +data *.kdev4 +CMakeLists.txt.user *.swp *.swo *.kate-swp .cproject .project -.settings +.settings/ .directory - -## resources -data -resources - -## binaries -esmtool -mwiniimport -omwlauncher -openmw -opencs - -## generated objects -apps/openmw/config.hpp -Docs/mainpage.hpp -moc_*.cxx -*.cfg -*.cxx_parameters -*qrc_launcher.cxx -*qrc_resources.cxx -*__* -*ui_datafilespage.h -*ui_graphicspage.h -*ui_mainwindow.h -*ui_playpage.h -*.install -*.desktop -*.[ao] -*.so From e11da5c0a3aec68078dd967fc0582f7908311941 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Wed, 16 Oct 2013 15:13:36 -0400 Subject: [PATCH 58/62] Added a constructor to Light CustomData --- apps/openmw/mwclass/light.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 4cf4ae37e1..906ae8a1ce 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -30,6 +30,13 @@ namespace float mTime; ///< Time remaining + CustomData(MWWorld::Ptr ptr) + { + MWWorld::LiveCellRef *ref = ptr.get(); + mTime = ref->mBase->mData.mTime; + } + ///< Constructs this CustomData from the base values for Ptr. + virtual MWWorld::CustomData *clone() const { return new CustomData (*this); @@ -225,15 +232,7 @@ namespace MWClass void Light::ensureCustomData (const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) - { - MWWorld::LiveCellRef *ref = ptr.get(); - - CustomData *data = new CustomData; - - data->mTime = ref->mBase->mData.mTime; - - ptr.getRefData().setCustomData(data); - } + ptr.getRefData().setCustomData(new CustomData(ptr)); } bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const From 65818155d8bb34640942ede25c3d9128baf07b08 Mon Sep 17 00:00:00 2001 From: "Alex \"rainChu\" Haddad" Date: Wed, 16 Oct 2013 15:14:35 -0400 Subject: [PATCH 59/62] Fixed punctuation consistency --- apps/openmw/mwworld/class.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index c73662bb19..da98f99f1b 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -134,12 +134,12 @@ namespace MWWorld void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const { - throw std::runtime_error ("class does not support time-based uses."); + throw std::runtime_error ("class does not support time-based uses"); } float Class::getRemainingUsageTime (const Ptr& ptr) const { - throw std::runtime_error ("class does not support time-based uses."); + throw std::runtime_error ("class does not support time-based uses"); } std::string Class::getScript (const Ptr& ptr) const From 8c139783b74a29a4d6299ee9ed874dc3fe651c83 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 16 Oct 2013 21:33:11 +0200 Subject: [PATCH 60/62] silenced a warning --- apps/openmw/mwclass/light.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 906ae8a1ce..a593eb295a 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -216,7 +216,6 @@ namespace MWClass { ensureCustomData(ptr); - ESM::CellRef &ref = ptr.getCellRef(); return dynamic_cast (*ptr.getRefData().getCustomData()).mTime; } From 04735a67340604f8c517582c0d7b6cc390c36d57 Mon Sep 17 00:00:00 2001 From: jeaye Date: Tue, 15 Oct 2013 22:17:50 -0700 Subject: [PATCH 61/62] Extend .gitignore Organize .gitignore to make it easier to add to Ignore only binaries, not directories Removed some invalid ignores (.cfg, .desktop, etc) Better globbing --- .gitignore | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 9f2cba3bfd..f22f1bd49c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,53 @@ -build -*~ -Doxygen -prebuilt -apps/openmw/config.hpp -Docs/mainpage.hpp +## make CMakeFiles */CMakeFiles CMakeCache.txt -moc_*.cxx cmake_install.cmake -*.[ao] +CMakeLists.txt.user Makefile makefile -data +build +prebuilt + +## doxygen +Doxygen + +## ides/editors +*~ *.kdev4 -CMakeLists.txt.user *.swp *.swo *.kate-swp .cproject .project -.settings/ +.settings .directory + +## resources +data +resources +/*.cfg +/*.desktop +/*.install + +## binaries +/esmtool +/mwiniimport +/omwlauncher +/openmw +/opencs + +## generated objects +apps/openmw/config.hpp +Docs/mainpage.hpp +moc_*.cxx +*.cxx_parameters +*qrc_launcher.cxx +*qrc_resources.cxx +*__* +*ui_datafilespage.h +*ui_graphicspage.h +*ui_mainwindow.h +*ui_playpage.h +*.[ao] +*.so From 3a3f2a37c85302a9353effb7ca811fb98deb2ce8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 17 Oct 2013 12:39:26 +0200 Subject: [PATCH 62/62] Add cut, copy & paste of text --- apps/openmw/mwinput/inputmanagerimp.cpp | 35 +++++++++++++++++++++++++ files/mygui/openmw_console.layout | 1 + 2 files changed, 36 insertions(+) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 43f2bcc15f..4746260edf 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -468,6 +468,41 @@ namespace MWInput bool InputManager::keyPressed( const SDL_KeyboardEvent &arg ) { + // Cut, copy & paste + MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); + if (focus) + { + MyGUI::EditBox* edit = focus->castType(false); + if (edit && !edit->getEditReadOnly()) + { + if (arg.keysym.sym == SDLK_v && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL))) + { + char* text = SDL_GetClipboardText(); + + if (text) + { + edit->addText(MyGUI::UString(text)); + SDL_free(text); + } + } + if (arg.keysym.sym == SDLK_x && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL))) + { + std::string text = edit->getTextSelection(); + if (text.length()) + { + SDL_SetClipboardText(text.c_str()); + edit->deleteTextSelection(); + } + } + if (arg.keysym.sym == SDLK_c && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL))) + { + std::string text = edit->getTextSelection(); + if (text.length()) + SDL_SetClipboardText(text.c_str()); + } + } + } + mInputBinder->keyPressed (arg); if(arg.keysym.sym == SDLK_RETURN diff --git a/files/mygui/openmw_console.layout b/files/mygui/openmw_console.layout index bfda40c68b..7d24a283e1 100644 --- a/files/mygui/openmw_console.layout +++ b/files/mygui/openmw_console.layout @@ -9,6 +9,7 @@ +