diff --git a/CMakeLists.txt b/CMakeLists.txt index e4706ccd90..ca3fe0eeb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -363,12 +363,17 @@ if(DPKG_PROGRAM) endif(DPKG_PROGRAM) if(WIN32) - FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*") - INSTALL(FILES ${files} DESTINATION ".") + FILE(GLOB dll_files "${OpenMW_BINARY_DIR}/Release/*.dll") + INSTALL(FILES ${dll_files} DESTINATION ".") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES + "${OpenMW_BINARY_DIR}/plugins.cfg" "${OpenMW_SOURCE_DIR}/readme.txt" + "${OpenMW_BINARY_DIR}/launcher.qss" "${OpenMW_BINARY_DIR}/settings-default.cfg" + "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" + "${OpenMW_BINARY_DIR}/Release/omwlauncher.exe" + "${OpenMW_BINARY_DIR}/Release/openmw.exe" DESTINATION ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") @@ -394,7 +399,7 @@ if(WIN32) SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe") SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.ico") SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.ico") - # SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp") + SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp") SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe") if(EXISTS ${VCREDIST32}) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index c4b3776ed6..79ea262e68 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwinput add_openmw_dir (mwgui layouts text_input widgets race class birth review window_manager console dialogue dialogue_history window_base stats_window messagebox journalwindow charactercreation - map_window window_pinnable_base cursorreplace + map_window window_pinnable_base cursorreplace tooltips ) add_openmw_dir (mwdialogue @@ -44,7 +44,7 @@ add_openmw_dir (mwsound ) add_openmw_dir (mwworld - refdata world physicssystem scene environment globals class action nullaction actionteleport + refdata world physicssystem scene globals class action nullaction actionteleport containerstore actiontalk actiontake manualref player cellfunctors cells localscripts customdata weather inventorystore ptr ) @@ -58,6 +58,10 @@ add_openmw_dir (mwmechanics mechanicsmanager stat creaturestats magiceffects movement actors drawstate spells ) +add_openmw_dir (mwbase + environment + ) + # Main executable IF(OGRE_STATIC) IF(WIN32) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2d3c872dd7..539afe1c87 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -50,10 +50,12 @@ #include "mwmechanics/mechanicsmanager.hpp" +#include "mwbase/environment.hpp" + void OMW::Engine::executeLocalScripts() { - MWWorld::LocalScripts& localScripts = mEnvironment.mWorld->getLocalScripts(); + MWWorld::LocalScripts& localScripts = MWBase::Environment::get().getWorld()->getLocalScripts(); localScripts.startIteration(); @@ -61,58 +63,17 @@ void OMW::Engine::executeLocalScripts() { std::pair script = localScripts.getNext(); - MWScript::InterpreterContext interpreterContext (mEnvironment, + MWScript::InterpreterContext interpreterContext ( &script.second.getRefData().getLocals(), script.second); - mEnvironment.mScriptManager->run (script.first, interpreterContext); + MWBase::Environment::get().getScriptManager()->run (script.first, interpreterContext); - if (mEnvironment.mWorld->hasCellChanged()) + if (MWBase::Environment::get().getWorld()->hasCellChanged()) break; } localScripts.setIgnore (MWWorld::Ptr()); } -void OMW::Engine::updateFocusReport (float duration) -{ - - if ((mFocusTDiff += duration)>0.25) - { - mFocusTDiff = 0; - - std::string name; - - std::string handle = mEnvironment.mWorld->getFacedHandle(); - - if (!handle.empty()) - { - // the faced handle is not updated immediately, so on a cell change it might - // point to an object that doesn't exist anymore - // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case - try - { - MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); - - if (!ptr.isEmpty()){ - name = MWWorld::Class::get (ptr).getName (ptr); - - } - } - catch (std::runtime_error& e) - {} - } - - if (name!=mFocusName) - { - mFocusName = name; - - if (mFocusName.empty()) - std::cout << "Unfocus" << std::endl; - else - std::cout << "Focus: " << name << std::endl; - } - } -} - void OMW::Engine::setAnimationVerbose(bool animverbose){ if(animverbose){ NifOgre::NIFLoader::getSingletonPtr()->setOutputAnimFiles(true); @@ -124,27 +85,19 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) { try { - mEnvironment.mFrameDuration = evt.timeSinceLastFrame; + mEnvironment.setFrameDuration (evt.timeSinceLastFrame); // update input - mEnvironment.mInputManager->update(); + MWBase::Environment::get().getInputManager()->update(); // sound if (mUseSound) - mEnvironment.mSoundManager->update (evt.timeSinceLastFrame); - - // update GUI - Ogre::RenderWindow* window = mOgre->getWindow(); - mEnvironment.mWindowManager->wmUpdateFps(window->getLastFPS(), - window->getTriangleCount(), - window->getBatchCount()); - - mEnvironment.mWindowManager->onFrame(mEnvironment.mFrameDuration); + MWBase::Environment::get().getSoundManager()->update (evt.timeSinceLastFrame); // global scripts - mEnvironment.mGlobalScripts->run (mEnvironment); + MWBase::Environment::get().getScriptManager()->getGlobalScripts().run(); - bool changed = mEnvironment.mWorld->hasCellChanged(); + bool changed = MWBase::Environment::get().getWorld()->hasCellChanged(); // local scripts executeLocalScripts(); // This does not handle the case where a global script causes a cell @@ -152,28 +105,32 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) // frame. // passing of time - if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game) - mEnvironment.mWorld->advanceTime ( - mEnvironment.mFrameDuration*mEnvironment.mWorld->getTimeScaleFactor()/3600); + if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game) + MWBase::Environment::get().getWorld()->advanceTime ( + mEnvironment.getFrameDuration()*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600); if (changed) // keep change flag for another frame, if cell changed happend in local script - mEnvironment.mWorld->markCellAsUnchanged(); + MWBase::Environment::get().getWorld()->markCellAsUnchanged(); // update actors std::vector > movement; - mEnvironment.mMechanicsManager->update (movement, mEnvironment.mFrameDuration, - mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game); + MWBase::Environment::get().getMechanicsManager()->update (movement, mEnvironment.getFrameDuration(), + MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game); - if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game) - mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration); + if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game) + MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration()); // update world - mEnvironment.mWorld->update (evt.timeSinceLastFrame); + MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame); - // report focus object (for debugging) - if (mReportFocus) - updateFocusReport (mEnvironment.mFrameDuration); + // update GUI + Ogre::RenderWindow* window = mOgre->getWindow(); + MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), + window->getTriangleCount(), + window->getBatchCount()); + + MWBase::Environment::get().getWindowManager()->onFrame(evt.timeSinceLastFrame); } catch (const std::exception& e) { @@ -191,7 +148,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mNewGame (false) , mUseSound (true) , mCompileAll (false) - , mReportFocus (false) , mFocusTDiff (0) , mScriptContext (0) , mFSStrict (false) @@ -203,13 +159,13 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) OMW::Engine::~Engine() { - delete mEnvironment.mWorld; - delete mEnvironment.mSoundManager; - delete mEnvironment.mGlobalScripts; - delete mEnvironment.mMechanicsManager; - delete mEnvironment.mDialogueManager; - delete mEnvironment.mJournal; - delete mEnvironment.mScriptManager; + delete MWBase::Environment::get().getInputManager(); + delete MWBase::Environment::get().getSoundManager(); + delete MWBase::Environment::get().getMechanicsManager(); + delete MWBase::Environment::get().getDialogueManager(); + delete MWBase::Environment::get().getJournal(); + delete MWBase::Environment::get().getScriptManager(); + delete MWBase::Environment::get().getWorld(); delete mScriptContext; delete mOgre; } @@ -219,7 +175,7 @@ OMW::Engine::~Engine() void OMW::Engine::loadBSA() { const Files::MultiDirCollection& bsa = mFileCollections.getCollection (".bsa"); - + for (Files::MultiDirCollection::TIter iter(bsa.begin()); iter!=bsa.end(); ++iter) { std::cout << "Adding " << iter->second.string() << std::endl; @@ -303,17 +259,11 @@ void OMW::Engine::setNewGame(bool newGame) mNewGame = newGame; } -void OMW::Engine::setReportFocus (bool report) -{ - mReportFocus = report; -} - // Initialise and enter main loop. void OMW::Engine::go() { mFocusTDiff = 0; - assert (!mEnvironment.mWorld); assert (!mCellName.empty()); assert (!mMaster.empty()); assert (!mOgre); @@ -382,69 +332,66 @@ void OMW::Engine::go() MWGui::CursorReplace replacer; // Create the world - mEnvironment.mWorld = new MWWorld::World (*mOgre, mFileCollections, mMaster, - mResDir, mNewGame, mEnvironment, mEncoding, mFallbackMap); + mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster, + mResDir, mNewGame, mEncoding, mFallbackMap)); // Create window manager - this manages all the MW-specific GUI windows MWScript::registerExtensions (mExtensions); - mEnvironment.mWindowManager = new MWGui::WindowManager(mEnvironment, - mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/")); + mEnvironment.setWindowManager (new MWGui::WindowManager( + mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"))); // Create sound system - mEnvironment.mSoundManager = new MWSound::SoundManager(mUseSound, mEnvironment); + mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); // Create script system - mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full, - mEnvironment); + mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full); mScriptContext->setExtensions (&mExtensions); - mEnvironment.mScriptManager = new MWScript::ScriptManager (mEnvironment.mWorld->getStore(), - mVerboseScripts, *mScriptContext); - - mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(), - *mEnvironment.mScriptManager); + mEnvironment.setScriptManager (new MWScript::ScriptManager (MWBase::Environment::get().getWorld()->getStore(), + mVerboseScripts, *mScriptContext)); // Create game mechanics system - mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (mEnvironment); + mEnvironment.setMechanicsManager (new MWMechanics::MechanicsManager); // Create dialog system - mEnvironment.mJournal = new MWDialogue::Journal (mEnvironment); - mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment,mExtensions); + mEnvironment.setJournal (new MWDialogue::Journal); + mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions)); // load cell ESM::Position pos; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.pos[2] = 0; - if (const ESM::Cell *exterior = mEnvironment.mWorld->getExterior (mCellName)) + if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName)) { - mEnvironment.mWorld->indexToPosition (exterior->data.gridX, exterior->data.gridY, + MWBase::Environment::get().getWorld()->indexToPosition (exterior->data.gridX, exterior->data.gridY, pos.pos[0], pos.pos[1], true); - mEnvironment.mWorld->changeToExteriorCell (pos); + MWBase::Environment::get().getWorld()->changeToExteriorCell (pos); } else { pos.pos[0] = pos.pos[1] = 0; - mEnvironment.mWorld->changeToInteriorCell (mCellName, pos); + MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos); } // Sets up the input system - MWInput::MWInputManager input(*mOgre, mEnvironment.mWorld->getPlayer(), - *mEnvironment.mWindowManager, mDebug, *this); - mEnvironment.mInputManager = &input; + + mEnvironment.setInputManager (new MWInput::MWInputManager (*mOgre, + MWBase::Environment::get().getWorld()->getPlayer(), + *MWBase::Environment::get().getWindowManager(), mDebug, *this)); std::cout << "\nPress Q/ESC or close window to exit.\n"; mOgre->getRoot()->addFrameListener (this); // Play some good 'ol tunes - mEnvironment.mSoundManager->playPlaylist(std::string("Explore")); + MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); // scripts if (mCompileAll) { - std::pair result = mEnvironment.mScriptManager->compileAll(); + std::pair result = MWBase::Environment::get().getScriptManager()->compileAll(); if (result.first) std::cout @@ -465,10 +412,10 @@ void OMW::Engine::go() void OMW::Engine::activate() { - if (mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game) + if (MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game) return; - std::string handle = mEnvironment.mWorld->getFacedHandle(); + std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); if (handle.empty()) return; @@ -479,7 +426,7 @@ void OMW::Engine::activate() MWWorld::Ptr ptr; try { - ptr = mEnvironment.mWorld->getPtrViaHandle (handle); + ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle); if (ptr.isEmpty()) return; @@ -489,12 +436,10 @@ void OMW::Engine::activate() return; } - MWScript::InterpreterContext interpreterContext (mEnvironment, - &ptr.getRefData().getLocals(), ptr); + MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); boost::shared_ptr action = - MWWorld::Class::get (ptr).activate (ptr, mEnvironment.mWorld->getPlayer().getPlayer(), - mEnvironment); + MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); interpreterContext.activate (ptr, action); @@ -502,8 +447,8 @@ void OMW::Engine::activate() if (!script.empty()) { - mEnvironment.mWorld->getLocalScripts().setIgnore (ptr); - mEnvironment.mScriptManager->run (script, interpreterContext); + MWBase::Environment::get().getWorld()->getLocalScripts().setIgnore (ptr); + MWBase::Environment::get().getScriptManager()->run (script, interpreterContext); } if (!interpreterContext.hasActivationBeenHandled()) diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 6eae20cc0f..c834ee438d 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -10,7 +10,8 @@ #include #include -#include "mwworld/environment.hpp" +#include "mwbase/environment.hpp" + #include "mwworld/ptr.hpp" namespace Compiler @@ -73,12 +74,11 @@ namespace OMW bool mNewGame; bool mUseSound; bool mCompileAll; - bool mReportFocus; float mFocusTDiff; std::string mFocusName; std::map mFallbackMap; - MWWorld::Environment mEnvironment; + MWBase::Environment mEnvironment; Compiler::Extensions mExtensions; Compiler::Context *mScriptContext; @@ -100,8 +100,6 @@ namespace OMW void executeLocalScripts(); - void updateFocusReport (float duration); - virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); public: @@ -144,9 +142,6 @@ namespace OMW /// Start as a new game. void setNewGame(bool newGame); - /// Write name of focussed object to cout - void setReportFocus (bool report); - /// Initialise and enter main loop. void go(); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index df52faab14..68aa12fb36 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -155,9 +155,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1252 - Western European (Latin) alphabet, used by default") - ("report-focus", bpo::value()->implicit_value(true) - ->default_value(false), "write name of focussed object to cout") - ("fallback", bpo::value()->default_value(FallbackMap(), "") ->multitoken()->composing(), "fallback values") @@ -265,7 +262,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat engine.setSoundUsage(!variables["nosound"].as()); engine.setScriptsVerbosity(variables["script-verbose"].as()); engine.setCompileAll(variables["script-all"].as()); - engine.setReportFocus(variables["report-focus"].as()); engine.setAnimationVerbose(variables["anim-verbose"].as()); engine.setFallbackValues(variables["fallback"].as().mMap); diff --git a/apps/openmw/mwbase/environment.cpp b/apps/openmw/mwbase/environment.cpp new file mode 100644 index 0000000000..8e9a9cfce3 --- /dev/null +++ b/apps/openmw/mwbase/environment.cpp @@ -0,0 +1,123 @@ + +#include "environment.hpp" + +#include + +MWBase::Environment *MWBase::Environment::sThis = 0; + +MWBase::Environment::Environment() +: mWorld (0), mSoundManager (0), mScriptManager (0), mWindowManager (0), + mMechanicsManager (0), mDialogueManager (0), mJournal (0), mInputManager (0), mFrameDuration (0) +{ + assert (!sThis); + sThis = this; +} + +MWBase::Environment::~Environment() +{ + sThis = 0; +} + +void MWBase::Environment::setWorld (MWWorld::World *world) +{ + mWorld = world; +} + +void MWBase::Environment::setSoundManager (MWSound::SoundManager *soundManager) +{ + mSoundManager = soundManager; +} + +void MWBase::Environment::setScriptManager (MWScript::ScriptManager *scriptManager) +{ + mScriptManager = scriptManager; +} + +void MWBase::Environment::setWindowManager (MWGui::WindowManager *windowManager) +{ + mWindowManager = windowManager; +} + +void MWBase::Environment::setMechanicsManager (MWMechanics::MechanicsManager *mechanicsManager) +{ + mMechanicsManager = mechanicsManager; +} + +void MWBase::Environment::setDialogueManager (MWDialogue::DialogueManager *dialogueManager) +{ + mDialogueManager = dialogueManager; +} + +void MWBase::Environment::setJournal (MWDialogue::Journal *journal) +{ + mJournal = journal; +} + +void MWBase::Environment::setInputManager (MWInput::MWInputManager *inputManager) +{ + mInputManager = inputManager; +} + +void MWBase::Environment::setFrameDuration (float duration) +{ + mFrameDuration = duration; +} + +MWWorld::World *MWBase::Environment::getWorld() const +{ + assert (mWorld); + return mWorld; +} + +MWSound::SoundManager *MWBase::Environment::getSoundManager() const +{ + assert (mSoundManager); + return mSoundManager; +} + +MWScript::ScriptManager *MWBase::Environment::getScriptManager() const +{ + assert (mScriptManager); + return mScriptManager; +} + +MWGui::WindowManager *MWBase::Environment::getWindowManager() const +{ + assert (mWindowManager); + return mWindowManager; +} + +MWMechanics::MechanicsManager *MWBase::Environment::getMechanicsManager() const +{ + assert (mMechanicsManager); + return mMechanicsManager; +} + +MWDialogue::DialogueManager *MWBase::Environment::getDialogueManager() const +{ + assert (mDialogueManager); + return mDialogueManager; +} + +MWDialogue::Journal *MWBase::Environment::getJournal() const +{ + assert (mJournal); + return mJournal; +} + +MWInput::MWInputManager *MWBase::Environment::getInputManager() const +{ + assert (mInputManager); + return mInputManager; +} + +float MWBase::Environment::getFrameDuration() const +{ + return mFrameDuration; +} + +const MWBase::Environment& MWBase::Environment::get() +{ + assert (sThis); + return *sThis; +} diff --git a/apps/openmw/mwbase/environment.hpp b/apps/openmw/mwbase/environment.hpp new file mode 100644 index 0000000000..a010e7faa0 --- /dev/null +++ b/apps/openmw/mwbase/environment.hpp @@ -0,0 +1,116 @@ +#ifndef GAME_BASE_INVIRONMENT_H +#define GAME_BASE_INVIRONMENT_H + +namespace MWSound +{ + class SoundManager; +} + +namespace MWScript +{ + class ScriptManager; +} + +namespace MWGui +{ + class WindowManager; +} + +namespace MWMechanics +{ + class MechanicsManager; +} + +namespace MWDialogue +{ + class DialogueManager; + class Journal; +} + +namespace MWInput +{ + struct MWInputManager; +} + +namespace MWWorld +{ + class World; +} + +namespace MWBase +{ + /// \brief Central hub for mw-subsystems + /// + /// This class allows each mw-subsystem to access any others subsystem's top-level manager class. + /// + /// \attention Environment does not take ownership of the manager class instances it is handed over in + /// the set* functions. + class Environment + { + static Environment *sThis; + + MWWorld::World *mWorld; + MWSound::SoundManager *mSoundManager; + MWScript::ScriptManager *mScriptManager; + MWGui::WindowManager *mWindowManager; + MWMechanics::MechanicsManager *mMechanicsManager; + MWDialogue::DialogueManager *mDialogueManager; + MWDialogue::Journal *mJournal; + MWInput::MWInputManager *mInputManager; + float mFrameDuration; + + Environment (const Environment&); + ///< not implemented + + Environment& operator= (const Environment&); + ///< not implemented + + public: + + Environment(); + + ~Environment(); + + void setWorld (MWWorld::World *world); + + void setSoundManager (MWSound::SoundManager *soundManager); + + void setScriptManager (MWScript::ScriptManager *scriptManager); + + void setWindowManager (MWGui::WindowManager *windowManager); + + void setMechanicsManager (MWMechanics::MechanicsManager *mechanicsManager); + + void setDialogueManager (MWDialogue::DialogueManager *dialogueManager); + + void setJournal (MWDialogue::Journal *journal); + + void setInputManager (MWInput::MWInputManager *inputManager); + + void setFrameDuration (float duration); + ///< Set length of current frame in seconds. + + MWWorld::World *getWorld() const; + + MWSound::SoundManager *getSoundManager() const; + + MWScript::ScriptManager *getScriptManager() const; + + MWGui::WindowManager *getWindowManager() const; + + MWMechanics::MechanicsManager *getMechanicsManager() const; + + MWDialogue::DialogueManager *getDialogueManager() const; + + MWDialogue::Journal *getJournal() const; + + MWInput::MWInputManager *getInputManager() const; + + float getFrameDuration() const; + + static const Environment& get(); + ///< Return instance of this class. + }; +} + +#endif diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index 6749a2bfd1..6faaacf319 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -1,13 +1,14 @@ #include "activator.hpp" -#include "../mwrender/objects.hpp" #include #include #include "../mwworld/ptr.hpp" - +#include "../mwrender/objects.hpp" +#include "../mwbase/environment.hpp" +#include "../mwgui/window_manager.hpp" namespace MWClass { @@ -18,7 +19,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); @@ -27,7 +28,7 @@ namespace MWClass } } - void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -63,4 +64,28 @@ namespace MWClass registerClass (typeid (ESM::Activator).name(), instance); } + + bool Activator::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + + std::string text; + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/activator.hpp b/apps/openmw/mwclass/activator.hpp index 08be8a5ff1..223dd0a36b 100644 --- a/apps/openmw/mwclass/activator.hpp +++ b/apps/openmw/mwclass/activator.hpp @@ -12,12 +12,18 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index 90db40b5ae..215183dca7 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -5,12 +5,17 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" #include "../mwrender/objects.hpp" +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" + #include "../mwsound/soundmanager.hpp" namespace MWClass @@ -31,7 +36,7 @@ namespace MWClass } } - void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -54,9 +59,9 @@ namespace MWClass } boost::shared_ptr Apparatus::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -94,4 +99,37 @@ namespace MWClass { return std::string("Item Apparatus Down"); } + + bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Apparatus::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + text += "\n" + store.gameSettings.search("sQuality")->str + ": " + MWGui::ToolTips::toString(ref->base->data.quality); + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index 861610f6cc..e99ea1c1d3 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -12,14 +12,14 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation virtual std::string getScript (const MWWorld::Ptr& ptr) const; @@ -28,6 +28,12 @@ namespace MWClass virtual int getValue (const MWWorld::Ptr& ptr) const; ///< Return trade value of the object. Throws an exception, if the object can't be traded. + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 8e1f81136b..fb34e4c883 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -9,13 +9,15 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" - #include "../mwworld/inventorystore.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" +#include "../mwbase/environment.hpp" + #include "../mwrender/objects.hpp" +#include "../mwgui/window_manager.hpp" + #include "../mwsound/soundmanager.hpp" namespace MWClass @@ -36,7 +38,7 @@ namespace MWClass } } - void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -58,9 +60,9 @@ namespace MWClass } boost::shared_ptr Armor::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -121,7 +123,7 @@ namespace MWClass return std::make_pair (slots, false); } - int Armor::getEquipmentSkill (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + int Armor::getEquipmentSkill (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -138,8 +140,7 @@ namespace MWClass case ESM::Armor::Boots: typeGmst = "iBootsWeight"; break; case ESM::Armor::LGauntlet: case ESM::Armor::RGauntlet: typeGmst = "iGauntletWeight"; break; -/// \todo how to determine if shield light, medium or heavy? -// case ESM::Armor::Shield: + case ESM::Armor::Shield: typeGmst = "iShieldWeight"; break; case ESM::Armor::LBracer: case ESM::Armor::RBracer: typeGmst = "iGauntletWeight"; break; } @@ -147,13 +148,13 @@ namespace MWClass if (typeGmst.empty()) return -1; - float iWeight = environment.mWorld->getStore().gameSettings.find (typeGmst)->i; + float iWeight = MWBase::Environment::get().getWorld()->getStore().gameSettings.find (typeGmst)->i; - if (iWeight * environment.mWorld->getStore().gameSettings.find ("fLightMaxMod")->f>= + if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fLightMaxMod")->f>= ref->base->data.weight) return ESM::Skill::LightArmor; - if (iWeight * environment.mWorld->getStore().gameSettings.find ("fMedMaxMod")->f>= + if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMedMaxMod")->f>= ref->base->data.weight) return ESM::Skill::MediumArmor; @@ -175,9 +176,9 @@ namespace MWClass registerClass (typeid (ESM::Armor).name(), instance); } - std::string Armor::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Armor::getUpSoundId (const MWWorld::Ptr& ptr) const { - int es = getEquipmentSkill(ptr, environment); + int es = getEquipmentSkill(ptr); if (es == ESM::Skill::LightArmor) return std::string("Item Armor Light Up"); else if (es == ESM::Skill::MediumArmor) @@ -186,9 +187,9 @@ namespace MWClass return std::string("Item Armor Heavy Up"); } - std::string Armor::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Armor::getDownSoundId (const MWWorld::Ptr& ptr) const { - int es = getEquipmentSkill(ptr, environment); + int es = getEquipmentSkill(ptr); if (es == ESM::Skill::LightArmor) return std::string("Item Armor Light Down"); else if (es == ESM::Skill::MediumArmor) @@ -196,4 +197,55 @@ namespace MWClass else return std::string("Item Armor Heavy Down"); } + + bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Armor::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + std::string text; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + // get armor type string (light/medium/heavy) + int armorType = getEquipmentSkill(ptr); + std::string typeText; + if (armorType == ESM::Skill::LightArmor) + typeText = store.gameSettings.search("sLight")->str; + else if (armorType == ESM::Skill::MediumArmor) + typeText = store.gameSettings.search("sMedium")->str; + else + typeText = store.gameSettings.search("sHeavy")->str; + + text += "\n" + store.gameSettings.search("sArmorRating")->str + ": " + MWGui::ToolTips::toString(ref->base->data.armor); + + /// \todo store the current armor health somewhere + text += "\n" + store.gameSettings.search("sCondition")->str + ": " + MWGui::ToolTips::toString(ref->base->data.health); + + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight) + " (" + typeText + ")"; + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.enchant = ref->base->enchant; + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index de5ca39835..c757587e5e 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -12,14 +12,14 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const; @@ -35,20 +35,25 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getEquipmentSkill (const MWWorld::Ptr& ptr, - const MWWorld::Environment& environment) const; + virtual int getEquipmentSkill (const MWWorld::Ptr& ptr) const; /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual int getValue (const MWWorld::Ptr& ptr) const; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 9069d94765..ab659b4805 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -5,12 +5,16 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" #include "../mwrender/objects.hpp" +#include "../mwgui/window_manager.hpp" + #include "../mwsound/soundmanager.hpp" namespace MWClass @@ -31,7 +35,7 @@ namespace MWClass } } - void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -54,11 +58,11 @@ namespace MWClass } boost::shared_ptr Book::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { // TODO implement reading - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -87,13 +91,49 @@ namespace MWClass registerClass (typeid (ESM::Book).name(), instance); } - std::string Book::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Book::getUpSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Book Up"); } - std::string Book::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Book::getDownSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Book Down"); } + + bool Book::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Book::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.enchant = ref->base->enchant; + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index 4738187cd6..e85fbfb7f9 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -12,28 +12,34 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual int getValue (const MWWorld::Ptr& ptr) const; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 672a2b60a0..620b664cc4 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -5,10 +5,15 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/world.hpp" + +#include "../mwgui/tooltips.hpp" +#include "../mwgui/window_manager.hpp" #include "../mwrender/objects.hpp" @@ -32,7 +37,7 @@ namespace MWClass } } - void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -55,9 +60,9 @@ namespace MWClass } boost::shared_ptr Clothing::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -111,8 +116,7 @@ namespace MWClass return std::make_pair (slots, false); } - int Clothing::getEquipmentSkill (const MWWorld::Ptr& ptr, - const MWWorld::Environment& environment) const + int Clothing::getEquipmentSkill (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -138,7 +142,7 @@ namespace MWClass registerClass (typeid (ESM::Clothing).name(), instance); } - std::string Clothing::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Clothing::getUpSoundId (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -150,7 +154,7 @@ namespace MWClass return std::string("Item Clothes Up"); } - std::string Clothing::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Clothing::getDownSoundId (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -161,4 +165,40 @@ namespace MWClass } return std::string("Item Clothes Down"); } + + bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Clothing::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.enchant = ref->base->enchant; + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 97e09012d5..afb1849995 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -12,14 +12,14 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation virtual std::string getScript (const MWWorld::Ptr& ptr) const; @@ -29,20 +29,25 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getEquipmentSkill (const MWWorld::Ptr& ptr, - const MWWorld::Environment& environment) const; + virtual int getEquipmentSkill (const MWWorld::Ptr& ptr) const; /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual int getValue (const MWWorld::Ptr& ptr) const; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 29b3331ba9..a9def96aa6 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -5,11 +5,16 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/nullaction.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/customdata.hpp" -#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" + +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" @@ -61,7 +66,7 @@ namespace MWClass } } - void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -76,7 +81,7 @@ namespace MWClass } boost::shared_ptr Container::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { const std::string lockedSound = "LockedChest"; const std::string trapActivationSound = "Disarm Trap Fail"; @@ -85,7 +90,7 @@ namespace MWClass { // TODO check for key std::cout << "Locked container" << std::endl; - environment.mSoundManager->playSound3D (ptr, lockedSound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, lockedSound, 1.0, 1.0); return boost::shared_ptr (new MWWorld::NullAction); } else @@ -100,7 +105,7 @@ namespace MWClass { // Trap activation goes here std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl; - environment.mSoundManager->playSound3D (ptr, trapActivationSound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, trapActivationSound, 1.0, 1.0); ptr.getCellRef().trap = ""; return boost::shared_ptr (new MWWorld::NullAction); } @@ -137,4 +142,38 @@ namespace MWClass registerClass (typeid (ESM::Container).name(), instance); } + + bool Container::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + if (ref->ref.lockLevel > 0) + text += "\n" + store.gameSettings.search("sLockLevel")->str + ": " + MWGui::ToolTips::toString(ref->ref.lockLevel); + if (ref->ref.trap != "") + text += "\n" + store.gameSettings.search("sTrapped")->str; + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index 387714176b..3b1c8de09a 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -14,16 +14,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const; ///< Return container store diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 7270fd22b9..cf00f361bc 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -6,12 +6,15 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/mechanicsmanager.hpp" +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/customdata.hpp" #include "../mwworld/containerstore.hpp" +#include "../mwgui/window_manager.hpp" + namespace { struct CustomData : public MWWorld::CustomData @@ -74,7 +77,7 @@ namespace MWClass actors.insertCreature(ptr); } - void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -87,14 +90,14 @@ namespace MWClass } } - void Creature::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const + void Creature::enable (const MWWorld::Ptr& ptr) const { - environment.mMechanicsManager->addActor (ptr); + MWBase::Environment::get().getMechanicsManager()->addActor (ptr); } - void Creature::disable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const + void Creature::disable (const MWWorld::Ptr& ptr) const { - environment.mMechanicsManager->removeActor (ptr); + MWBase::Environment::get().getMechanicsManager()->removeActor (ptr); } std::string Creature::getName (const MWWorld::Ptr& ptr) const @@ -113,7 +116,7 @@ namespace MWClass } boost::shared_ptr Creature::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { return boost::shared_ptr (new MWWorld::ActionTalk (ptr)); } @@ -140,4 +143,27 @@ namespace MWClass registerClass (typeid (ESM::Creature).name(), instance); } + + bool Creature::hasToolTip (const MWWorld::Ptr& ptr) const + { + /// \todo We don't want tooltips for Creatures in combat mode. + + return true; + } + + MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + + std::string text; + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 8eb45e8381..4a1a8285fd 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -20,23 +20,29 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; - virtual void enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const; + virtual void enable (const MWWorld::Ptr& ptr) const; ///< Enable reference; only does the non-rendering part - virtual void disable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const; + virtual void disable (const MWWorld::Ptr& ptr) const; ///< Enable reference; only does the non-rendering part virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const; ///< Return creature stats virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation virtual MWWorld::ContainerStore& getContainerStore ( diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 9d6c6a78dc..7041de1c68 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -5,13 +5,17 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/player.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/nullaction.hpp" #include "../mwworld/actionteleport.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" + #include "../mwrender/objects.hpp" #include "../mwsound/soundmanager.hpp" @@ -34,7 +38,7 @@ namespace MWClass } } - void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -58,7 +62,7 @@ namespace MWClass } boost::shared_ptr Door::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -73,7 +77,7 @@ namespace MWClass // TODO check for key // TODO report failure to player (message, sound?). Look up behaviour of original MW. std::cout << "Locked!" << std::endl; - environment.mSoundManager->playSound3D (ptr, lockedSound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, lockedSound, 1.0, 1.0); return boost::shared_ptr (new MWWorld::NullAction); } @@ -81,7 +85,7 @@ namespace MWClass { // Trap activation std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl; - environment.mSoundManager->playSound3D(ptr, trapActivationSound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound3D(ptr, trapActivationSound, 1.0, 1.0); ptr.getCellRef().trap = ""; return boost::shared_ptr (new MWWorld::NullAction); } @@ -89,11 +93,11 @@ namespace MWClass if (ref->ref.teleport) { // teleport door - if (environment.mWorld->getPlayer().getPlayer()==actor) + if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor) { // the player is using the door // The reason this is not 3D is that it would get interrupted when you teleport - environment.mSoundManager->playSound(openSound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound(openSound, 1.0, 1.0); return boost::shared_ptr ( new MWWorld::ActionTeleportPlayer (ref->ref.destCell, ref->ref.doorDest)); } @@ -110,7 +114,7 @@ namespace MWClass // TODO return action for rotating the door // This is a little pointless, but helps with testing - environment.mSoundManager->playSound3D (ptr, openSound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, openSound, 1.0, 1.0); return boost::shared_ptr (new MWWorld::NullAction); } } @@ -142,4 +146,63 @@ namespace MWClass registerClass (typeid (ESM::Door).name(), instance); } + + bool Door::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + + std::string text; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + if (ref->ref.teleport) + { + std::string dest; + if (ref->ref.destCell != "") + { + // door leads to an interior, use interior name as tooltip + dest = ref->ref.destCell; + } + else + { + // door leads to exterior, use cell name (if any), otherwise translated region name + int x,y; + MWBase::Environment::get().getWorld()->positionToIndex (ref->ref.doorDest.pos[0], ref->ref.doorDest.pos[1], x, y); + const ESM::Cell* cell = store.cells.findExt(x,y); + if (cell->name != "") + dest = cell->name; + else + { + const ESM::Region* region = store.regions.search(cell->region); + dest = region->name; + } + } + text += "\n" + store.gameSettings.search("sTo")->str; + text += "\n"+dest; + } + + if (ref->ref.lockLevel > 0) + text += "\n" + store.gameSettings.search("sLockLevel")->str + ": " + MWGui::ToolTips::toString(ref->ref.lockLevel); + if (ref->ref.trap != "") + text += "\n" + store.gameSettings.search("sTrapped")->str; + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index aecb4224cc..63d1c1ab8b 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -12,16 +12,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const; ///< Lock object diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 9707e79a8f..068ae0cde2 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -5,9 +5,14 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" + +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" @@ -31,7 +36,7 @@ namespace MWClass } } - void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -52,9 +57,9 @@ namespace MWClass } boost::shared_ptr Ingredient::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -83,13 +88,47 @@ namespace MWClass registerClass (typeid (ESM::Ingredient).name(), instance); } - std::string Ingredient::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Ingredient::getUpSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Ingredient Up"); } - std::string Ingredient::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Ingredient::getDownSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Ingredient Down"); } + + bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Ingredient::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index 2d77176727..36756b6c33 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -12,16 +12,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr @@ -30,10 +36,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index f67dd4cf05..0c6892d247 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -5,11 +5,16 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" #include "../mwworld/nullaction.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/world.hpp" + +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwsound/soundmanager.hpp" @@ -39,7 +44,7 @@ namespace MWClass objects.insertLight (ptr, r, g, b, radius); } - void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -52,14 +57,14 @@ namespace MWClass } } - void Light::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const + void Light::enable (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); if (!ref->base->sound.empty()) { - environment.mSoundManager->playSound3D (ptr, ref->base->sound, 1.0, 1.0, MWSound::Play_Loop); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, ref->base->sound, 1.0, 1.0, MWSound::Play_Loop); } } @@ -75,7 +80,7 @@ namespace MWClass } boost::shared_ptr Light::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -83,7 +88,7 @@ namespace MWClass if (!(ref->base->data.flags & ESM::Light::Carry)) return boost::shared_ptr (new MWWorld::NullAction); - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -125,13 +130,47 @@ namespace MWClass registerClass (typeid (ESM::Light).name(), instance); } - std::string Light::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Light::getUpSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Misc Up"); } - std::string Light::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Light::getDownSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Misc Down"); } + + bool Light::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index bde252c289..7149a41a9c 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -12,9 +12,9 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; - virtual void enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const; + virtual void enable (const MWWorld::Ptr& ptr) const; ///< Enable reference; only does the non-rendering part /// \attention This is not the same as the script instruction with the same name. References /// should only be enabled while in an active cell. @@ -23,8 +23,14 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation virtual std::string getScript (const MWWorld::Ptr& ptr) const; @@ -39,10 +45,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 76bc3948f6..bd5849f669 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -5,10 +5,14 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/world.hpp" +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" @@ -32,7 +36,7 @@ namespace MWClass } } - void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -56,9 +60,9 @@ namespace MWClass } boost::shared_ptr Lockpick::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -96,13 +100,51 @@ namespace MWClass registerClass (typeid (ESM::Tool).name(), instance); } - std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Lockpick Up"); } - std::string Lockpick::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Lockpick::getDownSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Lockpick Down"); } + + bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + + /// \todo store remaining uses somewhere + + text += "\n" + store.gameSettings.search("sUses")->str + ": " + MWGui::ToolTips::toString(ref->base->data.uses); + text += "\n" + store.gameSettings.search("sQuality")->str + ": " + MWGui::ToolTips::toString(ref->base->data.quality); + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index 1b56234af1..0eaaa5af9b 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -12,16 +12,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr @@ -34,10 +40,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 84099caaaf..facee1bbbe 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -5,14 +5,21 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" + +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" #include "../mwsound/soundmanager.hpp" +#include + namespace MWClass { void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -31,7 +38,7 @@ namespace MWClass } } - void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -54,9 +61,9 @@ namespace MWClass } boost::shared_ptr Miscellaneous::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -85,27 +92,72 @@ namespace MWClass registerClass (typeid (ESM::Miscellaneous).name(), instance); } - std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); - if (ref->base->name =="Gold") + if (ref->base->name == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str) { return std::string("Item Gold Up"); } return std::string("Item Misc Up"); } - std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); - if (ref->base->name =="Gold") + if (ref->base->name == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str) { return std::string("Item Gold Down"); } return std::string("Item Misc Down"); } + + bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Miscellaneous::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + if (ref->ref.soul != "") + { + const ESM::Creature *creature = store.creatures.search(ref->ref.soul); + info.caption += " (" + creature->name + ")"; + } + + std::string text; + + if (ref->base->name == store.gameSettings.search("sGold")->str) + info.caption += " (" + boost::lexical_cast(ref->base->data.value) + ")"; + else + { + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + } + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index fc002280cf..fbe721cf3d 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -12,16 +12,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr @@ -30,10 +36,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index f6a8d0dbee..444fe9965f 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -14,11 +14,14 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/customdata.hpp" +#include "../mwgui/window_manager.hpp" + +#include "../mwbase/environment.hpp" + namespace { const Ogre::Radian kOgrePi (Ogre::Math::PI); @@ -105,13 +108,13 @@ namespace MWClass void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { - - + + renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr)); - + } - void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { @@ -133,14 +136,14 @@ namespace MWClass } - void Npc::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const + void Npc::enable (const MWWorld::Ptr& ptr) const { - environment.mMechanicsManager->addActor (ptr); + MWBase::Environment::get().getMechanicsManager()->addActor (ptr); } - void Npc::disable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const + void Npc::disable (const MWWorld::Ptr& ptr) const { - environment.mMechanicsManager->removeActor (ptr); + MWBase::Environment::get().getMechanicsManager()->removeActor (ptr); } std::string Npc::getName (const MWWorld::Ptr& ptr) const @@ -166,7 +169,7 @@ namespace MWClass } boost::shared_ptr Npc::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { return boost::shared_ptr (new MWWorld::ActionTalk (ptr)); } @@ -297,7 +300,29 @@ namespace MWClass void Npc::registerSelf() { boost::shared_ptr instance (new Npc); - std::cout << "class npc:" << typeid (ESM::NPC).name(); registerClass (typeid (ESM::NPC).name(), instance); } + + bool Npc::hasToolTip (const MWWorld::Ptr& ptr) const + { + /// \todo We don't want tooltips for NPCs in combat mode. + + return true; + } + + MWGui::ToolTipInfo Npc::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + + std::string text; + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index f210eda5f0..38b0ba03f0 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -17,12 +17,12 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; - virtual void enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const; + virtual void enable (const MWWorld::Ptr& ptr) const; ///< Enable reference; only does the non-rendering part - virtual void disable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const; + virtual void disable (const MWWorld::Ptr& ptr) const; ///< Enable reference; only does the non-rendering part virtual std::string getName (const MWWorld::Ptr& ptr) const; @@ -38,11 +38,17 @@ namespace MWClass virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const; ///< Return container store + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const; ///< Return inventory store virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation virtual std::string getScript (const MWWorld::Ptr& ptr) const; diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index 642211df3c..07e7663b38 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -5,9 +5,14 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" + +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" @@ -31,7 +36,7 @@ namespace MWClass } } - void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -54,9 +59,9 @@ namespace MWClass } boost::shared_ptr Potion::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -85,13 +90,49 @@ namespace MWClass registerClass (typeid (ESM::Potion).name(), instance); } - std::string Potion::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Potion::getUpSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Potion Up"); } - std::string Potion::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Potion::getDownSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Potion Down"); } + + bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Potion::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + info.effects = &ref->base->effects; + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index 7d30179376..8c2357fb2e 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -12,16 +12,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr @@ -30,10 +36,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 923c29ee69..02dc1115d2 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -5,10 +5,14 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/world.hpp" +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" @@ -32,7 +36,7 @@ namespace MWClass } } - void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -55,9 +59,9 @@ namespace MWClass return ref->base->name; } boost::shared_ptr Probe::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -95,13 +99,51 @@ namespace MWClass registerClass (typeid (ESM::Probe).name(), instance); } - std::string Probe::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Probe::getUpSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Probe Up"); } - std::string Probe::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Probe::getDownSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Probe Down"); } + + bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Probe::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + + /// \todo store remaining uses somewhere + + text += "\n" + store.gameSettings.search("sUses")->str + ": " + MWGui::ToolTips::toString(ref->base->data.uses); + text += "\n" + store.gameSettings.search("sQuality")->str + ": " + MWGui::ToolTips::toString(ref->base->data.quality); + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index 232b523645..f8c13fa1ea 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -12,16 +12,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr @@ -34,10 +40,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index d6433f5df5..0eb1f0cf2a 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -5,9 +5,13 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" @@ -31,7 +35,7 @@ namespace MWClass } } - void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -54,9 +58,9 @@ namespace MWClass } boost::shared_ptr Repair::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -85,13 +89,50 @@ namespace MWClass registerClass (typeid (ESM::Repair).name(), instance); } - std::string Repair::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Repair::getUpSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Repair Up"); } - std::string Repair::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Repair::getDownSoundId (const MWWorld::Ptr& ptr) const { return std::string("Item Repair Down"); } + + bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + std::string text; + + /// \todo store remaining uses somewhere + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + text += "\n" + store.gameSettings.search("sUses")->str + ": " + MWGui::ToolTips::toString(ref->base->data.uses); + text += "\n" + store.gameSettings.search("sQuality")->str + ": " + MWGui::ToolTips::toString(ref->base->data.quality); + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 0a9d9c2535..1d9ebb8bfb 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -12,16 +12,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr @@ -30,10 +36,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index 48750dd019..4a4136816e 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -25,7 +25,7 @@ namespace MWClass } } - void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/static.hpp b/apps/openmw/mwclass/static.hpp index a4b1d8c547..cd1626c197 100644 --- a/apps/openmw/mwclass/static.hpp +++ b/apps/openmw/mwclass/static.hpp @@ -12,7 +12,7 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 7790e6a80b..fcfaebcb7a 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -5,10 +5,15 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/world.hpp" + +#include "../mwgui/window_manager.hpp" +#include "../mwgui/tooltips.hpp" #include "../mwrender/objects.hpp" @@ -32,7 +37,7 @@ namespace MWClass } } - void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -55,9 +60,9 @@ namespace MWClass } boost::shared_ptr Weapon::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + const MWWorld::Ptr& actor) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -108,8 +113,7 @@ namespace MWClass return std::make_pair (slots, stack); } - int Weapon::getEquipmentSkill (const MWWorld::Ptr& ptr, - const MWWorld::Environment& environment) const + int Weapon::getEquipmentSkill (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -154,7 +158,7 @@ namespace MWClass registerClass (typeid (ESM::Weapon).name(), instance); } - std::string Weapon::getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Weapon::getUpSoundId (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -200,7 +204,7 @@ namespace MWClass return std::string("Item Misc Up"); } - std::string Weapon::getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const + std::string Weapon::getDownSoundId (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = ptr.get(); @@ -245,4 +249,94 @@ namespace MWClass return std::string("Item Misc Down"); } + + bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return (ref->base->name != ""); + } + + MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + MWGui::ToolTipInfo info; + info.caption = ref->base->name; + info.icon = ref->base->icon; + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + std::string text; + + // weapon type & damage. arrows / bolts don't have his info. + if (ref->base->data.type < 12) + { + text += "\n" + store.gameSettings.search("sType")->str + " "; + + std::map > mapping; + mapping[ESM::Weapon::ShortBladeOneHand] = std::make_pair("sSkillShortblade", "sOneHanded"); + mapping[ESM::Weapon::LongBladeOneHand] = std::make_pair("sSkillLongblade", "sOneHanded"); + mapping[ESM::Weapon::LongBladeTwoHand] = std::make_pair("sSkillLongblade", "sTwoHanded"); + mapping[ESM::Weapon::BluntOneHand] = std::make_pair("sSkillBluntweapon", "sOneHanded"); + mapping[ESM::Weapon::BluntTwoClose] = std::make_pair("sSkillBluntweapon", "sTwoHanded"); + mapping[ESM::Weapon::BluntTwoWide] = std::make_pair("sSkillBluntweapon", "sTwoHanded"); + mapping[ESM::Weapon::SpearTwoWide] = std::make_pair("sSkillSpear", "sTwoHanded"); + mapping[ESM::Weapon::AxeOneHand] = std::make_pair("sSkillAxe", "sOneHanded"); + mapping[ESM::Weapon::AxeTwoHand] = std::make_pair("sSkillAxe", "sTwoHanded"); + mapping[ESM::Weapon::MarksmanBow] = std::make_pair("sSkillMarksman", ""); + mapping[ESM::Weapon::MarksmanCrossbow] = std::make_pair("sSkillMarksman", ""); + mapping[ESM::Weapon::MarksmanThrown] = std::make_pair("sSkillMarksman", ""); + + std::string type = mapping[ref->base->data.type].first; + std::string oneOrTwoHanded = mapping[ref->base->data.type].second; + + text += store.gameSettings.search(type)->str + + ((oneOrTwoHanded != "") ? ", " + store.gameSettings.search(oneOrTwoHanded)->str : ""); + + // weapon damage + if (ref->base->data.type >= 9) + { + // marksman + text += "\n" + store.gameSettings.search("sAttack")->str + ": " + + MWGui::ToolTips::toString(static_cast(ref->base->data.chop[0])) + + " - " + MWGui::ToolTips::toString(static_cast(ref->base->data.chop[1])); + } + else + { + // Chop + text += "\n" + store.gameSettings.search("sChop")->str + ": " + + MWGui::ToolTips::toString(static_cast(ref->base->data.chop[0])) + + " - " + MWGui::ToolTips::toString(static_cast(ref->base->data.chop[1])); + // Slash + text += "\n" + store.gameSettings.search("sSlash")->str + ": " + + MWGui::ToolTips::toString(static_cast(ref->base->data.slash[0])) + + " - " + MWGui::ToolTips::toString(static_cast(ref->base->data.slash[1])); + // Thrust + text += "\n" + store.gameSettings.search("sThrust")->str + ": " + + MWGui::ToolTips::toString(static_cast(ref->base->data.thrust[0])) + + " - " + MWGui::ToolTips::toString(static_cast(ref->base->data.thrust[1])); + } + } + + /// \todo store the current weapon health somewhere + if (ref->base->data.type < 11) // thrown weapons and arrows/bolts don't have health, only quantity + text += "\n" + store.gameSettings.search("sCondition")->str + ": " + MWGui::ToolTips::toString(ref->base->data.health); + + text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); + text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); + + info.enchant = ref->base->enchant; + + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); + text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); + } + + info.text = text; + + return info; + } } diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index 505c45645f..9c5f43bd3f 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -12,16 +12,22 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + const MWWorld::Ptr& actor) const; ///< Generate action for activation + virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const; ///< \return Item health data available? @@ -35,8 +41,7 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getEquipmentSkill (const MWWorld::Ptr& ptr, - const MWWorld::Environment& environment) const; + virtual int getEquipmentSkill (const MWWorld::Ptr& ptr) const; /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. @@ -45,10 +50,10 @@ namespace MWClass static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const MWWorld::Ptr& ptr) const; ///< Return the put down sound Id }; } diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 90f0c0231f..ac41244d1c 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -9,9 +9,9 @@ #include +#include "../mwbase/environment.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" #include "../mwworld/refdata.hpp" #include "../mwworld/player.hpp" @@ -54,6 +54,20 @@ namespace return lowerCase; } + bool stringCompareNoCase (std::string first, std::string second) + { + unsigned int i=0; + while ( (itolower(second[i])) return false; + ++i; + } + if (first.length() bool selectCompare (char comp, T1 value1, T2 value2) @@ -181,7 +195,7 @@ namespace MWDialogue case 46://Same faction { - MWMechanics::NpcStats PCstats = MWWorld::Class::get(mEnvironment.mWorld->getPlayer().getPlayer()).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + MWMechanics::NpcStats PCstats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor); int sameFaction = 0; if(!NPCstats.mFactionRank.empty()) @@ -288,12 +302,12 @@ namespace MWDialogue if (select.type==ESM::VT_Short || select.type==ESM::VT_Int || select.type==ESM::VT_Long) { - if (!checkGlobal (comp, toLower (name), select.i, *mEnvironment.mWorld)) + if (!checkGlobal (comp, toLower (name), select.i, *MWBase::Environment::get().getWorld())) return false; } else if (select.type==ESM::VT_Float) { - if (!checkGlobal (comp, toLower (name), select.f, *mEnvironment.mWorld)) + if (!checkGlobal (comp, toLower (name), select.f, *MWBase::Environment::get().getWorld())) return false; } else @@ -308,13 +322,13 @@ namespace MWDialogue select.type==ESM::VT_Long) { if (!checkLocal (comp, toLower (name), select.i, actor, - mEnvironment.mWorld->getStore())) + MWBase::Environment::get().getWorld()->getStore())) return false; } else if (select.type==ESM::VT_Float) { if (!checkLocal (comp, toLower (name), select.f, actor, - mEnvironment.mWorld->getStore())) + MWBase::Environment::get().getWorld()->getStore())) return false; } else @@ -326,7 +340,7 @@ namespace MWDialogue case '4'://journal if(select.type==ESM::VT_Int) { - if(!selectCompare(comp,mEnvironment.mJournal->getJournalIndex(toLower(name)),select.i)) return false; + if(!selectCompare(comp,MWBase::Environment::get().getJournal()->getJournalIndex(toLower(name)),select.i)) return false; } else throw std::runtime_error ( @@ -336,7 +350,7 @@ namespace MWDialogue case '5'://item { - MWWorld::Ptr player = mEnvironment.mWorld->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player); int sum = 0; @@ -424,13 +438,13 @@ namespace MWDialogue select.type==ESM::VT_Long) { if (checkLocal (comp, toLower (name), select.i, actor, - mEnvironment.mWorld->getStore())) + MWBase::Environment::get().getWorld()->getStore())) return false; } else if (select.type==ESM::VT_Float) { if (checkLocal (comp, toLower (name), select.f, actor, - mEnvironment.mWorld->getStore())) + MWBase::Environment::get().getWorld()->getStore())) return false; } else @@ -500,7 +514,7 @@ namespace MWDialogue // TODO check player faction if(!info.pcFaction.empty()) { - MWMechanics::NpcStats stats = MWWorld::Class::get(mEnvironment.mWorld->getPlayer().getPlayer()).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + MWMechanics::NpcStats stats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); std::map::iterator it = stats.mFactionRank.find(info.pcFaction); if(it!=stats.mFactionRank.end()) { @@ -528,7 +542,7 @@ namespace MWDialogue // check cell if (!info.cell.empty()) - if (mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell->name != info.cell) + if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell->name != info.cell) return false; // TODO check DATAstruct @@ -540,8 +554,8 @@ namespace MWDialogue return true; } - DialogueManager::DialogueManager (MWWorld::Environment& environment,const Compiler::Extensions& extensions) : - mEnvironment (environment),mCompilerContext (MWScript::CompilerContext::Type_Dialgoue, environment), + DialogueManager::DialogueManager (const Compiler::Extensions& extensions) : + mCompilerContext (MWScript::CompilerContext::Type_Dialgoue), mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream) { mChoice = -1; @@ -549,10 +563,10 @@ namespace MWDialogue mCompilerContext.setExtensions (&extensions); mDialogueMap.clear(); actorKnownTopics.clear(); - ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; - for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) + ESMS::RecListCaseT::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list; + for(ESMS::RecListCaseT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) { - mDialogueMap[it->first] = it->second; + mDialogueMap[toLower(it->first)] = it->second; } } @@ -592,8 +606,8 @@ namespace MWDialogue actorKnownTopics.clear(); //initialise the GUI - mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue); - MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Dialogue); + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); win->startDialogue(MWWorld::Class::get (actor).getName (actor)); //setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI @@ -601,9 +615,9 @@ namespace MWDialogue //greeting bool greetingFound = false; - //ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; - ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; - for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) + //ESMS::RecListT::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list; + ESMS::RecListCaseT::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list; + for(ESMS::RecListCaseT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) { ESM::Dialogue ndialogue = it->second; if(ndialogue.type == ESM::Dialogue::Greeting) @@ -650,7 +664,7 @@ namespace MWDialogue if (!actorScript.empty()) { // grab local variables from actor's script, if available. - locals = mEnvironment.mScriptManager->getLocals (actorScript); + locals = MWBase::Environment::get().getScriptManager()->getLocals (actorScript); } Compiler::ScriptParser parser(mErrorHandler,mCompilerContext, locals, false); @@ -677,13 +691,12 @@ namespace MWDialogue void DialogueManager::executeScript(std::string script) { - std::cout << script; std::vector code; if(compile(script,code)) { try { - MWScript::InterpreterContext interpreterContext(mEnvironment,&mActor.getRefData().getLocals(),mActor); + MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); Interpreter::Interpreter interpreter; MWScript::installOpcodes (interpreter); interpreter.run (&code[0], code.size(), interpreterContext); @@ -701,9 +714,9 @@ namespace MWDialogue int choice = mChoice; mChoice = -1; actorKnownTopics.clear(); - MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); - ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; - for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); + ESMS::RecListCaseT::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list; + for(ESMS::RecListCaseT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) { ESM::Dialogue ndialogue = it->second; if(ndialogue.type == ESM::Dialogue::Topic) @@ -713,7 +726,7 @@ namespace MWDialogue { if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) { - actorKnownTopics.push_back(it->first); + actorKnownTopics.push_back(toLower(it->first)); //does the player know the topic? if(knownTopics.find(toLower(it->first)) != knownTopics.end()) { @@ -724,7 +737,11 @@ namespace MWDialogue } } } + + // sort again, because the previous sort was case-sensitive + keywordList.sort(stringCompareNoCase); win->setKeywords(keywordList); + mChoice = choice; } @@ -747,7 +764,7 @@ namespace MWDialogue parseText(text); - MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); win->addTitle(keyword); win->addText(iter->response); @@ -767,7 +784,7 @@ namespace MWDialogue void DialogueManager::goodbyeSelected() { - mEnvironment.mInputManager->setGuiMode(MWGui::GM_Game); + MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game); } void DialogueManager::questionAnswered(std::string answere) @@ -790,7 +807,7 @@ namespace MWDialogue mChoiceMap.clear(); mChoice = -1; mIsInChoice = false; - MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); std::string text = iter->response; parseText(text); win->addText(text); @@ -808,15 +825,15 @@ namespace MWDialogue void DialogueManager::printError(std::string error) { - MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); win->addText(error); } void DialogueManager::askQuestion(std::string question, int choice) { - MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); win->askQuestion(question); - mChoiceMap[question] = choice; + mChoiceMap[toLower(question)] = choice; mIsInChoice = true; } diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanager.hpp index d0380fa717..a3e37987db 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanager.hpp @@ -11,17 +11,10 @@ #include "../mwworld/ptr.hpp" #include -namespace MWWorld -{ - class Environment; -} - namespace MWDialogue { class DialogueManager { - MWWorld::Environment& mEnvironment; - bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const; bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const; @@ -39,7 +32,7 @@ namespace MWDialogue MWScript::CompilerContext mCompilerContext; std::ostream mErrorStream; Compiler::StreamErrorHandler mErrorHandler; - + bool compile (const std::string& cmd,std::vector& code); void executeScript(std::string script); @@ -55,7 +48,7 @@ namespace MWDialogue public: - DialogueManager (MWWorld::Environment& environment,const Compiler::Extensions& extensions); + DialogueManager (const Compiler::Extensions& extensions); void startDialogue (const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwdialogue/journal.cpp b/apps/openmw/mwdialogue/journal.cpp index 0715214ebd..e0245406ef 100644 --- a/apps/openmw/mwdialogue/journal.cpp +++ b/apps/openmw/mwdialogue/journal.cpp @@ -1,7 +1,7 @@ #include "journal.hpp" -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" #include "../mwgui/window_manager.hpp" #include "../mwgui/messagebox.hpp" @@ -23,31 +23,30 @@ namespace MWDialogue return iter->second; } - Journal::Journal (MWWorld::Environment& environment) - : mEnvironment (environment) + Journal::Journal() {} void Journal::addEntry (const std::string& id, int index) { StampedJournalEntry entry = - StampedJournalEntry::makeFromQuest (id, index, *mEnvironment.mWorld); + StampedJournalEntry::makeFromQuest (id, index, *MWBase::Environment::get().getWorld()); mJournal.push_back (entry); Quest& quest = getQuest (id); - quest.addEntry (entry, *mEnvironment.mWorld); // we are doing slicing on purpose here - + quest.addEntry (entry, *MWBase::Environment::get().getWorld()); // we are doing slicing on purpose here + std::vector empty; std::string notification = "Your Journal has been updated."; - mEnvironment.mWindowManager->messageBox (notification, empty); + MWBase::Environment::get().getWindowManager()->messageBox (notification, empty); } void Journal::setJournalIndex (const std::string& id, int index) { Quest& quest = getQuest (id); - quest.setIndex (index, *mEnvironment.mWorld); + quest.setIndex (index, *MWBase::Environment::get().getWorld()); } void Journal::addTopic (const std::string& topicId, const std::string& infoId) @@ -62,7 +61,7 @@ namespace MWDialogue iter = result.first; } - iter->second.addEntry (JournalEntry (topicId, infoId), *mEnvironment.mWorld); + iter->second.addEntry (JournalEntry (topicId, infoId), *MWBase::Environment::get().getWorld()); } int Journal::getJournalIndex (const std::string& id) const diff --git a/apps/openmw/mwdialogue/journal.hpp b/apps/openmw/mwdialogue/journal.hpp index ff1343945d..62b9f4bed9 100644 --- a/apps/openmw/mwdialogue/journal.hpp +++ b/apps/openmw/mwdialogue/journal.hpp @@ -8,11 +8,6 @@ #include "journalentry.hpp" #include "quest.hpp" -namespace MWWorld -{ - struct Environment; -} - namespace MWDialogue { /// \brief The player's journal @@ -29,7 +24,6 @@ namespace MWDialogue private: - MWWorld::Environment& mEnvironment; TEntryContainer mJournal; TQuestContainer mQuests; TTopicContainer mTopics; @@ -38,7 +32,7 @@ namespace MWDialogue public: - Journal (MWWorld::Environment& environment); + Journal(); void addEntry (const std::string& id, int index); ///< Add a journal entry. diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index e9c15fab4a..cb15eaf15b 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -25,13 +25,14 @@ BirthDialog::BirthDialog(WindowManager& parWindowManager) birthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); birthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); + backButton->setCaption(mWindowManager.getGameSettingString("sBack", "")); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked); updateBirths(); @@ -46,21 +47,16 @@ void BirthDialog::setNextButtonShow(bool shown) MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - // TODO: All hardcoded coords for buttons are temporary, will be replaced with a dynamic system. if (shown) - { - okButton->setCaption("Next"); - - // Adjust back button when next is shown - backButton->setCoord(MyGUI::IntCoord(375 - 18, 340, 53, 23)); - okButton->setCoord(MyGUI::IntCoord(431 - 18, 340, 42 + 18, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sNext", "")); else - { - okButton->setCaption("OK"); - backButton->setCoord(MyGUI::IntCoord(375, 340, 53, 23)); - okButton->setCoord(MyGUI::IntCoord(431, 340, 42, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); + + int okButtonWidth = okButton->getTextSize().width + 24; + int backButtonWidth = backButton->getTextSize().width + 24; + + okButton->setCoord(473 - okButtonWidth, 340, okButtonWidth, 23); + backButton->setCoord(473 - okButtonWidth - backButtonWidth - 6, 340, backButtonWidth, 23); } void BirthDialog::open() @@ -206,7 +202,7 @@ void BirthDialog::updateSpells() MyGUI::IntCoord spellCoord = coord; spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget in the layout as a template? - spellWidget->createEffectWidgets(spellItems, spellArea, spellCoord); + spellWidget->createEffectWidgets(spellItems, spellArea, spellCoord, (category == 0) ? MWEffectList::EF_Constant : 0); coord.top = spellCoord.top; ++i; diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index ce5e744ccb..9a23758558 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -8,6 +8,8 @@ #include "dialogue.hpp" #include "mode.hpp" +#include "../mwbase/environment.hpp" + namespace { struct Step @@ -93,7 +95,7 @@ namespace using namespace MWGui; -CharacterCreation::CharacterCreation(WindowManager* _wm, MWWorld::Environment* _environment) +CharacterCreation::CharacterCreation(WindowManager* _wm) : mNameDialog(0) , mRaceDialog(0) , mDialogueWindow(0) @@ -105,7 +107,6 @@ CharacterCreation::CharacterCreation(WindowManager* _wm, MWWorld::Environment* _ , mBirthSignDialog(0) , mReviewDialog(0) , mWM(_wm) - , mEnvironment(_environment) { mCreationStage = CSE_NotStarted; } @@ -279,8 +280,8 @@ void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow) { const std::string &classId = mPickClassDialog->getClassId(); if (!classId.empty()) - mEnvironment->mMechanicsManager->setPlayerClass(classId); - const ESM::Class *klass = mEnvironment->mWorld->getStore().classes.find(classId); + MWBase::Environment::get().getMechanicsManager()->setPlayerClass(classId); + const ESM::Class *klass = MWBase::Environment::get().getWorld()->getStore().classes.find(classId); if (klass) { mPlayerClass = *klass; @@ -307,7 +308,7 @@ void CharacterCreation::onPickClassDialogBack() { const std::string classId = mPickClassDialog->getClassId(); if (!classId.empty()) - mEnvironment->mMechanicsManager->setPlayerClass(classId); + MWBase::Environment::get().getMechanicsManager()->setPlayerClass(classId); mWM->removeDialog(mPickClassDialog); } @@ -345,7 +346,7 @@ void CharacterCreation::onNameDialogDone(WindowBase* parWindow) { mPlayerName = mNameDialog->getTextInput(); mWM->setValue("name", mPlayerName); - mEnvironment->mMechanicsManager->setPlayerName(mPlayerName); + MWBase::Environment::get().getMechanicsManager()->setPlayerName(mPlayerName); mWM->removeDialog(mNameDialog); } @@ -366,7 +367,7 @@ void CharacterCreation::onRaceDialogBack() { mPlayerRaceId = mRaceDialog->getRaceId(); if (!mPlayerRaceId.empty()) - mEnvironment->mMechanicsManager->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male); + MWBase::Environment::get().getMechanicsManager()->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male); mWM->removeDialog(mRaceDialog); } @@ -380,7 +381,7 @@ void CharacterCreation::onRaceDialogDone(WindowBase* parWindow) mPlayerRaceId = mRaceDialog->getRaceId(); mWM->setValue("race", mPlayerRaceId); if (!mPlayerRaceId.empty()) - mEnvironment->mMechanicsManager->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male); + MWBase::Environment::get().getMechanicsManager()->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male); mWM->removeDialog(mRaceDialog); } @@ -402,7 +403,7 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow) mPlayerBirthSignId = mBirthSignDialog->getBirthId(); mWM->setBirthSign(mPlayerBirthSignId); if (!mPlayerBirthSignId.empty()) - mEnvironment->mMechanicsManager->setPlayerBirthsign(mPlayerBirthSignId); + MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mPlayerBirthSignId); mWM->removeDialog(mBirthSignDialog); } @@ -419,7 +420,7 @@ void CharacterCreation::onBirthSignDialogBack() { if (mBirthSignDialog) { - mEnvironment->mMechanicsManager->setPlayerBirthsign(mBirthSignDialog->getBirthId()); + MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mBirthSignDialog->getBirthId()); mWM->removeDialog(mBirthSignDialog); } @@ -450,7 +451,7 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) klass.data.skills[i][1] = majorSkills[i]; klass.data.skills[i][0] = minorSkills[i]; } - mEnvironment->mMechanicsManager->setPlayerClass(klass); + MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass); mPlayerClass = klass; mWM->setPlayerClass(klass); @@ -592,7 +593,7 @@ void CharacterCreation::onGenerateClassBack() if (mGenerateClassResultDialog) mWM->removeDialog(mGenerateClassResultDialog); - mEnvironment->mMechanicsManager->setPlayerClass(mGenerateClass); + MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); mWM->setGuiMode(GM_Class); } @@ -601,7 +602,7 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow) { if (mGenerateClassResultDialog) mWM->removeDialog(mGenerateClassResultDialog); - mEnvironment->mMechanicsManager->setPlayerClass(mGenerateClass); + MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); if (mCreationStage == CSE_ReviewNext) mWM->setGuiMode(GM_Review); diff --git a/apps/openmw/mwgui/charactercreation.hpp b/apps/openmw/mwgui/charactercreation.hpp index b01e754d9d..222754cdc3 100644 --- a/apps/openmw/mwgui/charactercreation.hpp +++ b/apps/openmw/mwgui/charactercreation.hpp @@ -30,7 +30,7 @@ namespace MWGui public: typedef std::vector SkillList; - CharacterCreation(WindowManager* _wm, MWWorld::Environment* _environment); + CharacterCreation(WindowManager* _wm); ~CharacterCreation(); //Show a dialog @@ -56,7 +56,6 @@ namespace MWGui ReviewDialog* mReviewDialog; WindowManager* mWM; - MWWorld::Environment* mEnvironment; //Player data std::string mPlayerName; diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 75e534b42a..9f1fc5d2a5 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -26,14 +26,20 @@ GenerateClassResultDialog::GenerateClassResultDialog(WindowManager& parWindowMan getWidget(classImage, "ClassImage"); getWidget(className, "ClassName"); - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); + backButton->setCaption(mWindowManager.getGameSettingString("sBack", "")); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked); + + int okButtonWidth = okButton->getTextSize().width + 24; + int backButtonWidth = backButton->getTextSize().width + 24; + okButton->setCoord(315 - okButtonWidth, 219, okButtonWidth, 23); + backButton->setCoord(315 - okButtonWidth - backButtonWidth - 6, 219, backButtonWidth, 23); } void GenerateClassResultDialog::open() @@ -102,7 +108,6 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager) getWidget(classImage, "ClassImage"); - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked); @@ -123,21 +128,16 @@ void PickClassDialog::setNextButtonShow(bool shown) MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - // TODO: All hardcoded coords for buttons are temporary, will be replaced with a dynamic system. if (shown) - { - okButton->setCaption("Next"); - - // Adjust back button when next is shown - backButton->setCoord(MyGUI::IntCoord(382 - 18, 265, 53, 23)); - okButton->setCoord(MyGUI::IntCoord(434 - 18, 265, 42 + 18, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sNext", "")); else - { - okButton->setCaption("OK"); - backButton->setCoord(MyGUI::IntCoord(382, 265, 53, 23)); - okButton->setCoord(MyGUI::IntCoord(434, 265, 42, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); + + int okButtonWidth = okButton->getTextSize().width + 24; + int backButtonWidth = backButton->getTextSize().width + 24; + + okButton->setCoord(476 - okButtonWidth, 265, okButtonWidth, 23); + backButton->setCoord(476 - okButtonWidth - backButtonWidth - 6, 265, backButtonWidth, 23); } void PickClassDialog::open() @@ -423,9 +423,9 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) // Make sure the edit box has focus MyGUI::InputManager::getInstance().setKeyFocusWidget(editName); - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr descriptionButton; getWidget(descriptionButton, "DescriptionButton"); + descriptionButton->setCaption(mWindowManager.getGameSettingString("sCreateClassMenu1", "")); descriptionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionClicked); MyGUI::ButtonPtr backButton; @@ -507,32 +507,27 @@ std::vector CreateClassDialog::getMinorSkills() const void CreateClassDialog::setNextButtonShow(bool shown) { - MyGUI::ButtonPtr descriptionButton; - getWidget(descriptionButton, "DescriptionButton"); - MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - // TODO: All hardcoded coords for buttons are temporary, will be replaced with a dynamic system. - if (shown) - { - okButton->setCaption("Next"); + MyGUI::ButtonPtr descriptionButton; + getWidget(descriptionButton, "DescriptionButton"); - // Adjust back button when next is shown - descriptionButton->setCoord(MyGUI::IntCoord(207 - 18, 158, 143, 23)); - backButton->setCoord(MyGUI::IntCoord(356 - 18, 158, 53, 23)); - okButton->setCoord(MyGUI::IntCoord(417 - 18, 158, 42 + 18, 23)); - } + if (shown) + okButton->setCaption(mWindowManager.getGameSettingString("sNext", "")); else - { - okButton->setCaption("OK"); - descriptionButton->setCoord(MyGUI::IntCoord(207, 158, 143, 23)); - backButton->setCoord(MyGUI::IntCoord(356, 158, 53, 23)); - okButton->setCoord(MyGUI::IntCoord(417, 158, 42, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); + + int okButtonWidth = okButton->getTextSize().width + 24; + int backButtonWidth = backButton->getTextSize().width + 24; + int descriptionButtonWidth = descriptionButton->getTextSize().width + 24; + + okButton->setCoord(459 - okButtonWidth, 158, okButtonWidth, 23); + backButton->setCoord(459 - okButtonWidth - backButtonWidth - 6, 158, backButtonWidth, 23); + descriptionButton->setCoord(459 - okButtonWidth - backButtonWidth - descriptionButtonWidth - 12, 158, descriptionButtonWidth, 23); } void CreateClassDialog::open() @@ -679,11 +674,12 @@ SelectSpecializationDialog::SelectSpecializationDialog(WindowManager& parWindowM specialization2->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); specializationId = ESM::Class::Combat; - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr cancelButton; getWidget(cancelButton, "CancelButton"); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); + int buttonWidth = cancelButton->getTextSize().width + 24; + cancelButton->setCoord(216 - buttonWidth, 90, buttonWidth, 21); } // widget controls @@ -728,11 +724,12 @@ SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager) attribute->eventClicked += MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); } - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr cancelButton; getWidget(cancelButton, "CancelButton"); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); + int buttonWidth = cancelButton->getTextSize().width + 24; + cancelButton->setCoord(186 - buttonWidth, 180, buttonWidth, 21); } // widget controls @@ -817,11 +814,12 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager) } } - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr cancelButton; getWidget(cancelButton, "CancelButton"); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); + int buttonWidth = cancelButton->getTextSize().width + 24; + cancelButton->setCoord(447 - buttonWidth, 218, buttonWidth, 21); } // widget controls @@ -847,11 +845,12 @@ DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager) getWidget(textEdit, "TextEdit"); - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked); okButton->setCaption(mWindowManager.getGameSettingString("sInputMenu1", "")); + int buttonWidth = okButton->getTextSize().width + 24; + okButton->setCoord(234 - buttonWidth, 214, buttonWidth, 24); // Make sure the edit box has focus MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index ac4f4a82a9..8e15abddd6 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -7,6 +7,8 @@ #include "../mwscript/extensions.hpp" +#include "../mwbase/environment.hpp" + namespace MWGui { class ConsoleInterpreterContext : public MWScript::InterpreterContext @@ -15,15 +17,14 @@ namespace MWGui public: - ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment, - MWWorld::Ptr reference); + ConsoleInterpreterContext (Console& console, MWWorld::Ptr reference); virtual void report (const std::string& message); }; ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console, - MWWorld::Environment& environment, MWWorld::Ptr reference) - : MWScript::InterpreterContext (environment, + MWWorld::Ptr reference) + : MWScript::InterpreterContext ( reference.isEmpty() ? 0 : &reference.getRefData().getLocals(), reference), mConsole (console) {} @@ -88,7 +89,7 @@ namespace MWGui scanner.listKeywords (mNames); // identifier - const ESMS::ESMStore& store = mEnvironment.mWorld->getStore(); + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); for (ESMS::RecListList::const_iterator iter (store.recLists.begin()); iter!=store.recLists.end(); ++iter) @@ -101,11 +102,9 @@ namespace MWGui } } - Console::Console(int w, int h, MWWorld::Environment& environment, - const Compiler::Extensions& extensions) + Console::Console(int w, int h, const Compiler::Extensions& extensions) : Layout("openmw_console_layout.xml"), - mCompilerContext (MWScript::CompilerContext::Type_Console, environment), - mEnvironment (environment) + mCompilerContext (MWScript::CompilerContext::Type_Console) { setCoord(10,10, w-10, h/2); @@ -139,7 +138,7 @@ namespace MWGui void Console::disable() { setVisible(false); - // Remove keyboard focus from the console input whenever the + // Remove keyboard focus from the console input whenever the // console is turned off MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL); } @@ -241,7 +240,7 @@ namespace MWGui { try { - ConsoleInterpreterContext interpreterContext (*this, mEnvironment, MWWorld::Ptr()); + ConsoleInterpreterContext interpreterContext (*this, MWWorld::Ptr()); Interpreter::Interpreter interpreter; MWScript::installOpcodes (interpreter); std::vector code; diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp index eaf4299be0..6974d83330 100644 --- a/apps/openmw/mwgui/console.hpp +++ b/apps/openmw/mwgui/console.hpp @@ -23,7 +23,6 @@ namespace MWGui private: MWScript::CompilerContext mCompilerContext; - MWWorld::Environment& mEnvironment; std::vector mNames; bool compile (const std::string& cmd, Compiler::Output& output); @@ -51,7 +50,7 @@ namespace MWGui StringList::iterator current; std::string editString; - Console(int w, int h, MWWorld::Environment& environment, const Compiler::Extensions& extensions); + Console(int w, int h, const Compiler::Extensions& extensions); void enable(); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index ac6681e279..0238446ebe 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -3,7 +3,7 @@ #include "window_manager.hpp" #include "widgets.hpp" #include "components/esm_store/store.hpp" -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" #include "../mwdialogue/dialoguemanager.hpp" #include @@ -36,9 +36,8 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su } -DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment) - : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager), - mEnvironment(environment) +DialogueWindow::DialogueWindow(WindowManager& parWindowManager) + : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager) { // Centre dialog center(); @@ -51,10 +50,10 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environm //An EditBox cannot receive mouse click events, so we use an //invisible widget on top of the editbox to receive them - /// \todo scrolling the dialogue history with the mouse wheel doesn't work using this solution getWidget(eventbox, "EventBox"); eventbox->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked); - + eventbox->eventMouseWheel += MyGUI::newDelegate(this, &DialogueWindow::onMouseWheel); + //Topics list getWidget(topicsList, "TopicsList"); topicsList->setScrollVisible(true); @@ -83,12 +82,20 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) if(color != "#B29154") { UString key = history->getColorTextAt(cursorPosition); - if(color == "#686EBA") mEnvironment.mDialogueManager->keywordSelected(lower_string(key)); + if(color == "#686EBA") MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(key)); - if(color == "#572D21") mEnvironment.mDialogueManager->questionAnswered(key); + if(color == "#572D21") MWBase::Environment::get().getDialogueManager()->questionAnswered(lower_string(key)); } } +void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) +{ + if (history->getVScrollPosition() - _rel*0.3 < 0) + history->setVScrollPosition(0); + else + history->setVScrollPosition(history->getVScrollPosition() - _rel*0.3); +} + void DialogueWindow::open() { topicsList->removeAllItems(); @@ -100,7 +107,7 @@ void DialogueWindow::open() void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) { - mEnvironment.mDialogueManager->goodbyeSelected(); + MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); } void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index) @@ -108,7 +115,7 @@ void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index) if (_index == MyGUI::ITEM_NONE) return; std::string topic = _sender->getItemNameAt(_index); - mEnvironment.mDialogueManager->keywordSelected(lower_string(topic)); + MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); } void DialogueWindow::startDialogue(std::string npcName) @@ -183,6 +190,16 @@ void DialogueWindow::addText(std::string text) void DialogueWindow::addTitle(std::string text) { + // This is called from the dialogue manager, so text is + // case-smashed - thus we have to retrieve the correct case + // of the text through the topic list. + for (size_t i=0; igetItemCount(); ++i) + { + std::string item = topicsList->getItemNameAt(i); + if (lower_string(item) == text) + text = item; + } + history->addDialogHeading(text); } diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index b80a016cbe..5921ca57a2 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -9,11 +9,6 @@ namespace MWGui class WindowManager; } -namespace MWWorld -{ - class Environment; -} - /* This file contains the dialouge window Layout is defined by resources/mygui/openmw_dialogue_window_layout.xml. @@ -23,17 +18,15 @@ namespace MWGui { class DialogueHistory; - using namespace MyGUI; - class DialogueWindow: public WindowBase { public: - DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment); + DialogueWindow(WindowManager& parWindowManager); void open(); // Events - typedef delegates::CMultiDelegate0 EventHandle_Void; + typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; /** Event : Dialog finished, OK button clicked.\n signature : void method()\n @@ -52,6 +45,7 @@ namespace MWGui void onSelectTopic(MyGUI::ListBox* _sender, size_t _index); void onByeClicked(MyGUI::Widget* _sender); void onHistoryClicked(MyGUI::Widget* _sender); + void onMouseWheel(MyGUI::Widget* _sender, int _rel); private: void updateOptions(); @@ -65,8 +59,6 @@ namespace MWGui MyGUI::ProgressPtr pDispositionBar; MyGUI::EditPtr pDispositionText; std::map pTopicsText;// this map links keyword and "real" text. - - MWWorld::Environment& mEnvironment; }; } #endif diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 644bcbc04f..e67eda7771 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -1,7 +1,7 @@ #include "journalwindow.hpp" #include "window_manager.hpp" #include "../mwdialogue/journal.hpp" -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" #include "../mwworld/world.hpp" #include "../mwsound/soundmanager.hpp" @@ -118,20 +118,20 @@ void MWGui::JournalWindow::open() { mPageNumber = 0; std::string journalOpenSound = "book open"; - mWindowManager.getEnvironment().mSoundManager->playSound (journalOpenSound, 1.0, 1.0); - if(mWindowManager.getEnvironment().mJournal->begin()!=mWindowManager.getEnvironment().mJournal->end()) + MWBase::Environment::get().getSoundManager()->playSound (journalOpenSound, 1.0, 1.0); + if(MWBase::Environment::get().getJournal()->begin()!=MWBase::Environment::get().getJournal()->end()) { book journal; journal.endLine = 0; - for(std::deque::const_iterator it = mWindowManager.getEnvironment().mJournal->begin();it!=mWindowManager.getEnvironment().mJournal->end();it++) + for(std::deque::const_iterator it = MWBase::Environment::get().getJournal()->begin();it!=MWBase::Environment::get().getJournal()->end();it++) { - std::string a = it->getText(mWindowManager.getEnvironment().mWorld->getStore()); + std::string a = it->getText(MWBase::Environment::get().getWorld()->getStore()); journal = formatText(a,journal,10,17); journal.endLine = journal.endLine +1; journal.pages.back() = journal.pages.back() + std::string("\n"); } - //std::string a = mWindowManager.getEnvironment().mJournal->begin()->getText(mWindowManager.getEnvironment().mWorld->getStore()); + //std::string a = MWBase::Environment::get().getJournal()->begin()->getText(MWBase::Environment::get().getWorld()->getStore()); //std::list journal = formatText(a,10,20,1); bool left = true; for(std::list::iterator it = journal.pages.begin(); it != journal.pages.end();it++) @@ -155,7 +155,7 @@ void MWGui::JournalWindow::open() } else { - //std::cout << mWindowManager.getEnvironment().mJournal->begin()->getText(mWindowManager.getEnvironment().mWorld->getStore()); + //std::cout << MWBase::Environment::get().getJournal()->begin()->getText(MWBase::Environment::get().getWorld()->getStore()); } } @@ -181,7 +181,7 @@ void MWGui::JournalWindow::notifyNextPage(MyGUI::WidgetPtr _sender) if(mPageNumber < int(leftPages.size())-1) { std::string nextSound = "book page2"; - mWindowManager.getEnvironment().mSoundManager->playSound (nextSound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound (nextSound, 1.0, 1.0); mPageNumber = mPageNumber + 1; displayLeftText(leftPages[mPageNumber]); displayRightText(rightPages[mPageNumber]); @@ -193,7 +193,7 @@ void MWGui::JournalWindow::notifyPrevPage(MyGUI::WidgetPtr _sender) if(mPageNumber > 0) { std::string prevSound = "book page"; - mWindowManager.getEnvironment().mSoundManager->playSound (prevSound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound (prevSound, 1.0, 1.0); mPageNumber = mPageNumber - 1; displayLeftText(leftPages[mPageNumber]); displayRightText(rightPages[mPageNumber]); diff --git a/apps/openmw/mwgui/map_window.cpp b/apps/openmw/mwgui/map_window.cpp index 0e9d57c3c2..e0c828fdc4 100644 --- a/apps/openmw/mwgui/map_window.cpp +++ b/apps/openmw/mwgui/map_window.cpp @@ -29,6 +29,9 @@ MapWindow::MapWindow(WindowManager& parWindowManager) : getWidget(mButton, "WorldButton"); mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); + mButton->setCaption(mWindowManager.getGameSettingString("sWorld", "")); + int width = mButton->getTextSize().width + 24; + mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22); MyGUI::Button* eventbox; getWidget(eventbox, "EventBox"); @@ -97,7 +100,10 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) mGlobalMap->setVisible(mGlobal); mLocalMap->setVisible(!mGlobal); - mButton->setCaption( mGlobal ? "Local" : "World" ); + mButton->setCaption( mGlobal ? mWindowManager.getGameSettingString("sWorld", "") : + mWindowManager.getGameSettingString("sLocal", "")); + int width = mButton->getTextSize().width + 24; + mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22); } void MapWindow::onPinToggled() diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 880c0bc520..275759c9f7 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -69,13 +69,14 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager) setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials")); getWidget(spellPowerList, "SpellPowerList"); - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); + backButton->setCaption(mWindowManager.getGameSettingString("sBack", "")); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked); updateRaces(); @@ -91,21 +92,16 @@ void RaceDialog::setNextButtonShow(bool shown) MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - // TODO: All hardcoded coords for buttons are temporary, will be replaced with a dynamic system. if (shown) - { - okButton->setCaption("Next"); - - // Adjust back button when next is shown - backButton->setCoord(MyGUI::IntCoord(471 - 18, 397, 53, 23)); - okButton->setCoord(MyGUI::IntCoord(532 - 18, 397, 42 + 18, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sNext", "")); else - { - okButton->setCaption("OK"); - backButton->setCoord(MyGUI::IntCoord(471, 397, 53, 23)); - okButton->setCoord(MyGUI::IntCoord(532, 397, 42, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); + + int okButtonWidth = okButton->getTextSize().width + 24; + int backButtonWidth = backButton->getTextSize().width + 24; + + okButton->setCoord(574 - okButtonWidth, 397, okButtonWidth, 23); + backButton->setCoord(574 - okButtonWidth - backButtonWidth - 6, 397, backButtonWidth, 23); } void RaceDialog::open() diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index cb0d9969c6..7dfe514def 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -28,21 +28,25 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager) getWidget(nameWidget, "NameText"); getWidget(button, "NameButton"); button->setCaption(mWindowManager.getGameSettingString("sName", "")); + adjustButtonSize(button); button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);; getWidget(raceWidget, "RaceText"); getWidget(button, "RaceButton"); button->setCaption(mWindowManager.getGameSettingString("sRace", "")); + adjustButtonSize(button); button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);; getWidget(classWidget, "ClassText"); getWidget(button, "ClassButton"); button->setCaption(mWindowManager.getGameSettingString("sClass", "")); + adjustButtonSize(button); button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);; getWidget(birthSignWidget, "SignText"); getWidget(button, "SignButton"); button->setCaption(mWindowManager.getGameSettingString("sBirthSign", "")); + adjustButtonSize(button); button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);; // Setup dynamic stats @@ -86,14 +90,20 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager) static_cast(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ReviewDialog::onWindowResize); - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); + backButton->setCaption(mWindowManager.getGameSettingString("sBack", "")); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked); + + int backButtonWidth = backButton->getTextSize().width + 24; + int okButtonWidth = okButton->getTextSize().width + 24; + okButton->setCoord(502 - okButtonWidth, 372, okButtonWidth, 23); + backButton->setCoord(502 - okButtonWidth - backButtonWidth - 6, 372, backButtonWidth, 23); } void ReviewDialog::open() @@ -181,13 +191,14 @@ void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanic { float modified = value.getModified(), base = value.getBase(); std::string text = boost::lexical_cast(std::floor(modified)); - ColorStyle style = CS_Normal; + std::string state = "normal"; if (modified > base) - style = CS_Super; + state = "increased"; else if (modified < base) - style = CS_Sub; + state = "decreased"; - setStyledText(widget, style, text); + widget->setCaption(text); + widget->_setWidgetState(state); } } @@ -210,17 +221,6 @@ void ReviewDialog::configureSkills(const std::vector& major, const std::vec } } -void ReviewDialog::setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value) -{ - widget->setCaption(value); - if (style == CS_Super) - widget->setTextColour(MyGUI::Colour(0, 1, 0)); - else if (style == CS_Sub) - widget->setTextColour(MyGUI::Colour(1, 0, 0)); - else - widget->setTextColour(MyGUI::Colour(1, 1, 1)); -} - void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { MyGUI::ImageBox* separator = skillClientWidget->createWidget("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); @@ -240,7 +240,7 @@ void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, M coord2.top += lineHeight; } -MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { MyGUI::TextBox* skillNameWidget; MyGUI::TextBox* skillValueWidget; @@ -249,7 +249,8 @@ MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::st skillNameWidget->setCaption(text); skillValueWidget = skillClientWidget->createWidget("SandTextRight", coord2, MyGUI::Align::Default); - setStyledText(skillValueWidget, style, value); + skillValueWidget->setCaption(value); + skillValueWidget->_setWidgetState(state); skillWidgets.push_back(skillNameWidget); skillWidgets.push_back(skillValueWidget); @@ -295,12 +296,12 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId float base = stat.getBase(); float modified = stat.getModified(); - ColorStyle style = CS_Normal; + std::string state = "normal"; if (modified > base) - style = CS_Super; + state = "increased"; else if (modified < base) - style = CS_Sub; - MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); + state = "decreased"; + MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), state, coord1, coord2); skillWidgetMap[skillId] = widget; } } diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index 588c1b6b5d..76ca5a2d76 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -69,17 +69,10 @@ namespace MWGui void onBirthSignClicked(MyGUI::Widget* _sender); private: - enum ColorStyle - { - CS_Sub, - CS_Normal, - CS_Super - }; - void setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value); void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - MyGUI::TextBox* addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + MyGUI::TextBox* addValueItem(const std::string text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void updateScroller(); void updateSkillArea(); diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 675e5141fa..b007fc1d40 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -72,6 +72,8 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager) MyGUI::WindowPtr t = static_cast(mMainWidget); t->eventWindowChangeCoord += MyGUI::newDelegate(this, &StatsWindow::onWindowResize); + + setupToolTips(); } void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos) @@ -109,17 +111,7 @@ void StatsWindow::setBar(const std::string& name, const std::string& tname, int void StatsWindow::setPlayerName(const std::string& playerName) { static_cast(mMainWidget)->setCaption(playerName); -} - -void StatsWindow::setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value) -{ - widget->setCaption(value); - if (style == CS_Super) - widget->setTextColour(MyGUI::Colour(0, 1, 0)); - else if (style == CS_Sub) - widget->setTextColour(MyGUI::Colour(1, 0, 0)); - else - widget->setTextColour(MyGUI::Colour(1, 1, 1)); + adjustWindowCaption(); } void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat& value) @@ -138,12 +130,15 @@ void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat& valueString << value.getModified(); setText (id, valueString.str()); + MyGUI::TextBox* box; + getWidget(box, id); + if (value.getModified()>value.getBase()) - setTextColor (id, 0, 1, 0); + box->_setWidgetState("increased"); else if (value.getModified()_setWidgetState("decreased"); else - setTextColor (id, 1, 1, 1); + box->_setWidgetState("normal"); break; } @@ -193,13 +188,14 @@ void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechani { float modified = value.getModified(), base = value.getBase(); std::string text = boost::lexical_cast(std::floor(modified)); - ColorStyle style = CS_Normal; + std::string state = "normal"; if (modified > base) - style = CS_Super; + state = "increased"; else if (modified < base) - style = CS_Sub; + state = "decreased"; - setStyledText(widget, style, text); + widget->setCaption(text); + widget->_setWidgetState(state); } } @@ -251,15 +247,20 @@ void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, My coord2.top += lineHeight; } -MyGUI::TextBox* StatsWindow::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string& tooltip, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { MyGUI::TextBox *skillNameWidget, *skillValueWidget; skillNameWidget = skillClientWidget->createWidget("SandText", coord1, MyGUI::Align::Default); skillNameWidget->setCaption(text); + skillNameWidget->setUserString("ToolTipType", "Text"); + skillNameWidget->setUserString("ToolTipText", tooltip); skillValueWidget = skillClientWidget->createWidget("SandTextRight", coord2, MyGUI::Align::Default); - setStyledText(skillValueWidget, style, value); + skillValueWidget->setUserString("ToolTipType", "Text"); + skillValueWidget->setUserString("ToolTipText", tooltip); + skillValueWidget->setCaption(value); + skillValueWidget->_setWidgetState(state); skillWidgets.push_back(skillNameWidget); skillWidgets.push_back(skillValueWidget); @@ -305,12 +306,13 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, float base = stat.getBase(); float modified = stat.getModified(); - ColorStyle style = CS_Normal; + std::string state = "normal"; if (modified > base) - style = CS_Super; + state = "increased"; else if (modified < base) - style = CS_Sub; - MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); + state = "decreased"; + MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), "", + boost::lexical_cast(static_cast(modified)), state, coord1, coord2); skillWidgetMap[skillId] = widget; } } @@ -369,8 +371,12 @@ void StatsWindow::updateSkillArea() if (!skillWidgets.empty()) addSeparator(coord1, coord2); - addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"), boost::lexical_cast(static_cast(reputation)), CS_Normal, coord1, coord2); - addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"), boost::lexical_cast(static_cast(bounty)), CS_Normal, coord1, coord2); + addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"), + mWindowManager.getGameSettingString("sSkillsMenuReputationHelp", ""), + boost::lexical_cast(static_cast(reputation)), "normal", coord1, coord2); + addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"), + mWindowManager.getGameSettingString("sCrimeHelp", ""), + boost::lexical_cast(static_cast(bounty)), "normal", coord1, coord2); clientHeight = coord1.top; updateScroller(); @@ -386,3 +392,98 @@ void StatsWindow::onPinToggled() { mWindowManager.setHMSVisibility(!mPinned); } + +void StatsWindow::setupToolTips() +{ + + const ESMS::ESMStore &store = mWindowManager.getStore(); + MyGUI::Widget* widget; + + getWidget(widget, "Attrib1"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeStrength")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sStrDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_strength.dds"); + getWidget(widget, "AttribVal1"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeStrength")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sStrDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_strength.dds"); + + getWidget(widget, "Attrib2"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeIntelligence")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sIntDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_int.dds"); + getWidget(widget, "AttribVal2"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeIntelligence")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sIntDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_int.dds"); + + getWidget(widget, "Attrib3"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeWillpower")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sWilDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_wilpower.dds"); + getWidget(widget, "AttribVal3"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeWillpower")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sWilDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_wilpower.dds"); + + getWidget(widget, "Attrib4"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeAgility")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sAgiDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_agility.dds"); + getWidget(widget, "AttribVal4"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeAgility")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sAgiDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_agility.dds"); + + getWidget(widget, "Attrib5"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeSpeed")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sSpdDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_speed.dds"); + getWidget(widget, "AttribVal5"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeSpeed")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sSpdDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_speed.dds"); + + getWidget(widget, "Attrib6"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeEndurance")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sEndDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_endurance.dds"); + getWidget(widget, "AttribVal6"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeEndurance")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sEndDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_endurance.dds"); + + getWidget(widget, "Attrib7"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributePersonality")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sPerDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_personality.dds"); + getWidget(widget, "AttribVal7"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributePersonality")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sPerDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_personality.dds"); + + getWidget(widget, "Attrib8"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeLuck")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sLucDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_luck.dds"); + getWidget(widget, "AttribVal8"); + widget->setUserString("ToolTipType", "ImageCaptionText"); + widget->setUserString("ToolTipCaption", store.gameSettings.find ("sAttributeLuck")->str); + widget->setUserString("ToolTipText", store.gameSettings.find ("sLucDesc")->str); + widget->setUserString("ToolTipImage", "k\\attribute_luck.dds"); +} diff --git a/apps/openmw/mwgui/stats_window.hpp b/apps/openmw/mwgui/stats_window.hpp index f2731e545c..ecbc82894e 100644 --- a/apps/openmw/mwgui/stats_window.hpp +++ b/apps/openmw/mwgui/stats_window.hpp @@ -43,20 +43,15 @@ namespace MWGui void updateSkillArea(); private: - enum ColorStyle - { - CS_Sub, - CS_Normal, - CS_Super - }; - void setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value); void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - MyGUI::TextBox* addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + MyGUI::TextBox* addValueItem(const std::string& text, const std::string& tooltip, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void updateScroller(); + void setupToolTips(); + void onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos); void onWindowResize(MyGUI::Window* window); diff --git a/apps/openmw/mwgui/text_input.cpp b/apps/openmw/mwgui/text_input.cpp index 8ac07e7668..7d84a9b9fd 100644 --- a/apps/openmw/mwgui/text_input.cpp +++ b/apps/openmw/mwgui/text_input.cpp @@ -12,7 +12,6 @@ TextInputDialog::TextInputDialog(WindowManager& parWindowManager) getWidget(textEdit, "TextEdit"); textEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted); - // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); @@ -25,16 +24,15 @@ void TextInputDialog::setNextButtonShow(bool shown) { MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); + if (shown) - { - okButton->setCaption("Next"); - okButton->setCoord(MyGUI::IntCoord(264 - 18, 60, 42 + 18, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sNext", "")); else - { - okButton->setCaption("OK"); - okButton->setCoord(MyGUI::IntCoord(264, 60, 42, 23)); - } + okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); + + int okButtonWidth = okButton->getTextSize().width + 24; + + okButton->setCoord(306 - okButtonWidth, 60, okButtonWidth, 23); } void TextInputDialog::setTextLabel(const std::string &label) diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp new file mode 100644 index 0000000000..90b5baa679 --- /dev/null +++ b/apps/openmw/mwgui/tooltips.cpp @@ -0,0 +1,365 @@ +#include "tooltips.hpp" + +#include "window_manager.hpp" +#include "widgets.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/world.hpp" +#include "../mwbase/environment.hpp" + +#include + +using namespace MWGui; +using namespace MyGUI; + +ToolTips::ToolTips(WindowManager* windowManager) : + Layout("openmw_tooltips.xml") + , mGameMode(true) + , mWindowManager(windowManager) + , mFullHelp(false) +{ + getWidget(mDynamicToolTipBox, "DynamicToolTipBox"); + + mDynamicToolTipBox->setVisible(false); + + // turn off mouse focus so that getMouseFocusWidget returns the correct widget, + // even if the mouse is over the tooltip + mDynamicToolTipBox->setNeedMouseFocus(false); + mMainWidget->setNeedMouseFocus(false); +} + +void ToolTips::onFrame(float frameDuration) +{ + /// \todo Store a MWWorld::Ptr in the widget user data, retrieve it here and construct a tooltip dynamically + + /// \todo we are destroying/creating the tooltip widgets every frame here, + /// because the tooltip might change (e.g. when trap is activated) + /// is there maybe a better way (listener when the object changes)? + for (size_t i=0; igetChildCount(); ++i) + { + mDynamicToolTipBox->_destroyChildWidget(mDynamicToolTipBox->getChildAt(i)); + } + + const IntSize &viewSize = RenderManager::getInstance().getViewSize(); + + if (!mGameMode) + { + Widget* focus = InputManager::getInstance().getMouseFocusWidget(); + if (focus == 0) + { + mDynamicToolTipBox->setVisible(false); + return; + } + + IntSize tooltipSize; + + std::string type = focus->getUserString("ToolTipType"); + std::string text = focus->getUserString("ToolTipText"); + + ToolTipInfo info; + + if (type == "") + { + mDynamicToolTipBox->setVisible(false); + return; + } + else if (type == "Text") + { + info.caption = text; + } + else if (type == "CaptionText") + { + std::string caption = focus->getUserString("ToolTipCaption"); + info.caption = caption; + info.text = text; + } + else if (type == "ImageCaptionText") + { + std::string caption = focus->getUserString("ToolTipCaption"); + std::string image = focus->getUserString("ToolTipImage"); + std::string sizeString = focus->getUserString("ToolTipImageSize"); + + info.text = text; + info.caption = caption; + info.icon = image; + } + tooltipSize = createToolTip(info); + + IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24); + + // make the tooltip stay completely in the viewport + if ((tooltipPosition.left + tooltipSize.width) > viewSize.width) + { + tooltipPosition.left = viewSize.width - tooltipSize.width; + } + if ((tooltipPosition.top + tooltipSize.height) > viewSize.height) + { + tooltipPosition.top = viewSize.height - tooltipSize.height; + } + + setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height); + mDynamicToolTipBox->setVisible(true); + } + else + { + if (!mFocusObject.isEmpty()) + { + IntSize tooltipSize = getToolTipViaPtr(); + + // adjust tooltip size to fit its content, position it above the crosshair + /// \todo Slide the tooltip along the bounding box of the focused object (like in Morrowind) + setCoord(viewSize.width/2 - (tooltipSize.width)/2.f, + viewSize.height/2 - (tooltipSize.height) - 32, + tooltipSize.width, + tooltipSize.height); + } + else + mDynamicToolTipBox->setVisible(false); + } +} + +void ToolTips::enterGameMode() +{ + mGameMode = true; +} + +void ToolTips::enterGuiMode() +{ + mGameMode = false; +} + +void ToolTips::setFocusObject(const MWWorld::Ptr& focus) +{ + mFocusObject = focus; +} + +IntSize ToolTips::getToolTipViaPtr () +{ + // this the maximum width of the tooltip before it starts word-wrapping + setCoord(0, 0, 300, 300); + + IntSize tooltipSize; + + const MWWorld::Class& object = MWWorld::Class::get (mFocusObject); + if (!object.hasToolTip(mFocusObject)) + { + mDynamicToolTipBox->setVisible(false); + } + else + { + mDynamicToolTipBox->setVisible(true); + + ToolTipInfo info = object.getToolTipInfo(mFocusObject); + tooltipSize = createToolTip(info); + } + + return tooltipSize; +} + +void ToolTips::findImageExtension(std::string& image) +{ + int len = image.size(); + if (len < 4) return; + + if (!Ogre::ResourceGroupManager::getSingleton().resourceExists(Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, image)) + { + // Change texture extension to .dds + image[len-3] = 'd'; + image[len-2] = 'd'; + image[len-1] = 's'; + } +} + +IntSize ToolTips::createToolTip(const ToolTipInfo& info) +{ + std::string caption = info.caption; + std::string image = info.icon; + int imageSize = (image != "") ? 32 : 0; + std::string text = info.text; + + // remove the first newline (easier this way) + if (text.size() > 0 && text[0] == '\n') + text.erase(0, 1); + + const ESM::Enchantment* enchant; + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + if (info.enchant != "") + { + enchant = store.enchants.search(info.enchant); + if (enchant->data.type == ESM::Enchantment::CastOnce) + text += "\n" + store.gameSettings.search("sItemCastOnce")->str; + else if (enchant->data.type == ESM::Enchantment::WhenStrikes) + text += "\n" + store.gameSettings.search("sItemCastWhenStrikes")->str; + else if (enchant->data.type == ESM::Enchantment::WhenUsed) + text += "\n" + store.gameSettings.search("sItemCastWhenUsed")->str; + else if (enchant->data.type == ESM::Enchantment::ConstantEffect) + text += "\n" + store.gameSettings.search("sItemCastConstant")->str; + } + + // this the maximum width of the tooltip before it starts word-wrapping + setCoord(0, 0, 300, 300); + + const IntPoint padding(8, 8); + + const int imageCaptionHPadding = 8; + const int imageCaptionVPadding = 4; + + std::string realImage = "icons\\" + image; + findImageExtension(realImage); + + EditBox* captionWidget = mDynamicToolTipBox->createWidget("NormalText", IntCoord(0, 0, 300, 300), Align::Left | Align::Top, "ToolTipCaption"); + captionWidget->setProperty("Static", "true"); + captionWidget->setCaption(caption); + IntSize captionSize = captionWidget->getTextSize(); + + int captionHeight = std::max(captionSize.height, imageSize); + + EditBox* textWidget = mDynamicToolTipBox->createWidget("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText"); + textWidget->setProperty("Static", "true"); + textWidget->setProperty("MultiLine", "true"); + textWidget->setProperty("WordWrap", "true"); + textWidget->setCaption(text); + textWidget->setTextAlign(Align::HCenter | Align::Top); + IntSize textSize = textWidget->getTextSize(); + + captionSize += IntSize(imageSize, 0); // adjust for image + IntSize totalSize = IntSize( std::max(textSize.width, captionSize.width + ((image != "") ? imageCaptionHPadding : 0)), + ((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight ); + + if (info.effects != 0) + { + Widget* effectArea = mDynamicToolTipBox->createWidget("", + IntCoord(0, totalSize.height, 300, 300-totalSize.height), + Align::Stretch, "ToolTipEffectArea"); + + IntCoord coord(0, 6, totalSize.width, 24); + + /** + * \todo + * the various potion effects should appear in the tooltip depending if the player + * has enough skill in alchemy to know about the effects of this potion. + */ + + Widgets::MWEffectListPtr effectsWidget = effectArea->createWidget + ("MW_StatName", coord, Align::Default, "ToolTipEffectsWidget"); + effectsWidget->setWindowManager(mWindowManager); + effectsWidget->setEffectList(info.effects); + + std::vector effectItems; + effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, Widgets::MWEffectList::EF_Potion); + totalSize.height += coord.top-6; + totalSize.width = std::max(totalSize.width, coord.width); + } + + if (info.enchant != "") + { + Widget* enchantArea = mDynamicToolTipBox->createWidget("", + IntCoord(0, totalSize.height, 300, 300-totalSize.height), + Align::Stretch, "ToolTipEnchantArea"); + + IntCoord coord(0, 6, totalSize.width, 24); + + Widgets::MWEffectListPtr enchantWidget = enchantArea->createWidget + ("MW_StatName", coord, Align::Default, "ToolTipEnchantWidget"); + enchantWidget->setWindowManager(mWindowManager); + enchantWidget->setEffectList(&enchant->effects); + + std::vector enchantEffectItems; + int flag = (enchant->data.type == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0; + enchantWidget->createEffectWidgets(enchantEffectItems, enchantArea, coord, true, flag); + totalSize.height += coord.top-6; + totalSize.width = std::max(totalSize.width, coord.width); + + if (enchant->data.type == ESM::Enchantment::WhenStrikes + || enchant->data.type == ESM::Enchantment::WhenUsed) + { + /// \todo store the current enchantment charge somewhere + int charge = enchant->data.charge; + + const int chargeWidth = 204; + + TextBox* chargeText = enchantArea->createWidget("SandText", IntCoord(0, 0, 10, 18), Align::Default, "ToolTipEnchantChargeText"); + chargeText->setCaption(store.gameSettings.search("sCharges")->str); + chargeText->setProperty("Static", "true"); + const int chargeTextWidth = chargeText->getTextSize().width + 5; + + const int chargeAndTextWidth = chargeWidth + chargeTextWidth; + chargeText->setCoord((totalSize.width - chargeAndTextWidth)/2, coord.top+6, chargeTextWidth, 18); + + IntCoord chargeCoord; + if (totalSize.width < chargeWidth) + { + totalSize.width = chargeWidth; + chargeCoord = IntCoord(0, coord.top+6, chargeWidth, 18); + } + else + { + chargeCoord = IntCoord((totalSize.width - chargeAndTextWidth)/2 + chargeTextWidth, coord.top+6, chargeWidth, 18); + } + Widgets::MWDynamicStatPtr chargeWidget = enchantArea->createWidget + ("MW_ChargeBar", chargeCoord, Align::Default, "ToolTipEnchantCharge"); + chargeWidget->setValue(charge, charge); + totalSize.height += 24; + } + } + + captionWidget->setCoord( (totalSize.width - captionSize.width)/2 + imageSize, + (captionHeight-captionSize.height)/2, + captionSize.width-imageSize, + captionSize.height); + + captionWidget->setPosition (captionWidget->getPosition() + padding); + textWidget->setPosition (textWidget->getPosition() + IntPoint(0, padding.top)); // only apply vertical padding, the horizontal works automatically due to Align::HCenter + + if (image != "") + { + ImageBox* imageWidget = mDynamicToolTipBox->createWidget("ImageBox", + IntCoord((totalSize.width - captionSize.width - imageCaptionHPadding)/2, 0, imageSize, imageSize), + Align::Left | Align::Top, "ToolTipImage"); + imageWidget->setImageTexture(realImage); + imageWidget->setPosition (imageWidget->getPosition() + padding); + } + + totalSize += IntSize(padding.left*2, padding.top*2); + + return totalSize; +} + +std::string ToolTips::toString(const float value) +{ + std::ostringstream stream; + stream << std::setprecision(3) << value; + return stream.str(); +} + +std::string ToolTips::toString(const int value) +{ + std::ostringstream stream; + stream << value; + return stream.str(); +} + +std::string ToolTips::getValueString(const int value, const std::string& prefix) +{ + if (value == 0) + return ""; + else + return "\n" + prefix + ": " + toString(value); +} + +std::string ToolTips::getMiscString(const std::string& text, const std::string& prefix) +{ + if (text == "") + return ""; + else + return "\n" + prefix + ": " + text; +} + +void ToolTips::toggleFullHelp() +{ + mFullHelp = !mFullHelp; +} + +bool ToolTips::getFullHelp() const +{ + return mFullHelp; +} diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp new file mode 100644 index 0000000000..fafe471a57 --- /dev/null +++ b/apps/openmw/mwgui/tooltips.hpp @@ -0,0 +1,76 @@ + +#ifndef MWGUI_TOOLTIPS_H +#define MWGUI_TOOLTIPS_H + +#include +#include "../mwworld/ptr.hpp" + +namespace MWGui +{ + class WindowManager; + + // Info about tooltip that is supplied by the MWWorld::Class object + struct ToolTipInfo + { + public: + ToolTipInfo() : + effects(0) + { + }; + + std::string caption; + std::string text; + std::string icon; + + // enchantment (for cloth, armor, weapons) + std::string enchant; + + // effects (for potions, ingredients) + const ESM::EffectList* effects; + }; + + class ToolTips : public OEngine::GUI::Layout + { + public: + ToolTips(WindowManager* windowManager); + + void onFrame(float frameDuration); + + void enterGameMode(); + void enterGuiMode(); + + void toggleFullHelp(); ///< show extra info in item tooltips (owner, script) + bool getFullHelp() const; + + void setFocusObject(const MWWorld::Ptr& focus); + + static std::string getValueString(const int value, const std::string& prefix); + ///< @return "prefix: value" or "" if value is 0 + + static std::string getMiscString(const std::string& text, const std::string& prefix); + ///< @return "prefix: text" or "" if text is empty + + static std::string toString(const float value); + static std::string toString(const int value); + + private: + MyGUI::Widget* mDynamicToolTipBox; + + WindowManager* mWindowManager; + + MWWorld::Ptr mFocusObject; + + void findImageExtension(std::string& image); + + MyGUI::IntSize getToolTipViaPtr (); + ///< @return requested tooltip size + + MyGUI::IntSize createToolTip(const ToolTipInfo& info); + ///< @return requested tooltip size + + bool mGameMode; + + bool mFullHelp; + }; +} +#endif diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 74603aaf1c..2f5af64736 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -222,7 +222,7 @@ void MWSpell::setSpellId(const std::string &spellId) updateWidgets(); } -void MWSpell::createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord) +void MWSpell::createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags) { const ESMS::ESMStore &store = mWindowManager->getStore(); const ESM::Spell *spell = store.spells.search(id); @@ -234,9 +234,11 @@ void MWSpell::createEffectWidgets(std::vector &effects, MyGUI: { effect = creator->createWidget("MW_EffectImage", coord, MyGUI::Align::Default); effect->setWindowManager(mWindowManager); + effect->setFlags(flags); effect->setSpellEffect(*it); effects.push_back(effect); coord.top += effect->getHeight(); + coord.width = std::max(coord.width, effect->getRequestedWidth()); } } @@ -264,12 +266,82 @@ MWSpell::~MWSpell() { } +/* MWEffectList */ + +MWEffectList::MWEffectList() + : mWindowManager(nullptr) + , mEffectList(0) +{ +} + +void MWEffectList::setEffectList(const ESM::EffectList* list) +{ + mEffectList = list; + updateWidgets(); +} + +void MWEffectList::createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags) +{ + // We don't know the width of all the elements beforehand, so we do it in + // 2 steps: first, create all widgets and check their width + MWSpellEffectPtr effect = nullptr; + std::vector::const_iterator end = mEffectList->list.end(); + int maxwidth = coord.width; + for (std::vector::const_iterator it = mEffectList->list.begin(); it != end; ++it) + { + effect = creator->createWidget("MW_EffectImage", coord, MyGUI::Align::Default); + effect->setWindowManager(mWindowManager); + effect->setFlags(flags); + effect->setSpellEffect(*it); + effects.push_back(effect); + + if (effect->getRequestedWidth() > maxwidth) + maxwidth = effect->getRequestedWidth(); + + coord.top += effect->getHeight(); + } + + // then adjust the size for all widgets + for (std::vector::iterator it = effects.begin(); it != effects.end(); ++it) + { + effect = static_cast(*it); + bool needcenter = center && (maxwidth > effect->getRequestedWidth()); + int diff = maxwidth - effect->getRequestedWidth(); + if (needcenter) + { + effect->setCoord(diff/2, effect->getCoord().top, effect->getRequestedWidth(), effect->getCoord().height); + } + else + { + effect->setCoord(0, effect->getCoord().top, effect->getRequestedWidth(), effect->getCoord().height); + } + } + + // inform the parent about width + coord.width = maxwidth; +} + +void MWEffectList::updateWidgets() +{ +} + +void MWEffectList::initialiseOverride() +{ + Base::initialiseOverride(); +} + +MWEffectList::~MWEffectList() +{ +} + /* MWSpellEffect */ MWSpellEffect::MWSpellEffect() : mWindowManager(nullptr) , imageWidget(nullptr) , textWidget(nullptr) + , mRequestedWidth(0) + , mFlags(0) { } @@ -284,14 +356,32 @@ void MWSpellEffect::updateWidgets() if (!mWindowManager) return; + // lists effects that have no magnitude (e.g. invisiblity) + /// \todo this list is probably incomplete + std::vector effectsWithoutMagnitude; + effectsWithoutMagnitude.push_back("sEffectInvisibility"); + effectsWithoutMagnitude.push_back("sEffectStuntedMagicka"); + effectsWithoutMagnitude.push_back("sEffectParalyze"); + + // lists effects that have no duration (e.g. open lock) + /// \todo this list is probably incomplete + std::vector effectsWithoutDuration; + effectsWithoutDuration.push_back("sEffectOpen"); + const ESMS::ESMStore &store = mWindowManager->getStore(); const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID); if (textWidget) { if (magicEffect) { - // TODO: Get name of effect from GMST - std::string spellLine = ""; + std::string pt = mWindowManager->getGameSettingString("spoint", ""); + std::string pts = mWindowManager->getGameSettingString("spoints", ""); + std::string to = " " + mWindowManager->getGameSettingString("sTo", "") + " "; + std::string sec = " " + mWindowManager->getGameSettingString("ssecond", ""); + std::string secs = " " + mWindowManager->getGameSettingString("sseconds", ""); + + std::string effectIDStr = effectIDToString(effect.effectID); + std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, ""); if (effect.skill >= 0 && effect.skill < ESM::Skill::Length) { spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], ""); @@ -310,26 +400,42 @@ void MWSpellEffect::updateWidgets() }; spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], ""); } - if (effect.magnMin >= 0 || effect.magnMax >= 0) + + bool hasMagnitude = (std::find(effectsWithoutMagnitude.begin(), effectsWithoutMagnitude.end(), effectIDStr) == effectsWithoutMagnitude.end()); + if ((effect.magnMin >= 0 || effect.magnMax >= 0) && hasMagnitude) { if (effect.magnMin == effect.magnMax) - spellLine += " " + boost::lexical_cast(effect.magnMin) + " pts"; + spellLine += " " + boost::lexical_cast(effect.magnMin) + " " + ((effect.magnMin == 1) ? pt : pts); else { - spellLine += " " + boost::lexical_cast(effect.magnMin) + " to " + boost::lexical_cast(effect.magnMin) + " pts"; + spellLine += " " + boost::lexical_cast(effect.magnMin) + to + boost::lexical_cast(effect.magnMax) + " " + pts; } } - if (effect.duration >= 0) + + // constant effects have no duration and no target + if (!(mFlags & MWEffectList::EF_Constant)) { - spellLine += " for " + boost::lexical_cast(effect.duration) + " secs"; + bool hasDuration = (std::find(effectsWithoutDuration.begin(), effectsWithoutDuration.end(), effectIDStr) == effectsWithoutDuration.end()); + if (effect.duration >= 0 && hasDuration) + { + spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast(effect.duration) + ((effect.duration == 1) ? sec : secs); + } + + // potions have no target + if (!(mFlags & MWEffectList::EF_Potion)) + { + std::string on = mWindowManager->getGameSettingString("sonword", ""); + if (effect.range == ESM::RT_Self) + spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", ""); + else if (effect.range == ESM::RT_Touch) + spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", ""); + else if (effect.range == ESM::RT_Target) + spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", ""); + } } - if (effect.range == ESM::RT_Self) - spellLine += " on Self"; - else if (effect.range == ESM::RT_Touch) - spellLine += " on Touch"; - else if (effect.range == ESM::RT_Target) - spellLine += " on Target"; + static_cast(textWidget)->setCaption(spellLine); + mRequestedWidth = textWidget->getTextSize().width + 24; } else static_cast(textWidget)->setCaption(""); @@ -342,6 +448,153 @@ void MWSpellEffect::updateWidgets() } } +std::string MWSpellEffect::effectIDToString(const short effectID) +{ + // Map effect ID to GMST name + // http://www.uesp.net/morrow/hints/mweffects.shtml + std::map names; + names[85] ="sEffectAbsorbAttribute"; + names[88] ="sEffectAbsorbFatigue"; + names[86] ="sEffectAbsorbHealth"; + names[87] ="sEffectAbsorbSpellPoints"; + names[89] ="sEffectAbsorbSkill"; + names[63] ="sEffectAlmsiviIntervention"; + names[47] ="sEffectBlind"; + names[123] ="sEffectBoundBattleAxe"; + names[129] ="sEffectBoundBoots"; + names[127] ="sEffectBoundCuirass"; + names[120] ="sEffectBoundDagger"; + names[131] ="sEffectBoundGloves"; + names[128] ="sEffectBoundHelm"; + names[125] ="sEffectBoundLongbow"; + names[121] ="sEffectBoundLongsword"; + names[122] ="sEffectBoundMace"; + names[130] ="sEffectBoundShield"; + names[124] ="sEffectBoundSpear"; + names[7] ="sEffectBurden"; + names[50] ="sEffectCalmCreature"; + names[49] ="sEffectCalmHumanoid"; + names[40] ="sEffectChameleon"; + names[44] ="sEffectCharm"; + names[118] ="sEffectCommandCreatures"; + names[119] ="sEffectCommandHumanoids"; + names[132] ="sEffectCorpus"; // NB this typo. (bethesda made it) + names[70] ="sEffectCureBlightDisease"; + names[69] ="sEffectCureCommonDisease"; + names[71] ="sEffectCureCorprusDisease"; + names[73] ="sEffectCureParalyzation"; + names[72] ="sEffectCurePoison"; + names[22] ="sEffectDamageAttribute"; + names[25] ="sEffectDamageFatigue"; + names[23] ="sEffectDamageHealth"; + names[24] ="sEffectDamageMagicka"; + names[26] ="sEffectDamageSkill"; + names[54] ="sEffectDemoralizeCreature"; + names[53] ="sEffectDemoralizeHumanoid"; + names[64] ="sEffectDetectAnimal"; + names[65] ="sEffectDetectEnchantment"; + names[66] ="sEffectDetectKey"; + names[38] ="sEffectDisintegrateArmor"; + names[37] ="sEffectDisintegrateWeapon"; + names[57] ="sEffectDispel"; + names[62] ="sEffectDivineIntervention"; + names[17] ="sEffectDrainAttribute"; + names[20] ="sEffectDrainFatigue"; + names[18] ="sEffectDrainHealth"; + names[19] ="sEffectDrainSpellpoints"; + names[21] ="sEffectDrainSkill"; + names[8] ="sEffectFeather"; + names[14] ="sEffectFireDamage"; + names[4] ="sEffectFireShield"; + names[117] ="sEffectFortifyAttackBonus"; + names[79] ="sEffectFortifyAttribute"; + names[82] ="sEffectFortifyFatigue"; + names[80] ="sEffectFortifyHealth"; + names[81] ="sEffectFortifySpellpoints"; + names[84] ="sEffectFortifyMagickaMultiplier"; + names[83] ="sEffectFortifySkill"; + names[52] ="sEffectFrenzyCreature"; + names[51] ="sEffectFrenzyHumanoid"; + names[16] ="sEffectFrostDamage"; + names[6] ="sEffectFrostShield"; + names[39] ="sEffectInvisibility"; + names[9] ="sEffectJump"; + names[10] ="sEffectLevitate"; + names[41] ="sEffectLight"; + names[5] ="sEffectLightningShield"; + names[12] ="sEffectLock"; + names[60] ="sEffectMark"; + names[43] ="sEffectNightEye"; + names[13] ="sEffectOpen"; + names[45] ="sEffectParalyze"; + names[27] ="sEffectPoison"; + names[56] ="sEffectRallyCreature"; + names[55] ="sEffectRallyHumanoid"; + names[61] ="sEffectRecall"; + names[68] ="sEffectReflect"; + names[100] ="sEffectRemoveCurse"; + names[95] ="sEffectResistBlightDisease"; + names[94] ="sEffectResistCommonDisease"; + names[96] ="sEffectResistCorprusDisease"; + names[90] ="sEffectResistFire"; + names[91] ="sEffectResistFrost"; + names[93] ="sEffectResistMagicka"; + names[98] ="sEffectResistNormalWeapons"; + names[99] ="sEffectResistParalysis"; + names[97] ="sEffectResistPoison"; + names[92] ="sEffectResistShock"; + names[74] ="sEffectRestoreAttribute"; + names[77] ="sEffectRestoreFatigue"; + names[75] ="sEffectRestoreHealth"; + names[76] ="sEffectRestoreSpellPoints"; + names[78] ="sEffectRestoreSkill"; + names[42] ="sEffectSanctuary"; + names[3] ="sEffectShield"; + names[15] ="sEffectShockDamage"; + names[46] ="sEffectSilence"; + names[11] ="sEffectSlowFall"; + names[58] ="sEffectSoultrap"; + names[48] ="sEffectSound"; + names[67] ="sEffectSpellAbsorption"; + names[136] ="sEffectStuntedMagicka"; + names[106] ="sEffectSummonAncestralGhost"; + names[110] ="sEffectSummonBonelord"; + names[108] ="sEffectSummonLeastBonewalker"; + names[134] ="sEffectSummonCenturionSphere"; + names[103] ="sEffectSummonClannfear"; + names[104] ="sEffectSummonDaedroth"; + names[105] ="sEffectSummonDremora"; + names[114] ="sEffectSummonFlameAtronach"; + names[115] ="sEffectSummonFrostAtronach"; + names[113] ="sEffectSummonGoldenSaint"; + names[109] ="sEffectSummonGreaterBonewalker"; + names[112] ="sEffectSummonHunger"; + names[102] ="sEffectSummonScamp"; + names[107] ="sEffectSummonSkeletalMinion"; + names[116] ="sEffectSummonStormAtronach"; + names[111] ="sEffectSummonWingedTwilight"; + names[135] ="sEffectSunDamage"; + names[1] ="sEffectSwiftSwim"; + names[59] ="sEffectTelekinesis"; + names[101] ="sEffectTurnUndead"; + names[133] ="sEffectVampirism"; + names[0] ="sEffectWaterBreathing"; + names[2] ="sEffectWaterWalking"; + names[33] ="sEffectWeaknesstoBlightDisease"; + names[32] ="sEffectWeaknesstoCommonDisease"; + names[34] ="sEffectWeaknesstoCorprusDisease"; + names[28] ="sEffectWeaknesstoFire"; + names[29] ="sEffectWeaknesstoFrost"; + names[31] ="sEffectWeaknesstoMagicka"; + names[36] ="sEffectWeaknesstoNormalWeapons"; + names[35] ="sEffectWeaknesstoPoison"; + names[30] ="sEffectWeaknesstoShock"; + + assert(names.find(effectID) != names.end() && "Unimplemented effect type"); + + return names[effectID]; +} + MWSpellEffect::~MWSpellEffect() { } diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index a7916285eb..c0e62533d8 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -119,14 +119,22 @@ namespace MWGui void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } void setSpellId(const std::string &id); - void createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord); + + /** + * @param vector to store the created effect widgets + * @param parent widget + * @param coordinates to use, will be expanded if more space is needed + * @param spell category, if this is 0, this means the spell effects are permanent and won't display e.g. duration + * @param various flags, see MWEffectList::EffectFlags + */ + void createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags); const std::string &getSpellId() const { return id; } protected: virtual ~MWSpell(); - virtual void initialiseOverride(); + virtual void initialiseOverride(); private: void updateWidgets(); @@ -137,6 +145,45 @@ namespace MWGui }; typedef MWSpell* MWSpellPtr; + class MYGUI_EXPORT MWEffectList : public Widget + { + MYGUI_RTTI_DERIVED( MWEffectList ); + public: + MWEffectList(); + + typedef MWMechanics::Stat EnchantmentValue; + + enum EffectFlags + { + EF_Potion = 0x01, // potions have no target (target is always the player) + EF_Constant = 0x02 // constant effect means that duration will not be displayed + }; + + void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } + void setEffectList(const ESM::EffectList* list); + + /** + * @param vector to store the created effect widgets + * @param parent widget + * @param coordinates to use, will be expanded if more space is needed + * @param center the effect widgets horizontally + * @param various flags, see MWEffectList::EffectFlags + */ + void createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags); + + protected: + virtual ~MWEffectList(); + + virtual void initialiseOverride(); + + private: + void updateWidgets(); + + WindowManager* mWindowManager; + const ESM::EffectList* mEffectList; + }; + typedef MWEffectList* MWEffectListPtr; + class MYGUI_EXPORT MWSpellEffect : public Widget { MYGUI_RTTI_DERIVED( MWSpellEffect ); @@ -147,9 +194,14 @@ namespace MWGui void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } void setSpellEffect(SpellEffectValue value); + void setFlags(int flags) { mFlags = flags; } + + std::string effectIDToString(const short effectID); const SpellEffectValue &getSpellEffect() const { return effect; } + int getRequestedWidth() const { return mRequestedWidth; } + protected: virtual ~MWSpellEffect(); @@ -161,8 +213,10 @@ namespace MWGui WindowManager* mWindowManager; SpellEffectValue effect; + int mFlags; MyGUI::ImageBox* imageWidget; MyGUI::TextBox* textWidget; + int mRequestedWidth; }; typedef MWSpellEffect* MWSpellEffectPtr; diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 34d62ba080..0f2df53e1a 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -7,10 +7,13 @@ #include "map_window.hpp" #include "stats_window.hpp" #include "messagebox.hpp" +#include "tooltips.hpp" #include "../mwmechanics/mechanicsmanager.hpp" #include "../mwinput/inputmanager.hpp" +#include "../mwbase/environment.hpp" + #include "console.hpp" #include "journalwindow.hpp" #include "charactercreation.hpp" @@ -23,14 +26,14 @@ using namespace MWGui; -WindowManager::WindowManager(MWWorld::Environment& environment, +WindowManager::WindowManager( const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath) : mGuiManager(NULL) - , environment(environment) , hud(NULL) , map(NULL) , menu(NULL) , stats(NULL) + , mToolTips(NULL) , mMessageBoxManager(NULL) , console(NULL) , mJournal(NULL) @@ -76,15 +79,16 @@ WindowManager::WindowManager(MWWorld::Environment& environment, menu = new MainMenu(w,h); map = new MapWindow(*this); stats = new StatsWindow(*this); - console = new Console(w,h, environment, extensions); + console = new Console(w,h, extensions); mJournal = new JournalWindow(*this); mMessageBoxManager = new MessageBoxManager(this); - dialogueWindow = new DialogueWindow(*this,environment); + dialogueWindow = new DialogueWindow(*this); + mToolTips = new ToolTips(this); // The HUD is always on hud->setVisible(true); - mCharGen = new CharacterCreation(this, &environment); + mCharGen = new CharacterCreation(this); // Setup player stats for (int i = 0; i < ESM::Attribute::Length; ++i) @@ -100,6 +104,7 @@ WindowManager::WindowManager(MWWorld::Environment& environment, MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); @@ -118,6 +123,7 @@ WindowManager::~WindowManager() delete stats; delete mJournal; delete dialogueWindow; + delete mToolTips; delete mCharGen; @@ -143,7 +149,7 @@ void WindowManager::update() if (needModeChange) { needModeChange = false; - environment.mInputManager->setGuiMode(nextMode); + MWBase::Environment::get().getInputManager()->setGuiMode(nextMode); nextMode = GM_Game; } if (showFPSLevel > 0) @@ -154,11 +160,6 @@ void WindowManager::update() } } -MWWorld::Environment& WindowManager::getEnvironment() -{ - return environment; -} - void WindowManager::setNextMode(GuiMode newMode) { nextMode = newMode; @@ -167,7 +168,7 @@ void WindowManager::setNextMode(GuiMode newMode) void WindowManager::setGuiMode(GuiMode newMode) { - environment.mInputManager->setGuiMode(newMode); + MWBase::Environment::get().getInputManager()->setGuiMode(newMode); } void WindowManager::updateVisible() @@ -183,6 +184,11 @@ void WindowManager::updateVisible() // Mouse is visible whenever we're not in game mode MyGUI::PointerManager::getInstance().setVisible(isGuiMode()); + if (mode == GM_Game) + mToolTips->enterGameMode(); + else + mToolTips->enterGuiMode(); + switch(mode) { case GM_Game: // If in game mode, don't show anything. @@ -388,7 +394,7 @@ int WindowManager::readPressedButton () const std::string &WindowManager::getGameSettingString(const std::string &id, const std::string &default_) { - const ESM::GameSetting *setting = environment.mWorld->getStore().gameSettings.search(id); + const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.search(id); if (setting && setting->type == ESM::VT_String) return setting->str; return default_; @@ -408,11 +414,12 @@ void WindowManager::onDialogueWindowBye() void WindowManager::onFrame (float frameDuration) { mMessageBoxManager->onFrame(frameDuration); + mToolTips->onFrame(frameDuration); } const ESMS::ESMStore& WindowManager::getStore() const { - return environment.mWorld->getStore(); + return MWBase::Environment::get().getWorld()->getStore(); } void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) @@ -423,7 +430,10 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) if (cell->cell->name != "") name = cell->cell->name; else - name = cell->cell->region; + { + const ESM::Region* region = MWBase::Environment::get().getWorld()->getStore().regions.search(cell->cell->region); + name = region->name; + } map->setCellName( name ); @@ -482,3 +492,18 @@ int WindowManager::toggleFps() Settings::Manager::setInt("fps", "HUD", showFPSLevel); return showFPSLevel; } + +void WindowManager::setFocusObject(const MWWorld::Ptr& focus) +{ + mToolTips->setFocusObject(focus); +} + +void WindowManager::toggleFullHelp() +{ + mToolTips->toggleFullHelp(); +} + +bool WindowManager::getFullHelp() const +{ + return mToolTips->getFullHelp(); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 2b53560baf..f96660715a 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -34,7 +34,6 @@ namespace Compiler namespace MWWorld { - class Environment; class World; } @@ -62,6 +61,7 @@ namespace MWGui class Console; class JournalWindow; class CharacterCreation; + class ToolTips; class TextInputDialog; class InfoBoxDialog; @@ -83,7 +83,7 @@ namespace MWGui typedef std::vector FactionList; typedef std::vector SkillList; - WindowManager(MWWorld::Environment& environment, const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath); + WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath); virtual ~WindowManager(); void setGuiMode(GuiMode newMode); @@ -95,8 +95,6 @@ namespace MWGui */ void update(); - MWWorld::Environment& getEnvironment(); - void setMode(GuiMode newMode) { if (newMode==GM_Inventory && allowed==GW_None) @@ -157,7 +155,11 @@ namespace MWGui void setPlayerPos(const float x, const float y); ///< set player position in map space void setPlayerDir(const float x, const float y); ///< set player view direction in map space + void setFocusObject(const MWWorld::Ptr& focus); + void toggleFogOfWar(); + void toggleFullHelp(); ///< show extra info in item tooltips (owner, script) + bool getFullHelp() const; int toggleFps(); ///< toggle fps display @return resulting fps level @@ -192,10 +194,10 @@ namespace MWGui private: OEngine::GUI::MyGUIManager *mGuiManager; - MWWorld::Environment& environment; HUD *hud; MapWindow *map; MainMenu *menu; + ToolTips *mToolTips; StatsWindow *stats; MessageBoxManager *mMessageBoxManager; Console *console; diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 37eadc887a..7a56a0adf8 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -98,34 +98,36 @@ namespace MWInput void toggleSpell() { - DrawState state = player.getDrawState(); - if(state == DrawState_Weapon || state == DrawState_Nothing) - { - player.setDrawState(DrawState_Spell); - std::cout << "Player has now readied his hands for spellcasting!\n"; - } - else - { - player.setDrawState(DrawState_Nothing); - std::cout << "Player does not have any kind of attack ready now.\n"; - } + if (windows.isGuiMode()) return; + DrawState state = player.getDrawState(); + if (state == DrawState_Weapon || state == DrawState_Nothing) + { + player.setDrawState(DrawState_Spell); + std::cout << "Player has now readied his hands for spellcasting!\n"; + } + else + { + player.setDrawState(DrawState_Nothing); + std::cout << "Player does not have any kind of attack ready now.\n"; + } } void toggleWeapon() { - DrawState state = player.getDrawState(); - if(state == DrawState_Spell || state == DrawState_Nothing) - { - player.setDrawState(DrawState_Weapon); - std::cout << "Player is now drawing his weapon.\n"; - } - else - { - player.setDrawState(DrawState_Nothing); - std::cout << "Player does not have any kind of attack ready now.\n"; - } + if (windows.isGuiMode()) return; + DrawState state = player.getDrawState(); + if (state == DrawState_Spell || state == DrawState_Nothing) + { + player.setDrawState(DrawState_Weapon); + std::cout << "Player is now drawing his weapon.\n"; + } + else + { + player.setDrawState(DrawState_Nothing); + std::cout << "Player does not have any kind of attack ready now.\n"; + } } void screenshot() @@ -185,11 +187,13 @@ namespace MWInput void toggleAutoMove() { + if (windows.isGuiMode()) return; player.setAutoMove (!player.getAutoMove()); } void toggleWalking() { + if (windows.isGuiMode()) return; player.toggleRunning(); } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 7d9f748d4a..849ab8ea4c 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -19,10 +19,10 @@ namespace MWMechanics { if (!paused && ptr.getRefData().getHandle()!="player") MWWorld::Class::get (ptr).getInventoryStore (ptr).autoEquip ( - MWWorld::Class::get (ptr).getNpcStats (ptr), mEnvironment); + MWWorld::Class::get (ptr).getNpcStats (ptr)); } - Actors::Actors (MWWorld::Environment& environment) : mEnvironment (environment), mDuration (0) {} + 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 7ff33b63bd..ae93fb52ee 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -12,16 +12,10 @@ namespace Ogre class Vector3; } -namespace MWWorld -{ - class Environment; -} - namespace MWMechanics { class Actors { - MWWorld::Environment& mEnvironment; std::set mActors; float mDuration; @@ -31,7 +25,7 @@ namespace MWMechanics public: - Actors (MWWorld::Environment& environment); + Actors(); void addActor (const MWWorld::Ptr& ptr); ///< Register an actor for stats management diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index f5711e78e6..8bc408be6f 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -5,8 +5,9 @@ #include "../mwgui/window_manager.hpp" +#include "../mwbase/environment.hpp" + #include "../mwworld/class.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" #include "../mwworld/player.hpp" @@ -14,7 +15,7 @@ namespace MWMechanics { void MechanicsManager::buildPlayer() { - MWWorld::Ptr ptr = mEnvironment.mWorld->getPlayer().getPlayer(); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr); @@ -33,10 +34,10 @@ namespace MWMechanics if (mRaceSelected) { const ESM::Race *race = - mEnvironment.mWorld->getStore().races.find ( - mEnvironment.mWorld->getPlayer().getRace()); + MWBase::Environment::get().getWorld()->getStore().races.find ( + MWBase::Environment::get().getWorld()->getPlayer().getRace()); - bool male = mEnvironment.mWorld->getPlayer().isMale(); + bool male = MWBase::Environment::get().getWorld()->getPlayer().isMale(); for (int i=0; i<8; ++i) { @@ -76,11 +77,11 @@ namespace MWMechanics } // birthsign - if (!mEnvironment.mWorld->getPlayer().getBirthsign().empty()) + if (!MWBase::Environment::get().getWorld()->getPlayer().getBirthsign().empty()) { const ESM::BirthSign *sign = - mEnvironment.mWorld->getStore().birthSigns.find ( - mEnvironment.mWorld->getPlayer().getBirthsign()); + MWBase::Environment::get().getWorld()->getStore().birthSigns.find ( + MWBase::Environment::get().getWorld()->getPlayer().getBirthsign()); for (std::vector::const_iterator iter (sign->powers.list.begin()); iter!=sign->powers.list.end(); ++iter) @@ -92,7 +93,7 @@ namespace MWMechanics // class if (mClassSelected) { - const ESM::Class& class_ = mEnvironment.mWorld->getPlayer().getClass(); + const ESM::Class& class_ = MWBase::Environment::get().getWorld()->getPlayer().getClass(); for (int i=0; i<2; ++i) { @@ -121,7 +122,7 @@ namespace MWMechanics } typedef ESMS::IndexListT::MapType ContainerType; - const ContainerType& skills = mEnvironment.mWorld->getStore().skills.list; + const ContainerType& skills = MWBase::Environment::get().getWorld()->getStore().skills.list; for (ContainerType::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter) { @@ -164,7 +165,7 @@ namespace MWMechanics MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (creature).getCreatureStats (creature); - MagicEffects now = creatureStats.mSpells.getMagicEffects (mEnvironment); + MagicEffects now = creatureStats.mSpells.getMagicEffects(); /// \todo add effects from active spells and equipment @@ -175,9 +176,9 @@ namespace MWMechanics // TODO apply diff to other stats } - MechanicsManager::MechanicsManager (MWWorld::Environment& environment) - : mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false), - mRaceSelected (false), mActors (environment) + MechanicsManager::MechanicsManager() + : mUpdatePlayer (true), mClassSelected (false), + mRaceSelected (false) { buildPlayer(); } @@ -236,7 +237,7 @@ namespace MWMechanics { mWatchedCreature.mAttributes[i] = stats.mAttributes[i]; - mEnvironment.mWindowManager->setValue (attributeNames[i], stats.mAttributes[i]); + MWBase::Environment::get().getWindowManager()->setValue (attributeNames[i], stats.mAttributes[i]); } } @@ -246,7 +247,7 @@ namespace MWMechanics { mWatchedCreature.mDynamic[i] = stats.mDynamic[i]; - mEnvironment.mWindowManager->setValue (dynamicNames[i], stats.mDynamic[i]); + MWBase::Environment::get().getWindowManager()->setValue (dynamicNames[i], stats.mDynamic[i]); } } @@ -259,25 +260,25 @@ namespace MWMechanics { update = true; mWatchedNpc.mSkill[i] = npcStats.mSkill[i]; - mEnvironment.mWindowManager->setValue((ESM::Skill::SkillEnum)i, npcStats.mSkill[i]); + MWBase::Environment::get().getWindowManager()->setValue((ESM::Skill::SkillEnum)i, npcStats.mSkill[i]); } } if (update) - mEnvironment.mWindowManager->updateSkillArea(); + MWBase::Environment::get().getWindowManager()->updateSkillArea(); - mEnvironment.mWindowManager->setValue ("level", stats.mLevel); + MWBase::Environment::get().getWindowManager()->setValue ("level", stats.mLevel); } if (mUpdatePlayer) { // basic player profile; should not change anymore after the creation phase is finished. - mEnvironment.mWindowManager->setValue ("name", mEnvironment.mWorld->getPlayer().getName()); - mEnvironment.mWindowManager->setValue ("race", - mEnvironment.mWorld->getStore().races.find (mEnvironment.mWorld->getPlayer(). + MWBase::Environment::get().getWindowManager()->setValue ("name", MWBase::Environment::get().getWorld()->getPlayer().getName()); + MWBase::Environment::get().getWindowManager()->setValue ("race", + MWBase::Environment::get().getWorld()->getStore().races.find (MWBase::Environment::get().getWorld()->getPlayer(). getRace())->name); - mEnvironment.mWindowManager->setValue ("class", - mEnvironment.mWorld->getPlayer().getClass().name); + MWBase::Environment::get().getWindowManager()->setValue ("class", + MWBase::Environment::get().getWorld()->getPlayer().getClass().name); mUpdatePlayer = false; MWGui::WindowManager::SkillList majorSkills (5); @@ -285,11 +286,11 @@ namespace MWMechanics for (int i=0; i<5; ++i) { - minorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][0]; - majorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][1]; + minorSkills[i] = MWBase::Environment::get().getWorld()->getPlayer().getClass().data.skills[i][0]; + majorSkills[i] = MWBase::Environment::get().getWorld()->getPlayer().getClass().data.skills[i][1]; } - mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills); + MWBase::Environment::get().getWindowManager()->configureSkills (majorSkills, minorSkills); } mActors.update (movement, duration, paused); @@ -297,14 +298,14 @@ namespace MWMechanics void MechanicsManager::setPlayerName (const std::string& name) { - mEnvironment.mWorld->getPlayer().setName (name); + MWBase::Environment::get().getWorld()->getPlayer().setName (name); mUpdatePlayer = true; } void MechanicsManager::setPlayerRace (const std::string& race, bool male) { - mEnvironment.mWorld->getPlayer().setGender (male); - mEnvironment.mWorld->getPlayer().setRace (race); + MWBase::Environment::get().getWorld()->getPlayer().setGender (male); + MWBase::Environment::get().getWorld()->getPlayer().setRace (race); mRaceSelected = true; buildPlayer(); mUpdatePlayer = true; @@ -312,14 +313,14 @@ namespace MWMechanics void MechanicsManager::setPlayerBirthsign (const std::string& id) { - mEnvironment.mWorld->getPlayer().setBirthsign (id); + MWBase::Environment::get().getWorld()->getPlayer().setBirthsign (id); buildPlayer(); mUpdatePlayer = true; } void MechanicsManager::setPlayerClass (const std::string& id) { - mEnvironment.mWorld->getPlayer().setClass (*mEnvironment.mWorld->getStore().classes.find (id)); + MWBase::Environment::get().getWorld()->getPlayer().setClass (*MWBase::Environment::get().getWorld()->getStore().classes.find (id)); mClassSelected = true; buildPlayer(); mUpdatePlayer = true; @@ -327,7 +328,7 @@ namespace MWMechanics void MechanicsManager::setPlayerClass (const ESM::Class& class_) { - mEnvironment.mWorld->getPlayer().setClass (class_); + MWBase::Environment::get().getWorld()->getPlayer().setClass (class_); mClassSelected = true; buildPlayer(); mUpdatePlayer = true; diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index a121507ce1..a26fb98cd9 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -15,16 +15,10 @@ namespace Ogre class Vector3; } -namespace MWWorld -{ - class Environment; -} - namespace MWMechanics { class MechanicsManager { - MWWorld::Environment& mEnvironment; MWWorld::Ptr mWatched; CreatureStats mWatchedCreature; NpcStats mWatchedNpc; @@ -41,7 +35,7 @@ namespace MWMechanics public: - MechanicsManager (MWWorld::Environment& environment); + MechanicsManager (); void configureGUI(); diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 916239a840..a53c75dc22 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -3,7 +3,8 @@ #include -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" + #include "../mwworld/world.hpp" #include "magiceffects.hpp" @@ -48,13 +49,13 @@ namespace MWMechanics mSelectedSpell.clear(); } - MagicEffects Spells::getMagicEffects (const MWWorld::Environment& environment) const + MagicEffects Spells::getMagicEffects() const { MagicEffects effects; for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) { - const ESM::Spell *spell = environment.mWorld->getStore().spells.find (*iter); + const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().spells.find (*iter); if (spell->data.type==ESM::Spell::ST_Ability || spell->data.type==ESM::Spell::ST_Blight || spell->data.type==ESM::Spell::ST_Disease || spell->data.type==ESM::Spell::ST_Curse) diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index f7606c4ac2..d90f5b502d 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -9,11 +9,6 @@ namespace ESM struct Spell; } -namespace MWWorld -{ - struct Environment; -} - namespace MWMechanics { class MagicEffects; @@ -49,7 +44,7 @@ namespace MWMechanics ///< If the spell to be removed is the selected spell, the selected spell will be changed to /// no spell (empty string). - MagicEffects getMagicEffects (const MWWorld::Environment& environment) const; + MagicEffects getMagicEffects() const; ///< Return sum of magic effects resulting from abilities, blights, deseases and curses. void clear(); diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index 5034e72b32..152cf32770 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -22,10 +22,10 @@ void Actors::setMwRoot(Ogre::SceneNode* root){ } void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv){ - insertBegin(ptr, true, true); - NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mEnvironment, mRend, inv); + insertBegin(ptr, true, true); + NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mRend, inv); - mAllActors[ptr] = anim; + mAllActors[ptr] = anim; } void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){ Ogre::SceneNode* cellnode; @@ -68,7 +68,7 @@ void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){ void Actors::insertCreature (const MWWorld::Ptr& ptr){ insertBegin(ptr, true, true); - CreatureAnimation* anim = new MWRender::CreatureAnimation(ptr, mEnvironment, mRend); + CreatureAnimation* anim = new MWRender::CreatureAnimation(ptr, mRend); //mAllActors.insert(std::pair(ptr,anim)); delete mAllActors[ptr]; mAllActors[ptr] = anim; diff --git a/apps/openmw/mwrender/actors.hpp b/apps/openmw/mwrender/actors.hpp index 66c98c541c..432bcc2972 100644 --- a/apps/openmw/mwrender/actors.hpp +++ b/apps/openmw/mwrender/actors.hpp @@ -13,7 +13,6 @@ #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" -#include "../mwworld/environment.hpp" #include "npcanimation.hpp" #include "creatureanimation.hpp" #include @@ -23,13 +22,12 @@ namespace MWRender{ OEngine::Render::OgreRenderer &mRend; std::map mCellSceneNodes; Ogre::SceneNode* mMwRoot; - MWWorld::Environment& mEnvironment; std::map mAllActors; public: - Actors(OEngine::Render::OgreRenderer& _rend, MWWorld::Environment& _env): mRend(_rend), mEnvironment(_env){} + Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {} ~Actors(); void setMwRoot(Ogre::SceneNode* root); void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 5755418e2d..fc62582082 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -4,10 +4,9 @@ namespace MWRender{ std::map Animation::mUniqueIDs; - Animation::Animation(MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend) + Animation::Animation(OEngine::Render::OgreRenderer& _rend) : insert(NULL) , mRend(_rend) - , mEnvironment(_env) , vecRotPos() , time(0.0f) , startTime(0.0f) @@ -428,7 +427,7 @@ namespace MWRender{ //base->_updateAnimation(); //base->_notifyMoved(); - + std::vector::iterator iter; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 98f0e74879..4ab60cff4b 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -5,7 +5,6 @@ #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" -#include "../mwworld/environment.hpp" #include #include #include @@ -21,16 +20,15 @@ struct PosAndRot{ }; class Animation{ - + protected: Ogre::SceneNode* insert; OEngine::Render::OgreRenderer &mRend; - MWWorld::Environment& mEnvironment; std::map vecRotPos; static std::map mUniqueIDs; - - - + + + float time; @@ -41,14 +39,14 @@ class Animation{ std::vectorrindexI; //Represents a translation index for each bone std::vectortindexI; - + //Only shapes with morphing data will use a shape number int shapeNumber; std::vector > shapeIndexI; //Ogre::SkeletonInstance* skel; std::vector* shapes; //All the NiTriShapeData for a creature - + std::vector* transformations; @@ -58,16 +56,16 @@ class Animation{ void handleAnimationTransforms(); bool timeIndex( float time, const std::vector & times, int & i, int & j, float & x ); std::string getUniqueID(std::string mesh); - + public: - Animation(MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend); + Animation(OEngine::Render::OgreRenderer& _rend); virtual void runAnimation(float timepassed) = 0; void startScript(std::string groupname, int mode, int loops); void stopScript(); virtual ~Animation(); - + }; } #endif diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index e0eb5ccc20..9ca3ed7319 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -10,7 +10,7 @@ namespace MWRender{ CreatureAnimation::~CreatureAnimation(){ } -CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){ +CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend): Animation(_rend){ insert = ptr.getRefData().getBaseNode(); ESMS::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwrender/creatureanimation.hpp b/apps/openmw/mwrender/creatureanimation.hpp index 2229eeec98..f50b7904b7 100644 --- a/apps/openmw/mwrender/creatureanimation.hpp +++ b/apps/openmw/mwrender/creatureanimation.hpp @@ -7,20 +7,19 @@ #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" -#include "../mwworld/environment.hpp" #include "components/nifogre/ogre_nif_loader.hpp" namespace MWRender{ class CreatureAnimation: public Animation{ - + public: virtual ~CreatureAnimation(); - CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend); + CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend); virtual void runAnimation(float timepassed); - + }; } -#endif \ No newline at end of file +#endif diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index d426721795..be8afbae65 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -8,7 +8,7 @@ #include #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" #include "../mwworld/ptr.hpp" #include #include @@ -138,8 +138,8 @@ ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid) return result; } -Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) : - mMwRoot(mwRoot), mEnvironment(env), mEngine(engine), +Debugging::Debugging(SceneNode *mwRoot, OEngine::Physic::PhysicEngine *engine) : + mMwRoot(mwRoot), mEngine(engine), mSceneMgr(mwRoot->getCreator()), mPathgridEnabled(false), mInteriorPathgridNode(NULL), mPathGridRoot(NULL), @@ -218,7 +218,7 @@ void Debugging::togglePathgrid() void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) { - ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell); + ESM::Pathgrid *pathgrid = MWBase::Environment::get().getWorld()->getStore().pathgrids.search(*store->cell); if (!pathgrid) return; Vector3 cellPathGridPos(0, 0, 0); diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index ebf3884dcc..e12c0647c6 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -23,7 +23,6 @@ namespace Ogre namespace MWWorld { class World; - class Environment; } namespace MWRender @@ -34,7 +33,6 @@ namespace MWRender { OEngine::Physic::PhysicEngine* mEngine; Ogre::SceneManager *mSceneMgr; - MWWorld::Environment& mEnvironment; // Path grid stuff bool mPathgridEnabled; @@ -68,7 +66,7 @@ namespace MWRender Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid); Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid); public: - Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine); + Debugging(Ogre::SceneNode* mwRoot, OEngine::Physic::PhysicEngine *engine); ~Debugging(); bool toggleRenderMode (int mode); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 2cc233a011..ea89024433 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -1,7 +1,7 @@ #include "localmap.hpp" #include "renderingmanager.hpp" -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" #include "../mwworld/world.hpp" #include "../mwgui/window_manager.hpp" #include "renderconst.hpp" @@ -12,12 +12,11 @@ using namespace MWRender; using namespace Ogre; -LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering, MWWorld::Environment* env) : +LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering) : mInterior(false), mCellX(0), mCellY(0) { mRendering = rend; mRenderingManager = rendering; - mEnvironment = env; mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); mCameraRotNode = mCameraPosNode->createChildSceneNode(); @@ -54,12 +53,12 @@ void LocalMap::saveTexture(const std::string& texname, const std::string& filena if (tex.isNull()) return; HardwarePixelBufferSharedPtr readbuffer = tex->getBuffer(); readbuffer->lock(HardwareBuffer::HBL_NORMAL ); - const PixelBox &readrefpb = readbuffer->getCurrentLock(); - uchar *readrefdata = static_cast(readrefpb.data); + const PixelBox &readrefpb = readbuffer->getCurrentLock(); + uchar *readrefdata = static_cast(readrefpb.data); Image img; img = img.loadDynamicImage (readrefdata, tex->getWidth(), - tex->getHeight(), tex->getFormat()); + tex->getHeight(), tex->getFormat()); img.save("./" + filename); readbuffer->unlock(); @@ -82,7 +81,7 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell) Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); Vector2 length = max-min; - + // divide into segments const int segsX = std::ceil( length.x / sSize ); const int segsY = std::ceil( length.y / sSize ); @@ -123,7 +122,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y); - const Vector2& north = mEnvironment->mWorld->getNorthVector(cell); + const Vector2& north = MWBase::Environment::get().getWorld()->getNorthVector(cell); Radian angle(std::atan2(-north.x, -north.y)); mAngle = angle.valueRadians(); mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0)); @@ -213,7 +212,7 @@ void LocalMap::render(const float x, const float y, texture, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - xw*sMapResolution/sSize, yw*sMapResolution/sSize, + xw*sMapResolution/sSize, yw*sMapResolution/sSize, 0, PF_R8G8B8, TU_RENDERTARGET); @@ -236,7 +235,7 @@ void LocalMap::render(const float x, const float y, texture + "_fog", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize, + xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize, 0, PF_A8R8G8B8, TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); @@ -276,7 +275,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni return; } - // retrieve the x,y grid coordinates the player is in + // retrieve the x,y grid coordinates the player is in int x,y; Vector3 _pos(position.x, 0, position.z); Vector2 pos(_pos.x, _pos.z); @@ -303,7 +302,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni x = std::ceil((pos.x - min.x)/sSize)-1; y = std::ceil((pos.y - min.y)/sSize)-1; - mEnvironment->mWindowManager->setInteriorMapTexture(x,y); + MWBase::Environment::get().getWindowManager()->setInteriorMapTexture(x,y); } // convert from world coordinates to texture UV coordinates @@ -323,8 +322,8 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni texName = mInteriorName + "_" + coordStr(x,y); } - mEnvironment->mWindowManager->setPlayerPos(u, v); - mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z); + MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v); + MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, -playerdirection.z); // explore radius (squared) const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 95685167c3..9e03988f38 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -5,11 +5,6 @@ #include -namespace MWWorld -{ - class Environment; -} - namespace MWRender { class RenderingManager; @@ -20,7 +15,7 @@ namespace MWRender class LocalMap { public: - LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering, MWWorld::Environment* env); + LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering); ~LocalMap(); /** @@ -61,7 +56,6 @@ namespace MWRender private: OEngine::Render::OgreRenderer* mRendering; MWRender::RenderingManager* mRenderingManager; - MWWorld::Environment* mEnvironment; // 1024*1024 pixels for a cell static const int sMapResolution = 1024; diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 751a075481..c35fff1cee 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -2,7 +2,7 @@ #include "../mwworld/world.hpp" #include "renderconst.hpp" - +#include "../mwbase/environment.hpp" using namespace Ogre; using namespace NifOgre; @@ -12,7 +12,7 @@ NpcAnimation::~NpcAnimation(){ } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_rend), mStateID(-1), inv(_inv), timeToChange(0), robe(inv.end()), helmet(inv.end()), shirt(inv.end()), cuirass(inv.end()), greaves(inv.end()), leftpauldron(inv.end()), rightpauldron(inv.end()), @@ -77,14 +77,14 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O std::string hairID = ref->base->hair; std::string headID = ref->base->head; headModel = "meshes\\" + - mEnvironment.mWorld->getStore().bodyParts.find(headID)->model; + MWBase::Environment::get().getWorld()->getStore().bodyParts.find(headID)->model; hairModel = "meshes\\" + - mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; + MWBase::Environment::get().getWorld()->getStore().bodyParts.find(hairID)->model; npcName = ref->base->name; //ESMStore::Races r = - const ESM::Race* race = mEnvironment.mWorld->getStore().races.find(ref->base->race); + const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().races.find(ref->base->race); bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); @@ -159,7 +159,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); else insert->scale(race->data.height.male, race->data.height.male, race->data.height.male); - std::cout << "Inv" << inv.getStateId() << "\n"; updateParts(); } @@ -370,116 +369,116 @@ void NpcAnimation::updateParts(){ addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1,hairModel); } if(partpriorities[ESM::PRT_Neck] < 1){ - const ESM::BodyPart *neckPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "neck"); + const ESM::BodyPart *neckPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "neck"); if(neckPart) addOrReplaceIndividualPart(ESM::PRT_Neck, -1,1,"meshes\\" + neckPart->model); } if(partpriorities[ESM::PRT_Cuirass] < 1){ - const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); + const ESM::BodyPart *chestPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "chest"); if(chestPart) addOrReplaceIndividualPart(ESM::PRT_Cuirass, -1,1,"meshes\\" + chestPart->model); } if(partpriorities[ESM::PRT_Groin] < 1){ - const ESM::BodyPart *groinPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin"); + const ESM::BodyPart *groinPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "groin"); if(groinPart) addOrReplaceIndividualPart(ESM::PRT_Groin, -1,1,"meshes\\" + groinPart->model); } if(partpriorities[ESM::PRT_RHand] < 1){ - const ESM::BodyPart *handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); + const ESM::BodyPart *handPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "hand"); if(!handPart) - handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); + handPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "hands"); if(handPart) addOrReplaceIndividualPart(ESM::PRT_RHand, -1,1,"meshes\\" + handPart->model); } if(partpriorities[ESM::PRT_LHand] < 1){ - const ESM::BodyPart *handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); + const ESM::BodyPart *handPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "hand"); if(!handPart) - handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); + handPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "hands"); if(handPart) addOrReplaceIndividualPart(ESM::PRT_LHand, -1,1,"meshes\\" + handPart->model); } if(partpriorities[ESM::PRT_RWrist] < 1){ - const ESM::BodyPart *wristPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); + const ESM::BodyPart *wristPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "wrist"); if(wristPart) addOrReplaceIndividualPart(ESM::PRT_RWrist, -1,1,"meshes\\" + wristPart->model); } if(partpriorities[ESM::PRT_LWrist] < 1){ - const ESM::BodyPart *wristPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); + const ESM::BodyPart *wristPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "wrist"); if(wristPart) addOrReplaceIndividualPart(ESM::PRT_LWrist, -1,1,"meshes\\" + wristPart->model); } if(partpriorities[ESM::PRT_RForearm] < 1){ - const ESM::BodyPart *forearmPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); + const ESM::BodyPart *forearmPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "forearm"); if(bodyRaceID == "b_n_argonian_f_") - forearmPart = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); + forearmPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search ("b_n_argonian_m_forearm"); if(forearmPart) addOrReplaceIndividualPart(ESM::PRT_RForearm, -1,1,"meshes\\" + forearmPart->model); } if(partpriorities[ESM::PRT_LForearm] < 1){ - const ESM::BodyPart *forearmPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); + const ESM::BodyPart *forearmPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "forearm"); if(bodyRaceID == "b_n_argonian_f_") - forearmPart = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); + forearmPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search ("b_n_argonian_m_forearm"); if(forearmPart) addOrReplaceIndividualPart(ESM::PRT_LForearm, -1,1,"meshes\\" + forearmPart->model); } if(partpriorities[ESM::PRT_RUpperarm] < 1){ - const ESM::BodyPart *armPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); + const ESM::BodyPart *armPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "upper arm"); if(armPart) addOrReplaceIndividualPart(ESM::PRT_RUpperarm, -1,1,"meshes\\" + armPart->model); } if(partpriorities[ESM::PRT_LUpperarm] < 1){ - const ESM::BodyPart *armPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); + const ESM::BodyPart *armPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "upper arm"); if(armPart) addOrReplaceIndividualPart(ESM::PRT_LUpperarm, -1,1,"meshes\\" + armPart->model); } if(partpriorities[ESM::PRT_RFoot] < 1){ - const ESM::BodyPart *footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + const ESM::BodyPart *footPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "foot"); if(isBeast && !footPart) - footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + footPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "feet"); if(footPart) addOrReplaceIndividualPart(ESM::PRT_RFoot, -1,1,"meshes\\" + footPart->model); } if(partpriorities[ESM::PRT_LFoot] < 1){ - const ESM::BodyPart *footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + const ESM::BodyPart *footPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "foot"); if(isBeast && !footPart) - footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + footPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "feet"); if(footPart) addOrReplaceIndividualPart(ESM::PRT_LFoot, -1,1,"meshes\\" + footPart->model); } if(partpriorities[ESM::PRT_RAnkle] < 1){ - const ESM::BodyPart *anklePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); + const ESM::BodyPart *anklePart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "ankle"); if(anklePart) addOrReplaceIndividualPart(ESM::PRT_RAnkle, -1,1,"meshes\\" + anklePart->model); } if(partpriorities[ESM::PRT_LAnkle] < 1){ - const ESM::BodyPart *anklePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); + const ESM::BodyPart *anklePart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "ankle"); if(anklePart) addOrReplaceIndividualPart(ESM::PRT_LAnkle, -1,1,"meshes\\" + anklePart->model); } if(partpriorities[ESM::PRT_RKnee] < 1){ - const ESM::BodyPart *kneePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); + const ESM::BodyPart *kneePart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "knee"); if(kneePart) addOrReplaceIndividualPart(ESM::PRT_RKnee, -1,1,"meshes\\" + kneePart->model); } if(partpriorities[ESM::PRT_LKnee] < 1){ - const ESM::BodyPart *kneePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); + const ESM::BodyPart *kneePart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "knee"); if(kneePart) addOrReplaceIndividualPart(ESM::PRT_LKnee, -1,1,"meshes\\" + kneePart->model); } if(partpriorities[ESM::PRT_RLeg] < 1){ - const ESM::BodyPart *legPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); + const ESM::BodyPart *legPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "upper leg"); if(legPart) addOrReplaceIndividualPart(ESM::PRT_RLeg, -1,1,"meshes\\" + legPart->model); } if(partpriorities[ESM::PRT_LLeg] < 1){ - const ESM::BodyPart *legPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); + const ESM::BodyPart *legPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "upper leg"); if(legPart) addOrReplaceIndividualPart(ESM::PRT_LLeg, -1,1,"meshes\\" + legPart->model); } if(partpriorities[ESM::PRT_Tail] < 1){ - const ESM::BodyPart *tailPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); + const ESM::BodyPart *tailPart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (bodyRaceID + "tail"); if(tailPart) addOrReplaceIndividualPart(ESM::PRT_Tail, -1,1,"meshes\\" + tailPart->model); } @@ -848,9 +847,9 @@ void NpcAnimation::removeIndividualPart(int type){ const ESM::BodyPart *bodypart = 0; if(isFemale) - bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.female); + bodypart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (part.female); if(!bodypart) - bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); + bodypart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search (part.male); if(bodypart){ addOrReplaceIndividualPart(part.part, group,priority,"meshes\\" + bodypart->model); } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 352b54beca..a37becc26d 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -10,7 +10,6 @@ #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" -#include "../mwworld/environment.hpp" #include "components/nifogre/ogre_nif_loader.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwclass/npc.hpp" @@ -36,8 +35,8 @@ private: int partpriorities[27]; std::pair*> zero; - - + + //Bounded Parts Ogre::Entity* lclavicle; Ogre::Entity* rclavicle; @@ -59,7 +58,7 @@ private: Ogre::Entity* rfoot; Ogre::Entity* hair; Ogre::Entity* head; - + Ogre::SceneNode* insert; bool isBeast; bool isFemale; @@ -80,9 +79,9 @@ private: MWWorld::ContainerStoreIterator leftglove; MWWorld::ContainerStoreIterator rightglove; MWWorld::ContainerStoreIterator skirtiter; - + public: - NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); + NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); virtual ~NpcAnimation(); Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); std::pair*> insertFreePart(const std::string &mesh, const std::string suffix); @@ -91,12 +90,12 @@ private: void updateParts(); void removeIndividualPart(int type); void reserveIndividualPart(int type, int group, int priority); - + bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); void removePartGroup(int group); void addPartGroup(int group, int priority, std::vector& parts); - + }; } -#endif \ No newline at end of file +#endif diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 5cd013fcf1..27c3f818e8 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -8,20 +8,15 @@ using namespace MWRender; -bool Objects::lightConst = false; -float Objects::lightConstValue = 0.0f; - -bool Objects::lightLinear = true; -int Objects::lightLinearMethod = 1; +// These are the Morrowind.ini defaults float Objects::lightLinearValue = 3; float Objects::lightLinearRadiusMult = 1; -bool Objects::lightQuadratic = false; -int Objects::lightQuadraticMethod = 2; float Objects::lightQuadraticValue = 16; float Objects::lightQuadraticRadiusMult = 1; -bool Objects::lightOutQuadInLin = false; +bool Objects::lightOutQuadInLin = true; +bool Objects::lightQuadratic = false; int Objects::uniqueID = 0; @@ -134,7 +129,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) } } - if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects")) + if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent) { insert->attachObject(ent); @@ -146,18 +141,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) { Ogre::StaticGeometry* sg = 0; -/* if (transparent) - { - if( mStaticGeometryAlpha.find(ptr.getCell()) == mStaticGeometryAlpha.end()) - { - uniqueID = uniqueID +1; - sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); - mStaticGeometryAlpha[ptr.getCell()] = sg; - } - else - sg = mStaticGeometryAlpha[ptr.getCell()]; - } - else*/ if (small) + if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { @@ -209,35 +193,61 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f assert(insert); Ogre::Light *light = mRenderer.getScene()->createLight(); light->setDiffuseColour (r, g, b); - mLights.push_back(light->getName()); - float cval=0.0f, lval=0.0f, qval=0.0f; + ESMS::LiveCellRef *ref = + ptr.get(); - if(lightConst) - cval = lightConstValue; + LightInfo info; + info.name = light->getName(); + info.radius = radius; + info.colour = Ogre::ColourValue(r, g, b); - if(!lightOutQuadInLin) + if (ref->base->data.flags & ESM::Light::Negative) + info.colour *= -1; + + info.interior = (ptr.getCell()->cell->data.flags & ESM::Cell::Interior); + + if (ref->base->data.flags & ESM::Light::Flicker) + info.type = LT_Flicker; + else if (ref->base->data.flags & ESM::Light::FlickerSlow) + info.type = LT_FlickerSlow; + else if (ref->base->data.flags & ESM::Light::Pulse) + info.type = LT_Pulse; + else if (ref->base->data.flags & ESM::Light::PulseSlow) + info.type = LT_PulseSlow; + else + info.type = LT_Normal; + + // random starting phase for the animation + info.time = Ogre::Math::RangeRandom(0, 2 * M_PI); + + // adjust the lights depending if we're in an interior or exterior cell + // quadratic means the light intensity falls off quite fast, resulting in a + // dark, atmospheric environment (perfect for exteriors) + // for interiors, we want more "warm" lights, so use linear attenuation. + bool quadratic = false; + if (!lightOutQuadInLin) + quadratic = lightQuadratic; + else { - if(lightLinear) - radius *= lightLinearRadiusMult; - if(lightQuadratic) - radius *= lightQuadraticRadiusMult; + quadratic = !info.interior; + } - if(lightLinear) - lval = lightLinearValue / pow(radius, lightLinearMethod); - if(lightQuadratic) - qval = lightQuadraticValue / pow(radius, lightQuadraticMethod); + if (!quadratic) + { + float r = radius * lightLinearRadiusMult; + float attenuation = lightLinearValue / r; + light->setAttenuation(r*10, 0, attenuation, 0); } else { - // FIXME: - // Do quadratic or linear, depending if we're in an exterior or interior - // cell, respectively. Ignore lightLinear and lightQuadratic. + float r = radius * lightQuadraticRadiusMult; + float attenuation = lightQuadraticValue / pow(r, 2); + light->setAttenuation(r*10, 0, 0, attenuation); } - light->setAttenuation(10*radius, cval, lval, qval); - insert->attachObject(light); + mLights.push_back(info); } bool Objects::deleteObject (const MWWorld::Ptr& ptr) @@ -292,13 +302,6 @@ void Objects::removeCell(MWWorld::Ptr::CellStore* store) mRenderer.getScene()->destroyStaticGeometry (sg); sg = 0; } - /*if(mStaticGeometryAlpha.find(store) != mStaticGeometryAlpha.end()) - { - Ogre::StaticGeometry* sg = mStaticGeometryAlpha[store]; - mStaticGeometryAlpha.erase(store); - mRenderer.getScene()->destroyStaticGeometry (sg); - sg = 0; - }*/ if(mBounds.find(store) != mBounds.end()) mBounds.erase(store); @@ -316,11 +319,6 @@ void Objects::buildStaticGeometry(ESMS::CellStore& cell) Ogre::StaticGeometry* sg = mStaticGeometrySmall[&cell]; sg->build(); } - /*if(mStaticGeometryAlpha.find(&cell) != mStaticGeometryAlpha.end()) - { - Ogre::StaticGeometry* sg = mStaticGeometryAlpha[&cell]; - sg->build(); - }*/ } Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell) @@ -330,12 +328,12 @@ Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell) void Objects::enableLights() { - std::vector::iterator it = mLights.begin(); + std::vector::iterator it = mLights.begin(); while (it != mLights.end()) { - if (mMwRoot->getCreator()->hasLight(*it)) + if (mMwRoot->getCreator()->hasLight(it->name)) { - mMwRoot->getCreator()->getLight(*it)->setVisible(true); + mMwRoot->getCreator()->getLight(it->name)->setVisible(true); ++it; } else @@ -345,12 +343,12 @@ void Objects::enableLights() void Objects::disableLights() { - std::vector::iterator it = mLights.begin(); + std::vector::iterator it = mLights.begin(); while (it != mLights.end()) { - if (mMwRoot->getCreator()->hasLight(*it)) + if (mMwRoot->getCreator()->hasLight(it->name)) { - mMwRoot->getCreator()->getLight(*it)->setVisible(false); + mMwRoot->getCreator()->getLight(it->name)->setVisible(false); ++it; } else @@ -358,3 +356,90 @@ void Objects::disableLights() } } +void Objects::update(const float dt) +{ + std::vector::iterator it = mLights.begin(); + while (it != mLights.end()) + { + if (mMwRoot->getCreator()->hasLight(it->name)) + { + Ogre::Light* light = mMwRoot->getCreator()->getLight(it->name); + + // Light animation (pulse & flicker) + it->time += dt; + const float phase = std::fmod(static_cast (it->time), (32 * 2 * M_PI)) * 20; + float pulseConstant; + + // These formulas are just guesswork, but they work pretty well + if (it->type == LT_Normal) + { + // Less than 1/255 light modifier for a constant light: + pulseConstant = (const float)(1.0 + sin(phase) / 255.0 ); + } + else if (it->type == LT_Flicker) + { + // Let's do a 50% -> 100% sine wave pulse over 1 second: + // This is 75% +/- 25% + pulseConstant = (const float)(0.75 + sin(phase) * 0.25); + + // Then add a 25% flicker variation: + it->resetTime -= dt; + if (it->resetTime < 0) + { + it->flickerVariation = (rand() % 1000) / 1000 * 0.25; + it->resetTime = 0.5; + } + if (it->resetTime > 0.25) + { + pulseConstant = (pulseConstant+it->flickerVariation) * (1-it->resetTime * 2.0f) + pulseConstant * it->resetTime * 2.0f; + } + else + { + pulseConstant = (pulseConstant+it->flickerVariation) * (it->resetTime * 2.0f) + pulseConstant * (1-it->resetTime * 2.0f); + } + } + else if (it->type == LT_FlickerSlow) + { + // Let's do a 50% -> 100% sine wave pulse over 1 second: + // This is 75% +/- 25% + pulseConstant = (const float)(0.75 + sin(phase / 4.0) * 0.25); + + // Then add a 25% flicker variation: + it->resetTime -= dt; + if (it->resetTime < 0) + { + it->flickerVariation = (rand() % 1000) / 1000 * 0.25; + it->resetTime = 0.5; + } + if (it->resetTime > 0.5) + { + pulseConstant = (pulseConstant+it->flickerVariation) * (1-it->resetTime) + pulseConstant * it->resetTime; + } + else + { + pulseConstant = (pulseConstant+it->flickerVariation) * (it->resetTime) + pulseConstant * (1-it->resetTime); + } + } + else if (it->type == LT_Pulse) + { + // Let's do a 75% -> 125% sine wave pulse over 1 second: + // This is 100% +/- 25% + pulseConstant = (const float)(1.0 + sin(phase) * 0.25); + } + else if (it->type == LT_PulseSlow) + { + // Let's do a 75% -> 125% sine wave pulse over 1 second: + // This is 100% +/- 25% + pulseConstant = (const float)(1.0 + sin(phase / 4.0) * 0.25); + } + else + assert(0 && "Invalid light type"); + + light->setDiffuseColour( it->colour * pulseConstant ); + + ++it; + } + else + it = mLights.erase(it); + } +} diff --git a/apps/openmw/mwrender/objects.hpp b/apps/openmw/mwrender/objects.hpp index 0c19f9f33f..fb26808b96 100644 --- a/apps/openmw/mwrender/objects.hpp +++ b/apps/openmw/mwrender/objects.hpp @@ -10,27 +10,55 @@ namespace MWRender{ +/// information about light needed for rendering +enum LightType +{ + // These are all mutually exclusive + LT_Normal=0, + LT_Flicker=1, + LT_FlickerSlow=2, + LT_Pulse=3, + LT_PulseSlow=4 +}; + +struct LightInfo +{ + // Constants + std::string name; // ogre handle + Ogre::ColourValue colour; + float radius; + bool interior; // Does this light belong to an interior or exterior cell + LightType type; + + // Runtime variables + float flickerVariation; // 25% flicker variation, reset once every 0.5 seconds + float flickerSlowVariation; // 25% flicker variation, reset once every 1.0 seconds + float resetTime; + long double time; + + + LightInfo() : + flickerVariation(0), resetTime(0.5), + flickerSlowVariation(0), time(0), interior(true) + { + } +}; + class Objects{ OEngine::Render::OgreRenderer &mRenderer; std::map mCellSceneNodes; std::map mStaticGeometry; std::map mStaticGeometrySmall; - //std::map mStaticGeometryAlpha; std::map mBounds; - std::vector mLights; + std::vector mLights; Ogre::SceneNode* mMwRoot; bool mIsStatic; static int uniqueID; - static bool lightConst; - static float lightConstValue; - static bool lightLinear; - static int lightLinearMethod; static float lightLinearValue; static float lightLinearRadiusMult; static bool lightQuadratic; - static int lightQuadraticMethod; static float lightQuadraticValue; static float lightQuadraticRadiusMult; @@ -40,7 +68,7 @@ class Objects{ ///< Remove all movable objects from \a node. public: - Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer){} + Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer) {} ~Objects(){} void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); @@ -49,6 +77,9 @@ public: void enableLights(); void disableLights(); + void update (const float dt); + ///< per-frame update + Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*); ///< get a bounding box that encloses all objects in the specified cell diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 80b804dce2..6d3f67de96 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -65,6 +65,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBQueryTotal->createBillboard(Vector3::ZERO); mBBQueryTotal->setMaterialName("QueryTotalPixels"); mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1); + mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery); mBBNodeReal->attachObject(mBBQueryTotal); mBBQueryVisible = mRendering->getScene()->createBillboardSet(1); @@ -73,6 +74,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBQueryVisible->createBillboard(Vector3::ZERO); mBBQueryVisible->setMaterialName("QueryVisiblePixels"); mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1); + mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery); mBBNodeReal->attachObject(mBBQueryVisible); mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1); @@ -82,6 +84,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBQuerySingleObject->createBillboard(Vector3::ZERO); mBBQuerySingleObject->setMaterialName("QueryVisiblePixels"); mBBQuerySingleObject->setRenderQueueGroup(RQG_OcclusionQuery); + mBBQuerySingleObject->setVisibilityFlags(RV_OcclusionQuery); mObjectNode->attachObject(mBBQuerySingleObject); mRendering->getScene()->addRenderObjectListener(this); diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index 2c7f9e9acb..c4aa093c0d 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -52,6 +52,8 @@ enum VisibilityFlags // Sun glare (not visible in reflection) RV_Glare = 128, + RV_OcclusionQuery = 256, + RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water, /// \todo markers (normally hidden) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index c1462807fc..a95a179c6c 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -24,8 +24,8 @@ using namespace Ogre; namespace MWRender { -RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment) - :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mSunEnabled(0) +RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine) + :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0) { mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); @@ -52,11 +52,16 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const // Load resources ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + // Due to the huge world size of MW, we'll want camera-relative rendering. + // This prevents precision artifacts when moving very far from the origin. + mRendering.getScene()->setCameraRelativeRendering(true); + // disable unsupported effects const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); - if (caps->getNumMultiRenderTargets() < 2) + if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects")) Settings::Manager::setBool("shader", "Water", false); - if (!caps->isShaderProfileSupported("fp40") && !caps->isShaderProfileSupported("ps_4_0")) + if ( !(caps->isShaderProfileSupported("fp40") || caps->isShaderProfileSupported("ps_4_0")) + || !Settings::Manager::getBool("shaders", "Objects")) Settings::Manager::setBool("enabled", "Shadows", false); // note that the order is important here @@ -93,19 +98,18 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mShadows = new Shadows(&mRendering); mShaderHelper = new ShaderHelper(this); - mTerrainManager = new TerrainManager(mRendering.getScene(), this, - environment); + mTerrainManager = new TerrainManager(mRendering.getScene(), this); //mSkyManager = 0; - mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera(), &environment); + mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera()); mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mSun = 0; - mDebugging = new Debugging(mMwRoot, environment, engine); - mLocalMap = new MWRender::LocalMap(&mRendering, this, &environment); + mDebugging = new Debugging(mMwRoot, engine); + mLocalMap = new MWRender::LocalMap(&mRendering, this); } RenderingManager::~RenderingManager () @@ -208,6 +212,7 @@ void RenderingManager::moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Ve void RenderingManager::update (float duration){ mActors.update (duration); + mObjects.update (duration); mOcclusionQuery->update(duration); @@ -220,6 +225,8 @@ void RenderingManager::update (float duration){ mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); checkUnderwater(); + + mWater->update(); } void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ if(store->cell->data.flags & store->cell->HasWater){ @@ -501,4 +508,14 @@ Shadows* RenderingManager::getShadows() return mShadows; } +void RenderingManager::switchToInterior() +{ + mRendering.getScene()->setCameraRelativeRendering(false); +} + +void RenderingManager::switchToExterior() +{ + mRendering.getScene()->setCameraRelativeRendering(true); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index a563d78c6a..0d11b3d57d 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -57,7 +57,7 @@ class RenderingManager: private RenderingInterface { virtual MWRender::Actors& getActors(); public: - RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment); + RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine); virtual ~RenderingManager(); @@ -117,6 +117,9 @@ class RenderingManager: private RenderingInterface { Shadows* getShadows(); + void switchToInterior(); + void switchToExterior(); + void setGlare(bool glare); void skyEnable (); void skyDisable (); diff --git a/apps/openmw/mwrender/shaderhelper.cpp b/apps/openmw/mwrender/shaderhelper.cpp index 5354251f8c..1d29be2b8d 100644 --- a/apps/openmw/mwrender/shaderhelper.cpp +++ b/apps/openmw/mwrender/shaderhelper.cpp @@ -256,9 +256,9 @@ void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool s } outStream << - " float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n" + " float3 lightingFinal = lightColour.xyz * diffuse.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n" " float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n" - " oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour.xyz, fogValue); \n" + " oColor.xyz = lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue); \n" " oColor.a = tex.a * diffuse.a * vertexColour.a; \n"; if (mrt) outStream << diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index bf5602f438..9a4ae7243c 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -66,7 +66,10 @@ void Shadows::recreate() if (split) { mPSSMSetup = new PSSMShadowCameraSetup(); - mPSSMSetup->setSplitPadding(5); + + // Make sure to keep this in sync with the camera's near clip distance! + mPSSMSetup->setSplitPadding(mRendering->getCamera()->getNearClipDistance()); + mPSSMSetup->calculateSplitPoints(3, mRendering->getCamera()->getNearClipDistance(), mShadowFar); const Real adjustFactors[3] = {64, 64, 64}; diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 859da2dc11..da2e7446ab 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -10,7 +10,7 @@ #include -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" #include "../mwworld/world.hpp" #include "renderconst.hpp" #include "renderingmanager.hpp" @@ -271,10 +271,10 @@ void Moon::setPhase(const Moon::Phase& phase) { // Colour texture Ogre::String textureName = "textures\\tx_"; - + if (mType == Moon::Type_Secunda) textureName += "secunda_"; else textureName += "masser_"; - + if (phase == Moon::Phase_New) textureName += "new"; else if (phase == Moon::Phase_WaxingCrescent) textureName += "one_wax"; else if (phase == Moon::Phase_WaxingHalf) textureName += "half_wax"; @@ -283,9 +283,9 @@ void Moon::setPhase(const Moon::Phase& phase) else if (phase == Moon::Phase_WaningHalf) textureName += "half_wan"; else if (phase == Moon::Phase_WaningGibbous) textureName += "three_wan"; else if (phase == Moon::Phase_Full) textureName += "full"; - + textureName += ".dds"; - + mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(textureName); mPhase = phase; @@ -365,9 +365,8 @@ void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType) ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock(); } -SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera, MWWorld::Environment* env) - : mEnvironment(env) - , mHour(0.0f) +SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) + : mHour(0.0f) , mDay(0) , mMonth(0) , mSun(NULL) @@ -713,7 +712,7 @@ void SkyManager::update(float duration) if (!mEnabled) return; // UV Scroll the clouds - mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", mEnvironment->mWorld->getTimeScaleFactor()/30.f); + mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f); /// \todo improve this mMasser->setPhase( static_cast( (int) ((mDay % 32)/4.f)) ); @@ -752,7 +751,7 @@ void SkyManager::update(float duration) mSecunda->setVisible(mSecundaEnabled); // rotate the stars by 360 degrees every 4 days - mAtmosphereNight->roll(Degree(mEnvironment->mWorld->getTimeScaleFactor()*duration*360 / (3600*96.f))); + mAtmosphereNight->roll(Degree(MWBase::Environment::get().getWorld()->getTimeScaleFactor()*duration*360 / (3600*96.f))); } void SkyManager::enable() diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 64d5c16a03..da89d0eb04 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -59,8 +59,8 @@ namespace MWRender Ogre::MaterialPtr mMaterial; Ogre::BillboardSet* mBBSet; }; - - + + /* * The moons need a seperate class because of their shader (which allows them to be partially transparent) */ @@ -104,11 +104,11 @@ namespace MWRender Type mType; Phase mPhase; }; - + class SkyManager { public: - SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera, MWWorld::Environment* env); + SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera); ~SkyManager(); void update(float duration); @@ -176,7 +176,6 @@ namespace MWRender private: bool mCreated; - MWWorld::Environment* mEnvironment; float mHour; int mDay; int mMonth; diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index f9b43655b7..90d853f752 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -4,6 +4,8 @@ #include "../mwworld/world.hpp" +#include "../mwbase/environment.hpp" + #include "terrainmaterial.hpp" #include "terrain.hpp" #include "renderconst.hpp" @@ -17,8 +19,8 @@ namespace MWRender //---------------------------------------------------------------------------------------------- - TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend, const MWWorld::Environment& evn) : - mEnvironment(evn), mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend) + TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) : + mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend) { TerrainMaterialGeneratorPtr matGen; @@ -107,7 +109,7 @@ namespace MWRender const int cellX = store->cell->getGridX(); const int cellY = store->cell->getGridY(); - ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY); + ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search(cellX, cellY); if ( land != NULL ) { if (!land->dataLoaded) @@ -268,7 +270,7 @@ namespace MWRender { //NB: All vtex ids are +1 compared to the ltex ids - assert( (int)mEnvironment.mWorld->getStore().landTexts.getSize() >= (int)ltexIndex - 1 && + assert( (int)MWBase::Environment::get().getWorld()->getStore().landTexts.getSize() >= (int)ltexIndex - 1 && "LAND.VTEX must be within the bounds of the LTEX array"); std::string texture; @@ -278,7 +280,7 @@ namespace MWRender } else { - texture = mEnvironment.mWorld->getStore().landTexts.search(ltexIndex-1)->texture; + texture = MWBase::Environment::get().getWorld()->getStore().landTexts.search(ltexIndex-1)->texture; //TODO this is needed due to MWs messed up texture handling texture = texture.substr(0, texture.rfind(".")) + ".dds"; } @@ -434,7 +436,7 @@ namespace MWRender } - ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY); + ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().lands.search(cellX, cellY); if ( land != NULL ) { if (!land->dataLoaded) diff --git a/apps/openmw/mwrender/terrain.hpp b/apps/openmw/mwrender/terrain.hpp index dc4a2388ce..c4ff053a6f 100644 --- a/apps/openmw/mwrender/terrain.hpp +++ b/apps/openmw/mwrender/terrain.hpp @@ -24,7 +24,7 @@ namespace MWRender{ */ class TerrainManager{ public: - TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend, const MWWorld::Environment& env); + TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend); virtual ~TerrainManager(); void setDiffuse(const Ogre::ColourValue& diffuse); @@ -36,7 +36,6 @@ namespace MWRender{ Ogre::TerrainGlobalOptions mTerrainGlobals; Ogre::TerrainGroup mTerrainGroup; - const MWWorld::Environment& mEnvironment; RenderingManager* mRendering; Ogre::TerrainMaterialGeneratorB::SM2Profile* mActiveProfile; diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 9785ec9039..a3265b2a5c 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -1149,8 +1149,8 @@ namespace Ogre // simple per-pixel lighting with no normal mapping for (int i=0; igetNumberOfLightsSupported(); ++i) { - outStream << " float3 halfAngle"< 0) outStream << diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 71cf56dfda..c81f23f548 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -11,7 +11,8 @@ namespace MWRender Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), mIsUnderwater(false), mVisibilityFlags(0), - mReflectionTarget(0), mActive(1), mToggled(1) + mReflectionTarget(0), mActive(1), mToggled(1), + mReflectionRenderActive(false) { mSky = sky; @@ -81,6 +82,8 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mUnderwaterEffect = Settings::Manager::getBool("underwater effect", "Water"); + mSceneManager->addRenderQueueListener(this); + // ---------------------------------------------------------------------------------------------- // ---------------------------------- reflection debug overlay ---------------------------------- @@ -161,6 +164,7 @@ void Water::changeCell(const ESM::Cell* cell) void Water::setHeight(const float height) { mTop = height; + mWaterPlane = Plane(Vector3::UNIT_Y, height); mWaterNode->setPosition(0, height, 0); } @@ -172,7 +176,12 @@ void Water::toggle() void Water::checkUnderwater(float y) { - if (!mActive) return; + if (!mActive) + { + CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false); + return; + } + if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID) { CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false); @@ -220,17 +229,15 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) mReflectionCamera->setFarClipDistance(mCamera->getFarClipDistance()); mReflectionCamera->setAspectRatio(mCamera->getAspectRatio()); mReflectionCamera->setFOVy(mCamera->getFOVy()); + mReflectionRenderActive = true; - // Some messy code to get the skybox to show up at all - // The problem here is that it gets clipped by the water plane - // Therefore scale it up a bit + /// \todo For some reason this camera is delayed for 1 frame, which causes ugly sky reflection behaviour.. + /// to circumvent this we just scale the sky up, so it's not that noticable Vector3 pos = mCamera->getRealPosition(); pos.y = mTop*2 - pos.y; mSky->setSkyPosition(pos); - mSky->scaleSky(mCamera->getFarClipDistance() / 1000.f); - - mReflectionCamera->enableCustomNearClipPlane(Plane(Vector3::UNIT_Y, mTop)); - mReflectionCamera->enableReflection(Plane(Vector3::UNIT_Y, mTop)); + mSky->scaleSky(mCamera->getFarClipDistance() / 5000.f); + mReflectionCamera->enableReflection(mWaterPlane); } } @@ -240,8 +247,9 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) { mSky->resetSkyPosition(); mSky->scaleSky(1); - mReflectionCamera->disableCustomNearClipPlane(); mReflectionCamera->disableReflection(); + mReflectionCamera->disableCustomNearClipPlane(); + mReflectionRenderActive = false; } } @@ -290,4 +298,27 @@ void Water::updateVisible() mReflectionTarget->setActive(mToggled && mActive && !mIsUnderwater); } +void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) +{ + // We don't want the sky to get clipped by custom near clip plane (the water plane) + if (queueGroupId < 20 && mReflectionRenderActive) + { + mReflectionCamera->disableCustomNearClipPlane(); + Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); + } +} + +void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation) +{ + if (queueGroupId < 20 && mReflectionRenderActive) + { + mReflectionCamera->enableCustomNearClipPlane(mWaterPlane); + Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); + } +} + +void Water::update() +{ +} + } // namespace diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index f14482e2b7..c8b8d311ed 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -11,7 +11,7 @@ namespace MWRender { class SkyManager; /// Water rendering - class Water : public Ogre::RenderTargetListener + class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener { static const int CELL_SIZE = 8192; Ogre::Camera *mCamera; @@ -27,11 +27,17 @@ namespace MWRender { bool mToggled; int mTop; + bool mReflectionRenderActive; + Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); protected: void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + + void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); + void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); + void updateVisible(); SkyManager* mSky; @@ -55,6 +61,7 @@ namespace MWRender { void setActive(bool active); void toggle(); + void update(); void setViewportBackground(const Ogre::ColourValue& bg); diff --git a/apps/openmw/mwscript/animationextensions.cpp b/apps/openmw/mwscript/animationextensions.cpp index 184be83db4..864a2bf1d1 100644 --- a/apps/openmw/mwscript/animationextensions.cpp +++ b/apps/openmw/mwscript/animationextensions.cpp @@ -27,10 +27,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getWorld().skipAnimation (ptr); + MWBase::Environment::get().getWorld()->skipAnimation (ptr); } }; @@ -43,9 +40,6 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - InterpreterContext& context = - static_cast (runtime.getContext()); - std::string group = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -60,7 +54,7 @@ namespace MWScript throw std::runtime_error ("animation mode out of range"); } - context.getWorld().playAnimationGroup (ptr, group, mode, 1); + MWBase::Environment::get().getWorld()->playAnimationGroup (ptr, group, mode, 1); } }; @@ -73,9 +67,6 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - InterpreterContext& context = - static_cast (runtime.getContext()); - std::string group = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -96,7 +87,7 @@ namespace MWScript throw std::runtime_error ("animation mode out of range"); } - context.getWorld().playAnimationGroup (ptr, group, mode, loops); + MWBase::Environment::get().getWorld()->playAnimationGroup (ptr, group, mode, loops); } }; diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index d69c42ab34..a5db5fd5f9 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -7,6 +7,8 @@ #include #include +#include "../mwbase/environment.hpp" + #include "../mwworld/world.hpp" #include "../mwworld/player.hpp" @@ -22,10 +24,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context - = static_cast (runtime.getContext()); - - runtime.push (context.getWorld().hasCellChanged() ? 1 : 0); + runtime.push (MWBase::Environment::get().getWorld()->hasCellChanged() ? 1 : 0); } }; @@ -35,9 +34,6 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context - = static_cast (runtime.getContext()); - std::string cell = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -45,16 +41,16 @@ namespace MWScript pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.pos[2] = 0; - if (const ESM::Cell *exterior = context.getWorld().getExterior (cell)) + if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (cell)) { - context.getWorld().indexToPosition (exterior->data.gridX, exterior->data.gridY, + MWBase::Environment::get().getWorld()->indexToPosition (exterior->data.gridX, exterior->data.gridY, pos.pos[0], pos.pos[1], true); - context.getWorld().changeToExteriorCell (pos); + MWBase::Environment::get().getWorld()->changeToExteriorCell (pos); } else { pos.pos[0] = pos.pos[1] = 0; - context.getWorld().changeToInteriorCell (cell, pos); + MWBase::Environment::get().getWorld()->changeToInteriorCell (cell, pos); } } }; @@ -65,9 +61,6 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context - = static_cast (runtime.getContext()); - Interpreter::Type_Integer x = runtime[0].mInteger; runtime.pop(); @@ -76,12 +69,12 @@ namespace MWScript ESM::Position pos; - context.getWorld().indexToPosition (x, y, pos.pos[0], pos.pos[1], true); + MWBase::Environment::get().getWorld()->indexToPosition (x, y, pos.pos[0], pos.pos[1], true); pos.pos[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; - context.getWorld().changeToExteriorCell (pos); + MWBase::Environment::get().getWorld()->changeToExteriorCell (pos); } }; @@ -91,11 +84,8 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context - = static_cast (runtime.getContext()); - bool interior = - context.getWorld().getPlayer().getPlayer().getCell()->cell->data.flags & + MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell->data.flags & ESM::Cell::Interior; runtime.push (interior ? 1 : 0); @@ -108,20 +98,17 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context - = static_cast (runtime.getContext()); - std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - const ESM::Cell *cell = context.getWorld().getPlayer().getPlayer().getCell()->cell; + const ESM::Cell *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell; std::string current = cell->name; if (!(cell->data.flags & ESM::Cell::Interior) && current.empty()) { const ESM::Region *region = - context.getWorld().getStore().regions.find (cell->region); + MWBase::Environment::get().getWorld()->getStore().regions.find (cell->region); current = region->name; } @@ -139,10 +126,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context - = static_cast (runtime.getContext()); - - MWWorld::Ptr::CellStore *cell = context.getWorld().getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); runtime.push (cell->mWaterLevel); } }; @@ -153,18 +137,15 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context - = static_cast (runtime.getContext()); - Interpreter::Type_Float level = runtime[0].mFloat; - MWWorld::Ptr::CellStore *cell = context.getWorld().getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); if (!(cell->cell->data.flags & ESM::Cell::Interior)) throw std::runtime_error("Can't set water level in exterior cell"); cell->mWaterLevel = level; - context.getEnvironment().mWorld->setWaterHeight(cell->mWaterLevel); + MWBase::Environment::get().getWorld()->setWaterHeight(cell->mWaterLevel); } }; @@ -174,18 +155,15 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context - = static_cast (runtime.getContext()); - Interpreter::Type_Float level = runtime[0].mFloat; - MWWorld::Ptr::CellStore *cell = context.getWorld().getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); if (!(cell->cell->data.flags & ESM::Cell::Interior)) throw std::runtime_error("Can't set water level in exterior cell"); - + cell->mWaterLevel +=level; - context.getEnvironment().mWorld->setWaterHeight(cell->mWaterLevel); + MWBase::Environment::get().getWorld()->setWaterHeight(cell->mWaterLevel); } }; diff --git a/apps/openmw/mwscript/compilercontext.cpp b/apps/openmw/mwscript/compilercontext.cpp index 15cc599a7f..078d0da5e7 100644 --- a/apps/openmw/mwscript/compilercontext.cpp +++ b/apps/openmw/mwscript/compilercontext.cpp @@ -1,48 +1,48 @@ #include "compilercontext.hpp" -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" + #include "../mwworld/world.hpp" namespace MWScript { - CompilerContext::CompilerContext (Type type, const MWWorld::Environment& environment) - : mType (type), mEnvironment (environment) + CompilerContext::CompilerContext (Type type) + : mType (type) {} bool CompilerContext::canDeclareLocals() const { return mType==Type_Full; - } - + } + char CompilerContext::getGlobalType (const std::string& name) const { - return mEnvironment.mWorld->getGlobalVariableType (name); - } - + return MWBase::Environment::get().getWorld()->getGlobalVariableType (name); + } + bool CompilerContext::isId (const std::string& name) const { return - mEnvironment.mWorld->getStore().activators.search (name) || - mEnvironment.mWorld->getStore().potions.search (name) || - mEnvironment.mWorld->getStore().appas.search (name) || - mEnvironment.mWorld->getStore().armors.search (name) || - mEnvironment.mWorld->getStore().books.search (name) || - mEnvironment.mWorld->getStore().clothes.search (name) || - mEnvironment.mWorld->getStore().containers.search (name) || - mEnvironment.mWorld->getStore().creatures.search (name) || - mEnvironment.mWorld->getStore().doors.search (name) || - mEnvironment.mWorld->getStore().ingreds.search (name) || - mEnvironment.mWorld->getStore().creatureLists.search (name) || - mEnvironment.mWorld->getStore().itemLists.search (name) || - mEnvironment.mWorld->getStore().lights.search (name) || - mEnvironment.mWorld->getStore().lockpicks.search (name) || - mEnvironment.mWorld->getStore().miscItems.search (name) || - mEnvironment.mWorld->getStore().npcs.search (name) || - mEnvironment.mWorld->getStore().probes.search (name) || - mEnvironment.mWorld->getStore().repairs.search (name) || - mEnvironment.mWorld->getStore().statics.search (name) || - mEnvironment.mWorld->getStore().weapons.search (name); + MWBase::Environment::get().getWorld()->getStore().activators.search (name) || + MWBase::Environment::get().getWorld()->getStore().potions.search (name) || + MWBase::Environment::get().getWorld()->getStore().appas.search (name) || + MWBase::Environment::get().getWorld()->getStore().armors.search (name) || + MWBase::Environment::get().getWorld()->getStore().books.search (name) || + MWBase::Environment::get().getWorld()->getStore().clothes.search (name) || + MWBase::Environment::get().getWorld()->getStore().containers.search (name) || + MWBase::Environment::get().getWorld()->getStore().creatures.search (name) || + MWBase::Environment::get().getWorld()->getStore().doors.search (name) || + MWBase::Environment::get().getWorld()->getStore().ingreds.search (name) || + MWBase::Environment::get().getWorld()->getStore().creatureLists.search (name) || + MWBase::Environment::get().getWorld()->getStore().itemLists.search (name) || + MWBase::Environment::get().getWorld()->getStore().lights.search (name) || + MWBase::Environment::get().getWorld()->getStore().lockpicks.search (name) || + MWBase::Environment::get().getWorld()->getStore().miscItems.search (name) || + MWBase::Environment::get().getWorld()->getStore().npcs.search (name) || + MWBase::Environment::get().getWorld()->getStore().probes.search (name) || + MWBase::Environment::get().getWorld()->getStore().repairs.search (name) || + MWBase::Environment::get().getWorld()->getStore().statics.search (name) || + MWBase::Environment::get().getWorld()->getStore().weapons.search (name); } } - diff --git a/apps/openmw/mwscript/compilercontext.hpp b/apps/openmw/mwscript/compilercontext.hpp index 7a3411bba7..32b2f1881c 100644 --- a/apps/openmw/mwscript/compilercontext.hpp +++ b/apps/openmw/mwscript/compilercontext.hpp @@ -3,44 +3,36 @@ #include -namespace MWWorld -{ - class Environment; -} - namespace MWScript { class CompilerContext : public Compiler::Context { public: - + enum Type { Type_Full, // global, local, targetted Type_Dialgoue, Type_Console }; - + private: - + Type mType; - const MWWorld::Environment& mEnvironment; - + public: - - CompilerContext (Type type, const MWWorld::Environment& environment); - + + CompilerContext (Type type); + /// Is the compiler allowed to declare local variables? - virtual bool canDeclareLocals() const; - - /// 'l: long, 's': short, 'f': float, ' ': does not exist. + virtual bool canDeclareLocals() const; + + /// 'l: long, 's': short, 'f': float, ' ': does not exist. virtual char getGlobalType (const std::string& name) const; virtual bool isId (const std::string& name) const; - ///< Does \a name match an ID, that can be referenced? + ///< Does \a name match an ID, that can be referenced? }; } #endif - - diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index a0aba5db9a..3e8658bf85 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -9,6 +9,8 @@ #include #include +#include "../mwbase/environment.hpp" + #include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -29,9 +31,6 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string item = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -41,7 +40,7 @@ namespace MWScript if (count<0) throw std::runtime_error ("second argument for AddItem must be non-negative"); - MWWorld::ManualRef ref (context.getWorld().getStore(), item); + MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item); ref.getPtr().getRefData().setCount (count); diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index 384e13e450..363a09b6bd 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -7,6 +7,8 @@ #include #include +#include "../mwbase/environment.hpp" + #include "../mwworld/player.hpp" #include "interpretercontext.hpp" @@ -46,7 +48,7 @@ namespace MWScript InterpreterContext& context = static_cast (runtime.getContext()); - bool enabled = context.getWorld().toggleCollisionMode(); + bool enabled = MWBase::Environment::get().getWorld()->toggleCollisionMode(); context.report (enabled ? "Collision -> On" : "Collision -> Off"); } diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index fec539d3e3..b99d55999c 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -23,16 +23,13 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string quest = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); Interpreter::Type_Integer index = runtime[0].mInteger; runtime.pop(); - context.getEnvironment().mJournal->addEntry (quest, index); + MWBase::Environment::get().getJournal()->addEntry (quest, index); } }; @@ -42,16 +39,13 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string quest = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); Interpreter::Type_Integer index = runtime[0].mInteger; runtime.pop(); - context.getEnvironment().mJournal->setJournalIndex (quest, index); + MWBase::Environment::get().getJournal()->setJournalIndex (quest, index); } }; @@ -61,13 +55,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string quest = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - int index = context.getEnvironment().mJournal->getJournalIndex (quest); + int index = MWBase::Environment::get().getJournal()->getJournalIndex (quest); runtime.push (index); @@ -80,13 +71,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string topic = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - context.getEnvironment().mDialogueManager->addTopic(topic); + MWBase::Environment::get().getDialogueManager()->addTopic(topic); } }; @@ -96,9 +84,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - MWDialogue::DialogueManager* dialogue = context.getEnvironment().mDialogueManager; + MWDialogue::DialogueManager* dialogue = MWBase::Environment::get().getDialogueManager(); while(arg0>0) { std::string question = runtime.getStringLiteral (runtime[0].mInteger); @@ -124,9 +110,8 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - context.getEnvironment().mDialogueManager->startDialogue (ptr); + + MWBase::Environment::get().getDialogueManager()->startDialogue (ptr); } }; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 58960aac47..378b2412a5 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -144,4 +144,5 @@ op 0x200014d: ModDisposition op 0x200014e: ModDisposition, explicit reference op 0x200014f: ForceGreeting op 0x2000150: ForceGreeting, explicit reference -opcodes 0x2000151-0x3ffffff unused +op 0x2000151: ToggleFullHelp +opcodes 0x2000152-0x3ffffff unused diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 14930b8280..eb96ba5e2b 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -12,9 +12,9 @@ namespace MWScript : mStore (store), mScriptManager (scriptManager) { addScript ("Main"); - - for (ESMS::RecListT::MapType::const_iterator iter - (store.startScripts.list.begin()); + + for (ESMS::RecListT::MapType::const_iterator iter + (store.startScripts.list.begin()); iter != store.startScripts.list.end(); ++iter) addScript (iter->second.script); } @@ -23,15 +23,15 @@ namespace MWScript { if (mScripts.find (name)==mScripts.end()) if (const ESM::Script *script = mStore.scripts.find (name)) - { + { Locals locals; - + locals.configure (*script); - mScripts.insert (std::make_pair (name, std::make_pair (true, locals))); + mScripts.insert (std::make_pair (name, std::make_pair (true, locals))); } } - + void GlobalScripts::removeScript (const std::string& name) { std::map >::iterator iter = mScripts.find (name); @@ -39,31 +39,30 @@ namespace MWScript if (iter!=mScripts.end()) iter->second.first = false; } - + bool GlobalScripts::isRunning (const std::string& name) const { std::map >::const_iterator iter = mScripts.find (name); - + if (iter==mScripts.end()) return false; - + return iter->second.first; } - - void GlobalScripts::run (MWWorld::Environment& environment) + + void GlobalScripts::run() { for (std::map >::iterator iter (mScripts.begin()); iter!=mScripts.end(); ++iter) { if (iter->second.first) { - MWScript::InterpreterContext interpreterContext (environment, + MWScript::InterpreterContext interpreterContext ( &iter->second.second, MWWorld::Ptr()); - mScriptManager.run (iter->first, interpreterContext); + mScriptManager.run (iter->first, interpreterContext); } } } } - diff --git a/apps/openmw/mwscript/globalscripts.hpp b/apps/openmw/mwscript/globalscripts.hpp index 741968fcdc..3d62e4d7a0 100644 --- a/apps/openmw/mwscript/globalscripts.hpp +++ b/apps/openmw/mwscript/globalscripts.hpp @@ -11,11 +11,6 @@ namespace ESMS struct ESMStore; } -namespace MWWorld -{ - class Environment; -} - namespace MWScript { class ScriptManager; @@ -25,21 +20,20 @@ namespace MWScript const ESMS::ESMStore& mStore; ScriptManager& mScriptManager; std::map > mScripts; // running, local variables - + public: - + GlobalScripts (const ESMS::ESMStore& store, ScriptManager& scriptManager); - + void addScript (const std::string& name); - + void removeScript (const std::string& name); - + bool isRunning (const std::string& name) const; - - void run (MWWorld::Environment& environment); + + void run(); ///< run all active global scripts }; } #endif - diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 426378efca..c4d9e9fabb 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -7,6 +7,8 @@ #include #include +#include "../mwbase/environment.hpp" + #include "../mwgui/window_manager.hpp" #include "../mwinput/inputmanager.hpp" @@ -26,10 +28,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getWindowManager().allow (mWindow); + MWBase::Environment::get().getWindowManager()->allow (mWindow); } }; @@ -45,10 +44,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getInputManager().setGuiMode(mDialogue); + MWBase::Environment::get().getInputManager()->setGuiMode(mDialogue); } }; @@ -63,7 +59,7 @@ namespace MWScript MWWorld::Ptr ptr = context.getReference(); - runtime.push (context.getWindowManager().readPressedButton()); + runtime.push (MWBase::Environment::get().getWindowManager()->readPressedButton()); } }; @@ -73,10 +69,17 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getEnvironment().mWindowManager->toggleFogOfWar(); + MWBase::Environment::get().getWindowManager()->toggleFogOfWar(); + } + }; + + class OpToggleFullHelp : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWBase::Environment::get().getWindowManager()->toggleFullHelp(); } }; @@ -93,6 +96,7 @@ namespace MWScript const int opcodeShowRestMenu = 0x2000018; const int opcodeGetButtonPressed = 0x2000137; const int opcodeToggleFogOfWar = 0x2000145; + const int opcodeToggleFullHelp = 0x2000151; void registerExtensions (Compiler::Extensions& extensions) { @@ -101,7 +105,7 @@ namespace MWScript extensions.registerInstruction ("enablenamemenu", "", opcodeEnableNameMenu); extensions.registerInstruction ("enableracemenu", "", opcodeEnableRaceMenu); extensions.registerInstruction ("enablestatsreviewmenu", "", - opcodeEnableStatsReviewMenu); +opcodeEnableStatsReviewMenu); extensions.registerInstruction ("enableinventorymenu", "", opcodeEnableInventoryMenu); extensions.registerInstruction ("enablemagicmenu", "", opcodeEnableMagicMenu); @@ -117,6 +121,9 @@ namespace MWScript extensions.registerInstruction ("togglefogofwar", "", opcodeToggleFogOfWar); extensions.registerInstruction ("tfow", "", opcodeToggleFogOfWar); + + extensions.registerInstruction ("togglefullhelp", "", opcodeToggleFullHelp); + extensions.registerInstruction ("tfh", "", opcodeToggleFullHelp); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -154,6 +161,8 @@ namespace MWScript interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed); interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar); + + interpreter.installSegment5 (opcodeToggleFullHelp, new OpToggleFullHelp); } } } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 258493782c..a369486faf 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -7,6 +7,8 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/world.hpp" #include "../mwgui/window_manager.hpp" @@ -15,6 +17,7 @@ #include "locals.hpp" #include "globalscripts.hpp" +#include "scriptmanager.hpp" namespace MWScript { @@ -23,7 +26,7 @@ namespace MWScript { if (!id.empty()) { - return mEnvironment.mWorld->getPtr (id, activeOnly); + return MWBase::Environment::get().getWorld()->getPtr (id, activeOnly); } else { @@ -39,7 +42,7 @@ namespace MWScript { if (!id.empty()) { - return mEnvironment.mWorld->getPtr (id, activeOnly); + return MWBase::Environment::get().getWorld()->getPtr (id, activeOnly); } else { @@ -50,9 +53,9 @@ namespace MWScript } } - InterpreterContext::InterpreterContext (MWWorld::Environment& environment, + InterpreterContext::InterpreterContext ( MWScript::Locals *locals, MWWorld::Ptr reference) - : mEnvironment (environment), mLocals (locals), mReference (reference), + : mLocals (locals), mReference (reference), mActivationHandled (false) {} @@ -107,7 +110,7 @@ namespace MWScript void InterpreterContext::messageBox (const std::string& message, const std::vector& buttons) { - mEnvironment.mWindowManager->messageBox (message, buttons); + MWBase::Environment::get().getWindowManager()->messageBox (message, buttons); } void InterpreterContext::report (const std::string& message) @@ -117,74 +120,74 @@ namespace MWScript bool InterpreterContext::menuMode() { - return mEnvironment.mWindowManager->isGuiMode(); + return MWBase::Environment::get().getWindowManager()->isGuiMode(); } int InterpreterContext::getGlobalShort (const std::string& name) const { - return mEnvironment.mWorld->getGlobalVariable (name).mShort; + return MWBase::Environment::get().getWorld()->getGlobalVariable (name).mShort; } int InterpreterContext::getGlobalLong (const std::string& name) const { // a global long is internally a float. - return mEnvironment.mWorld->getGlobalVariable (name).mLong; + return MWBase::Environment::get().getWorld()->getGlobalVariable (name).mLong; } float InterpreterContext::getGlobalFloat (const std::string& name) const { - return mEnvironment.mWorld->getGlobalVariable (name).mFloat; + return MWBase::Environment::get().getWorld()->getGlobalVariable (name).mFloat; } void InterpreterContext::setGlobalShort (const std::string& name, int value) { if (name=="gamehour") - mEnvironment.mWorld->setHour (value); + MWBase::Environment::get().getWorld()->setHour (value); else if (name=="day") - mEnvironment.mWorld->setDay (value); + MWBase::Environment::get().getWorld()->setDay (value); else if (name=="month") - mEnvironment.mWorld->setMonth (value); + MWBase::Environment::get().getWorld()->setMonth (value); else - mEnvironment.mWorld->getGlobalVariable (name).mShort = value; + MWBase::Environment::get().getWorld()->getGlobalVariable (name).mShort = value; } void InterpreterContext::setGlobalLong (const std::string& name, int value) { if (name=="gamehour") - mEnvironment.mWorld->setHour (value); + MWBase::Environment::get().getWorld()->setHour (value); else if (name=="day") - mEnvironment.mWorld->setDay (value); + MWBase::Environment::get().getWorld()->setDay (value); else if (name=="month") - mEnvironment.mWorld->setMonth (value); + MWBase::Environment::get().getWorld()->setMonth (value); else - mEnvironment.mWorld->getGlobalVariable (name).mLong = value; + MWBase::Environment::get().getWorld()->getGlobalVariable (name).mLong = value; } void InterpreterContext::setGlobalFloat (const std::string& name, float value) { if (name=="gamehour") - mEnvironment.mWorld->setHour (value); + MWBase::Environment::get().getWorld()->setHour (value); else if (name=="day") - mEnvironment.mWorld->setDay (value); + MWBase::Environment::get().getWorld()->setDay (value); else if (name=="month") - mEnvironment.mWorld->setMonth (value); + MWBase::Environment::get().getWorld()->setMonth (value); else - mEnvironment.mWorld->getGlobalVariable (name).mFloat = value; + MWBase::Environment::get().getWorld()->getGlobalVariable (name).mFloat = value; } bool InterpreterContext::isScriptRunning (const std::string& name) const { - return mEnvironment.mGlobalScripts->isRunning (name); + return MWBase::Environment::get().getScriptManager()->getGlobalScripts().isRunning (name); } void InterpreterContext::startScript (const std::string& name) { - mEnvironment.mGlobalScripts->addScript (name); + MWBase::Environment::get().getScriptManager()->getGlobalScripts().addScript (name); } void InterpreterContext::stopScript (const std::string& name) { - mEnvironment.mGlobalScripts->removeScript (name); + MWBase::Environment::get().getScriptManager()->getGlobalScripts().removeScript (name); } float InterpreterContext::getDistance (const std::string& name, const std::string& id) const @@ -192,7 +195,7 @@ namespace MWScript // TODO handle exterior cells (when ref and ref2 are located in different cells) const MWWorld::Ptr ref2 = getReference (id, false); - const MWWorld::Ptr ref = mEnvironment.mWorld->getPtr (name, true); + const MWWorld::Ptr ref = MWBase::Environment::get().getWorld()->getPtr (name, true); double diff[3]; @@ -233,7 +236,7 @@ namespace MWScript if (!mAction.get()) throw std::runtime_error ("activation failed, because no action to perform"); - mAction->execute (mEnvironment); + mAction->execute(); mActivationHandled = true; } @@ -246,7 +249,7 @@ namespace MWScript float InterpreterContext::getSecondsPassed() const { - return mEnvironment.mFrameDuration; + return MWBase::Environment::get().getFrameDuration(); } bool InterpreterContext::isDisabled (const std::string& id) const @@ -258,38 +261,13 @@ namespace MWScript void InterpreterContext::enable (const std::string& id) { MWWorld::Ptr ref = getReference (id, false); - mEnvironment.mWorld->enable (ref); + MWBase::Environment::get().getWorld()->enable (ref); } void InterpreterContext::disable (const std::string& id) { MWWorld::Ptr ref = getReference (id, false); - mEnvironment.mWorld->disable (ref); - } - - MWWorld::Environment& InterpreterContext::getEnvironment() - { - return mEnvironment; - } - - MWGui::WindowManager& InterpreterContext::getWindowManager() - { - return *mEnvironment.mWindowManager; - } - - MWInput::MWInputManager& InterpreterContext::getInputManager() - { - return *mEnvironment.mInputManager; - } - - MWWorld::World& InterpreterContext::getWorld() - { - return *mEnvironment.mWorld; - } - - MWSound::SoundManager& InterpreterContext::getSoundManager() - { - return *mEnvironment.mSoundManager; + MWBase::Environment::get().getWorld()->disable (ref); } MWWorld::Ptr InterpreterContext::getReference() diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index 35b4a169d2..40f53337db 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -6,7 +6,6 @@ #include #include "../mwworld/ptr.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" #include "../mwworld/action.hpp" @@ -26,7 +25,6 @@ namespace MWScript class InterpreterContext : public Interpreter::Context { - MWWorld::Environment& mEnvironment; Locals *mLocals; MWWorld::Ptr mReference; @@ -40,8 +38,7 @@ namespace MWScript public: - InterpreterContext (MWWorld::Environment& environment, - MWScript::Locals *locals, MWWorld::Ptr reference); + InterpreterContext (MWScript::Locals *locals, MWWorld::Ptr reference); ///< The ownership of \a locals is not transferred. 0-pointer allowed. virtual int getLocalShort (int index) const; @@ -110,18 +107,6 @@ namespace MWScript virtual void disable (const std::string& id = ""); - MWWorld::Environment& getEnvironment(); - - /// \todo remove the following functions (extentions should use getEnvironment instead) - - MWWorld::World& getWorld(); - - MWSound::SoundManager& getSoundManager(); - - MWGui::WindowManager& getWindowManager(); - - MWInput::MWInputManager& getInputManager(); - MWWorld::Ptr getReference(); ///< Reference, that the script is running from (can be empty) }; diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a0770b9a88..4ba523937c 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -7,6 +7,8 @@ #include #include +#include "../mwbase/environment.hpp" + #include "../mwworld/class.hpp" #include "interpretercontext.hpp" @@ -100,7 +102,7 @@ namespace MWScript static_cast (runtime.getContext()); bool enabled = - context.getWorld().toggleRenderMode (MWWorld::World::Render_CollisionDebug); + MWBase::Environment::get().getWorld()->toggleRenderMode (MWWorld::World::Render_CollisionDebug); context.report (enabled ? "Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off"); @@ -117,7 +119,7 @@ namespace MWScript static_cast (runtime.getContext()); bool enabled = - context.getWorld().toggleRenderMode (MWWorld::World::Render_Wireframe); + MWBase::Environment::get().getWorld()->toggleRenderMode (MWWorld::World::Render_Wireframe); context.report (enabled ? "Wireframe Rendering -> On" : "Wireframe Rendering -> Off"); @@ -133,7 +135,7 @@ namespace MWScript static_cast (runtime.getContext()); bool enabled = - context.getWorld().toggleRenderMode (MWWorld::World::Render_Pathgrid); + MWBase::Environment::get().getWorld()->toggleRenderMode (MWWorld::World::Render_Pathgrid); context.report (enabled ? "Path Grid rendering -> On" : "Path Grid Rendering -> Off"); @@ -146,13 +148,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - context.getWorld().getFader()->fadeIn(time); + MWBase::Environment::get().getWorld()->getFader()->fadeIn(time); } }; @@ -162,13 +161,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - context.getWorld().getFader()->fadeOut(time); + MWBase::Environment::get().getWorld()->getFader()->fadeOut(time); } }; @@ -178,16 +174,13 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - Interpreter::Type_Float alpha = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - context.getWorld().getFader()->fadeTo(alpha, time); + MWBase::Environment::get().getWorld()->getFader()->fadeTo(alpha, time); } }; @@ -197,10 +190,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getWorld().toggleWater(); + MWBase::Environment::get().getWorld()->toggleWater(); } }; diff --git a/apps/openmw/mwscript/ref.hpp b/apps/openmw/mwscript/ref.hpp index 5ca1ea4d62..28093c4e56 100644 --- a/apps/openmw/mwscript/ref.hpp +++ b/apps/openmw/mwscript/ref.hpp @@ -5,6 +5,8 @@ #include +#include "../mwbase/environment.hpp" + #include "../mwworld/ptr.hpp" #include "../mwworld/world.hpp" @@ -16,13 +18,10 @@ namespace MWScript { MWWorld::Ptr operator() (Interpreter::Runtime& runtime) const { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - return context.getWorld().getPtr (id, false); + return MWBase::Environment::get().getWorld()->getPtr (id, false); } }; diff --git a/apps/openmw/mwscript/scriptmanager.cpp b/apps/openmw/mwscript/scriptmanager.cpp index e93f2deeca..506cf049c4 100644 --- a/apps/openmw/mwscript/scriptmanager.cpp +++ b/apps/openmw/mwscript/scriptmanager.cpp @@ -20,7 +20,7 @@ namespace MWScript Compiler::Context& compilerContext) : mErrorHandler (std::cerr), mStore (store), mVerbose (verbose), mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext), - mOpcodesInstalled (false) + mOpcodesInstalled (false), mGlobalScripts (store, *this) {} bool ScriptManager::compile (const std::string& name) @@ -151,4 +151,9 @@ namespace MWScript return iter->second.second; } + + GlobalScripts& ScriptManager::getGlobalScripts() + { + return mGlobalScripts; + } } diff --git a/apps/openmw/mwscript/scriptmanager.hpp b/apps/openmw/mwscript/scriptmanager.hpp index 35cbc0d1e8..35c1fadd9e 100644 --- a/apps/openmw/mwscript/scriptmanager.hpp +++ b/apps/openmw/mwscript/scriptmanager.hpp @@ -11,6 +11,8 @@ #include #include +#include "globalscripts.hpp" + namespace ESMS { struct ESMStore; @@ -42,8 +44,8 @@ namespace MWScript typedef std::pair, Compiler::Locals> CompiledScript; typedef std::map ScriptCollection; - ScriptCollection mScripts; + GlobalScripts mGlobalScripts; public: @@ -63,6 +65,8 @@ namespace MWScript Compiler::Locals& getLocals (const std::string& name); ///< Return locals for script \a name. + + GlobalScripts& getGlobalScripts(); }; }; diff --git a/apps/openmw/mwscript/skyextensions.cpp b/apps/openmw/mwscript/skyextensions.cpp index a5cc9e2138..e16c2ec233 100644 --- a/apps/openmw/mwscript/skyextensions.cpp +++ b/apps/openmw/mwscript/skyextensions.cpp @@ -7,6 +7,8 @@ #include #include +#include "../mwbase/environment.hpp" + #include "interpretercontext.hpp" namespace MWScript @@ -19,11 +21,11 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { + bool enabled = MWBase::Environment::get().getWorld()->toggleSky(); + InterpreterContext& context = static_cast (runtime.getContext()); - bool enabled = context.getWorld().toggleSky(); - context.report (enabled ? "Sky -> On" : "Sky -> Off"); } }; @@ -34,10 +36,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getWorld().setMoonColour (false); + MWBase::Environment::get().getWorld()->setMoonColour (false); } }; @@ -47,10 +46,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getWorld().setMoonColour (true); + MWBase::Environment::get().getWorld()->setMoonColour (true); } }; @@ -60,10 +56,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - runtime.push (context.getWorld().getMasserPhase()); + runtime.push (MWBase::Environment::get().getWorld()->getMasserPhase()); } }; @@ -73,42 +66,33 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - runtime.push (context.getWorld().getSecundaPhase()); + runtime.push (MWBase::Environment::get().getWorld()->getSecundaPhase()); } }; - + class OpGetCurrentWeather : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - - runtime.push (context.getWorld().getCurrentWeather()); + runtime.push (MWBase::Environment::get().getWorld()->getCurrentWeather()); } }; - + class OpChangeWeather : public Interpreter::Opcode0 { public: - + virtual void execute (Interpreter::Runtime& runtime) { - InterpreterContext& context = - static_cast (runtime.getContext()); - std::string region = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - + Interpreter::Type_Integer id = runtime[0].mInteger; runtime.pop(); - - context.getWorld().changeWeather(region, id); + + MWBase::Environment::get().getWorld()->changeWeather(region, id); } }; diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index b4386a8a0d..c2b45641a3 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -7,6 +7,8 @@ #include #include +#include "../mwbase/environment.hpp" + #include "../mwworld/world.hpp" #include "../mwsound/soundmanager.hpp" @@ -36,7 +38,7 @@ namespace MWScript std::string text = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - context.getSoundManager().say (ptr, file); + MWBase::Environment::get().getSoundManager()->say (ptr, file); context.messageBox (text); } }; @@ -50,10 +52,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - - runtime.push (context.getSoundManager().sayDone (ptr)); + runtime.push (MWBase::Environment::get().getSoundManager()->sayDone (ptr)); } }; @@ -63,13 +62,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - context.getSoundManager().streamMusic (sound); + MWBase::Environment::get().getSoundManager()->streamMusic (sound); } }; @@ -79,13 +75,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - context.getSoundManager().playSound (sound, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); } }; @@ -95,9 +88,6 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -107,7 +97,7 @@ namespace MWScript Interpreter::Type_Float pitch = runtime[0].mFloat; runtime.pop(); - context.getSoundManager().playSound (sound, volume, pitch); + MWBase::Environment::get().getSoundManager()->playSound (sound, volume, pitch); } }; @@ -124,13 +114,10 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - context.getSoundManager().playSound3D (ptr, sound, 1.0, 1.0, mLoop ? MWSound::Play_Loop : 0); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, sound, 1.0, 1.0, mLoop ? MWSound::Play_Loop : 0); } }; @@ -147,9 +134,6 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -159,7 +143,7 @@ namespace MWScript Interpreter::Type_Float pitch = runtime[0].mFloat; runtime.pop(); - context.getSoundManager().playSound3D (ptr, sound, volume, pitch, mLoop ? MWSound::Play_Loop : 0); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, sound, volume, pitch, mLoop ? MWSound::Play_Loop : 0); } }; @@ -173,13 +157,10 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - context.getSoundManager().stopSound3D (ptr, sound); + MWBase::Environment::get().getSoundManager()->stopSound3D (ptr, sound); } }; @@ -192,13 +173,10 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - int index = runtime[0].mInteger; runtime.pop(); - runtime.push (context.getSoundManager().getSoundPlaying ( + runtime.push (MWBase::Environment::get().getSoundManager()->getSoundPlaying ( ptr, runtime.getStringLiteral (index))); } }; diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 239f8d7682..cad52e5930 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -7,8 +7,9 @@ #include #include +#include "../mwbase/environment.hpp" + #include "../mwworld/class.hpp" -#include "../mwworld/environment.hpp" #include "../mwworld/player.hpp" #include "../mwmechanics/creaturestats.hpp" @@ -351,11 +352,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { std::string factionID = ""; - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + if(arg0==0) { - factionID = context.getEnvironment().mDialogueManager->getFaction(); + factionID = MWBase::Environment::get().getDialogueManager()->getFaction(); } else { @@ -364,7 +364,7 @@ namespace MWScript } if(factionID != "") { - MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) { MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 0; @@ -380,11 +380,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { std::string factionID = ""; - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + if(arg0==0) { - factionID = context.getEnvironment().mDialogueManager->getFaction(); + factionID = MWBase::Environment::get().getDialogueManager()->getFaction(); } else { @@ -393,7 +392,7 @@ namespace MWScript } if(factionID != "") { - MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) { MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 0; @@ -413,11 +412,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { std::string factionID = ""; - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + if(arg0==0) { - factionID = context.getEnvironment().mDialogueManager->getFaction(); + factionID = MWBase::Environment::get().getDialogueManager()->getFaction(); } else { @@ -426,7 +424,7 @@ namespace MWScript } if(factionID != "") { - MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) != MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) { MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] -1; @@ -461,9 +459,7 @@ namespace MWScript factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).mFactionRank.begin()->first; } } - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); - MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); if(factionID!="") { if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) != MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) @@ -481,7 +477,7 @@ namespace MWScript } } }; - + template class OpModDisposition : public Interpreter::Opcode0 { diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 730d9d9b21..4656efb6ed 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -9,7 +9,8 @@ #include #include -#include "../mwworld/environment.hpp" +#include "../mwbase/environment.hpp" + #include "../mwworld/world.hpp" #include "../mwworld/player.hpp" @@ -46,9 +47,8 @@ namespace MWSound { - SoundManager::SoundManager(bool useSound, MWWorld::Environment& environment) + SoundManager::SoundManager(bool useSound) : mResourceMgr(Ogre::ResourceGroupManager::getSingleton()) - , mEnvironment(environment) , mOutput(new DEFAULT_OUTPUT(*this)) , mMasterVolume(1.0f) , mSFXVolume(1.0f) @@ -113,7 +113,7 @@ namespace MWSound std::string SoundManager::lookup(const std::string &soundId, float &volume, float &min, float &max) { - const ESM::Sound *snd = mEnvironment.mWorld->getStore().sounds.search(soundId); + const ESM::Sound *snd = MWBase::Environment::get().getWorld()->getStore().sounds.search(soundId); if(snd == NULL) throw std::runtime_error(std::string("Failed to lookup sound ")+soundId); @@ -380,7 +380,7 @@ namespace MWSound void SoundManager::updateRegionSound(float duration) { - MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore *current = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); static int total = 0; static std::string regionName = ""; static float timePassed = 0.0; @@ -397,7 +397,7 @@ namespace MWSound total = 0; } - const ESM::Region *regn = mEnvironment.mWorld->getStore().regions.find(regionName); + const ESM::Region *regn = MWBase::Environment::get().getWorld()->getStore().regions.find(regionName); std::vector::const_iterator soundIter; if(total == 0) { @@ -445,8 +445,8 @@ namespace MWSound if(!isMusicPlaying()) startRandomTitle(); - const ESM::Cell *cell = mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell; - Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera(); + const ESM::Cell *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell; + Ogre::Camera *cam = MWBase::Environment::get().getWorld()->getPlayer().getRenderer()->getCamera(); Ogre::Vector3 nPos, nDir, nUp; nPos = cam->getRealPosition(); nDir = cam->getRealDirection(); diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index d64db299b4..8afd488e11 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -16,11 +16,6 @@ namespace Ogre class Camera; } -namespace MWWorld -{ - struct Environment; -} - namespace MWSound { class Sound_Output; @@ -52,8 +47,6 @@ namespace MWSound { Ogre::ResourceGroupManager& mResourceMgr; - MWWorld::Environment& mEnvironment; - std::auto_ptr mOutput; float mMasterVolume; @@ -82,7 +75,7 @@ namespace MWSound friend class OpenAL_Output; public: - SoundManager(bool useSound, MWWorld::Environment& environment); + SoundManager(bool useSound); ~SoundManager(); void stopMusic(); diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index 1558193355..d5cf12779e 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -3,8 +3,6 @@ namespace MWWorld { - class Environment; - /// \brief Abstract base for actions class Action { @@ -18,7 +16,7 @@ namespace MWWorld virtual ~Action() {} - virtual void execute (Environment& environment) = 0; + virtual void execute() = 0; }; } diff --git a/apps/openmw/mwworld/actiontake.cpp b/apps/openmw/mwworld/actiontake.cpp index bbe9540497..b1e2e1fc3d 100644 --- a/apps/openmw/mwworld/actiontake.cpp +++ b/apps/openmw/mwworld/actiontake.cpp @@ -1,8 +1,9 @@ #include "actiontake.hpp" +#include "../mwbase/environment.hpp" + #include "class.hpp" -#include "environment.hpp" #include "world.hpp" #include "containerstore.hpp" @@ -10,14 +11,14 @@ namespace MWWorld { ActionTake::ActionTake (const MWWorld::Ptr& object) : mObject (object) {} - void ActionTake::execute (Environment& environment) + void ActionTake::execute() { // insert into player's inventory - MWWorld::Ptr player = environment.mWorld->getPtr ("player", true); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPtr ("player", true); MWWorld::Class::get (player).getContainerStore (player).add (mObject); // remove from world - environment.mWorld->deleteObject (mObject); + MWBase::Environment::get().getWorld()->deleteObject (mObject); } } diff --git a/apps/openmw/mwworld/actiontake.hpp b/apps/openmw/mwworld/actiontake.hpp index 509ebc6bbf..f495fc3c4a 100644 --- a/apps/openmw/mwworld/actiontake.hpp +++ b/apps/openmw/mwworld/actiontake.hpp @@ -14,7 +14,7 @@ namespace MWWorld ActionTake (const MWWorld::Ptr& object); - virtual void execute (Environment& environment); + virtual void execute(); }; } diff --git a/apps/openmw/mwworld/actiontalk.cpp b/apps/openmw/mwworld/actiontalk.cpp index 7d38c22fd7..b33b788323 100644 --- a/apps/openmw/mwworld/actiontalk.cpp +++ b/apps/openmw/mwworld/actiontalk.cpp @@ -1,7 +1,7 @@ #include "actiontalk.hpp" -#include "environment.hpp" +#include "../mwbase/environment.hpp" #include "../mwdialogue/dialoguemanager.hpp" @@ -9,8 +9,8 @@ namespace MWWorld { ActionTalk::ActionTalk (const Ptr& actor) : mActor (actor) {} - void ActionTalk::execute (Environment& environment) + void ActionTalk::execute() { - environment.mDialogueManager->startDialogue (mActor); + MWBase::Environment::get().getDialogueManager()->startDialogue (mActor); } } diff --git a/apps/openmw/mwworld/actiontalk.hpp b/apps/openmw/mwworld/actiontalk.hpp index a60a61660b..1b7b9b6d6f 100644 --- a/apps/openmw/mwworld/actiontalk.hpp +++ b/apps/openmw/mwworld/actiontalk.hpp @@ -15,7 +15,7 @@ namespace MWWorld ActionTalk (const Ptr& actor); ///< \param actor The actor the player is talking to - virtual void execute (Environment& environment); + virtual void execute(); }; } diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index 207e2c50e9..6ebbd7b7f3 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -1,7 +1,8 @@ #include "actionteleport.hpp" -#include "environment.hpp" +#include "../mwbase/environment.hpp" + #include "world.hpp" namespace MWWorld @@ -11,11 +12,11 @@ namespace MWWorld : mCellName (cellName), mPosition (position) {} - void ActionTeleportPlayer::execute (Environment& environment) + void ActionTeleportPlayer::execute() { if (mCellName.empty()) - environment.mWorld->changeToExteriorCell (mPosition); + MWBase::Environment::get().getWorld()->changeToExteriorCell (mPosition); else - environment.mWorld->changeToInteriorCell (mCellName, mPosition); + MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, mPosition); } } diff --git a/apps/openmw/mwworld/actionteleport.hpp b/apps/openmw/mwworld/actionteleport.hpp index e4c972a9e3..00efdc8765 100644 --- a/apps/openmw/mwworld/actionteleport.hpp +++ b/apps/openmw/mwworld/actionteleport.hpp @@ -19,7 +19,7 @@ namespace MWWorld ActionTeleportPlayer (const std::string& cellName, const ESM::Position& position); ///< If cellName is empty, an exterior cell is asumed. - virtual void execute (Environment& environment); + virtual void execute(); }; } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index d49b98d0fb..78ed5ca2e5 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -27,17 +27,17 @@ namespace MWWorld } - void Class::insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const + void Class::insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics) const { } - void Class::enable (const Ptr& ptr, MWWorld::Environment& environment) const + void Class::enable (const Ptr& ptr) const { } - void Class::disable (const Ptr& ptr, MWWorld::Environment& environment) const + void Class::disable (const Ptr& ptr) const { } @@ -62,14 +62,12 @@ namespace MWWorld throw std::runtime_error ("class does not have item health"); } - boost::shared_ptr Class::activate (const Ptr& ptr, const Ptr& actor, - const Environment& environment) const + boost::shared_ptr Class::activate (const Ptr& ptr, const Ptr& actor) const { return boost::shared_ptr (new NullAction); } - boost::shared_ptr Class::use (const Ptr& ptr, - const Environment& environment) const + boost::shared_ptr Class::use (const Ptr& ptr) const { return boost::shared_ptr (new NullAction); } @@ -134,7 +132,7 @@ namespace MWWorld return std::make_pair (std::vector(), false); } - int Class::getEquipmentSkill (const Ptr& ptr, const Environment& environment) const + int Class::getEquipmentSkill (const Ptr& ptr) const { return -1; } @@ -164,13 +162,23 @@ namespace MWWorld sClasses.insert (std::make_pair (key, instance)); } - std::string Class::getUpSoundId (const Ptr& ptr, const MWWorld::Environment& environment) const + std::string Class::getUpSoundId (const Ptr& ptr) const { throw std::runtime_error ("class does not have an up sound"); } - std::string Class::getDownSoundId (const Ptr& ptr, const MWWorld::Environment& environment) const + std::string Class::getDownSoundId (const Ptr& ptr) const { throw std::runtime_error ("class does not have an down sound"); } + + MWGui::ToolTipInfo Class::getToolTipInfo (const Ptr& ptr) const + { + throw std::runtime_error ("class does not have a tool tip"); + } + + bool Class::hasToolTip (const Ptr& ptr) const + { + return false; + } } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index e474e9b926..e69b8f2ac9 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -12,6 +12,7 @@ #include "physicssystem.hpp" #include "../mwrender/renderinginterface.hpp" +#include "../mwgui/tooltips.hpp" namespace Ogre { @@ -33,7 +34,6 @@ namespace MWMechanics namespace MWWorld { class Ptr; - class Environment; class ContainerStore; class InventoryStore; @@ -65,15 +65,15 @@ namespace MWWorld /// (default implementation: throw an exception) virtual void insertObjectRendering (const Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; - virtual void insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const; + virtual void insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics) const; ///< Add reference into a cell for rendering (default implementation: don't render anything). - virtual void enable (const Ptr& ptr, MWWorld::Environment& environment) const; + virtual void enable (const Ptr& ptr) const; ///< Enable reference; only does the non-rendering part (default implementation: ignore) /// \attention This is not the same as the script instruction with the same name. References /// should only be enabled while in an active cell. - virtual void disable (const Ptr& ptr, MWWorld::Environment& environment) const; + virtual void disable (const Ptr& ptr) const; ///< Enable reference; only does the non-rendering part (default implementation: ignore) /// \attention This is not the same as the script instruction with the same name. References /// should only be enabled while in an active cell. @@ -86,6 +86,12 @@ namespace MWWorld ///< Return creature stats or throw an exception, if class does not have creature stats /// (default implementation: throw an exceoption) + virtual bool hasToolTip (const Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual MWGui::ToolTipInfo getToolTipInfo (const Ptr& ptr) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual MWMechanics::NpcStats& getNpcStats (const Ptr& ptr) const; ///< Return NPC stats or throw an exception, if class does not have NPC stats /// (default implementation: throw an exceoption) @@ -97,11 +103,10 @@ namespace MWWorld ///< Return item max health or throw an exception, if class does not have item health /// (default implementation: throw an exceoption) - virtual boost::shared_ptr activate (const Ptr& ptr, const Ptr& actor, - const Environment& environment) const; + virtual boost::shared_ptr activate (const Ptr& ptr, const Ptr& actor) const; ///< Generate action for activation (default implementation: return a null action). - virtual boost::shared_ptr use (const Ptr& ptr, const Environment& environment) + virtual boost::shared_ptr use (const Ptr& ptr) const; ///< Generate action for using via inventory menu (default implementation: return a /// null action). @@ -149,7 +154,7 @@ namespace MWWorld /// /// Default implementation: return (empty vector, false). - virtual int getEquipmentSkill (const Ptr& ptr, const Environment& environment) + virtual int getEquipmentSkill (const Ptr& ptr) const; /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. @@ -167,11 +172,11 @@ namespace MWWorld static void registerClass (const std::string& key, boost::shared_ptr instance); - virtual std::string getUpSoundId (const Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getUpSoundId (const Ptr& ptr) const; ///< Return the up sound ID of \a ptr or throw an exception, if class does not support ID retrieval /// (default implementation: throw an exception) - virtual std::string getDownSoundId (const Ptr& ptr, const MWWorld::Environment& environment) const; + virtual std::string getDownSoundId (const Ptr& ptr) const; ///< Return the down sound ID of \a ptr or throw an exception, if class does not support ID retrieval /// (default implementation: throw an exception) }; diff --git a/apps/openmw/mwworld/environment.hpp b/apps/openmw/mwworld/environment.hpp deleted file mode 100644 index 3a83f886fd..0000000000 --- a/apps/openmw/mwworld/environment.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef GAME_WORLD_INVIRONMENT_H -#define GAME_WORLD_INVIRONMENT_H - -namespace MWSound -{ - class SoundManager; -} - -namespace MWScript -{ - class GlobalScripts; - class ScriptManager; -} - -namespace MWGui -{ - class WindowManager; -} - -namespace MWMechanics -{ - class MechanicsManager; -} - -namespace MWDialogue -{ - class DialogueManager; - class Journal; -} - -namespace MWInput -{ - struct MWInputManager; -} - -namespace MWWorld -{ - class World; - - ///< Collection of script-accessable sub-systems - class Environment - { - public: - Environment() - : mWorld (0), mSoundManager (0), mGlobalScripts (0), mScriptManager (0), mWindowManager (0), - mMechanicsManager (0), mDialogueManager (0), mJournal (0), mFrameDuration (0), - mInputManager (0) - {} - - World *mWorld; - MWSound::SoundManager *mSoundManager; - MWScript::GlobalScripts *mGlobalScripts; - MWScript::ScriptManager *mScriptManager; - MWGui::WindowManager *mWindowManager; - MWMechanics::MechanicsManager *mMechanicsManager; - MWDialogue::DialogueManager *mDialogueManager; - MWDialogue::Journal *mJournal; - float mFrameDuration; - - // For setting GUI mode - MWInput::MWInputManager *mInputManager; - }; -} - -#endif diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 230f7d69a0..576f2371f9 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -8,8 +8,6 @@ #include "class.hpp" -#include /// \todo remove after rendering is implemented - void MWWorld::InventoryStore::copySlots (const InventoryStore& store) { // some const-trickery, required because of a flaw in the handling of MW-references and the @@ -72,7 +70,7 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite /// \todo restack item previously in this slot (if required) /// \todo unstack item pointed to by iterator if required) - + mSlots[slot] = iterator; flagAsModified(); @@ -96,8 +94,7 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) return mSlots[slot]; } -void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats, - const Environment& environment) +void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats) { TSlots slots; initSlots (slots); @@ -105,7 +102,7 @@ void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats, for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter) { Ptr test = *iter; - int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test, environment); + int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test); std::pair, bool> itemsSlots = MWWorld::Class::get (*iter).getEquipmentSlots (*iter); @@ -125,7 +122,7 @@ void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats, { // check skill int oldSkill = - MWWorld::Class::get (old).getEquipmentSkill (old, environment); + MWWorld::Class::get (old).getEquipmentSkill (old); if (testSkill!=-1 || oldSkill!=-1 || testSkill!=oldSkill) { @@ -169,13 +166,5 @@ void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats, { mSlots.swap (slots); flagAsModified(); - - /// \todo remove the following line after rendering is implemented - for (std::size_t i=0; igetChildIterator().getNext(); Ogre::Quaternion yawQuat = yawNode->getOrientation(); Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); - Ogre::Quaternion both = yawQuat * pitchQuat; + + // unused + //Ogre::Quaternion both = yawQuat * pitchQuat; playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); playerphysics->ps.viewangles.z = 0; @@ -316,7 +318,9 @@ namespace MWWorld void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){ Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); - Ogre::Vector3 objPos = node->getPosition(); + + // unused + //Ogre::Vector3 objPos = node->getPosition(); addObject (node->getName(), model, node->getOrientation(), node->getScale().x, node->getPosition()); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index b3af5dd528..0b1483ff8f 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -24,8 +24,6 @@ namespace MWWorld float* playerPos = mPlayer.mData.getPosition().pos; playerPos[0] = playerPos[1] = playerPos[2] = 0; - std::cout << renderer->getHandle(); - mPlayer.mData.setBaseNode(renderer->getNode()); /// \todo Do not make a copy of classes defined in esm/p records. mClass = new ESM::Class (*world.getStore().classes.find (player->cls)); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 2f34ded95f..6f9f3ed3ed 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -1,6 +1,7 @@ #include "scene.hpp" #include "world.hpp" +#include "../mwbase/environment.hpp" #include "../mwmechanics/mechanicsmanager.hpp" @@ -9,7 +10,6 @@ #include "../mwgui/window_manager.hpp" #include "ptr.hpp" -#include "environment.hpp" #include "player.hpp" #include "class.hpp" @@ -18,7 +18,7 @@ namespace { template -void insertCellRefList(MWRender::RenderingManager& rendering, MWWorld::Environment& environment, +void insertCellRefList(MWRender::RenderingManager& rendering, T& cellRefList, ESMS::CellStore &cell, MWWorld::PhysicsSystem& physics) { if (!cellRefList.list.empty()) @@ -36,8 +36,8 @@ void insertCellRefList(MWRender::RenderingManager& rendering, MWWorld::Environme try { rendering.addObject(ptr); - class_.insertObject(ptr, physics, environment); - class_.enable (ptr, environment); + class_.insertObject(ptr, physics); + class_.enable (ptr); } catch (const std::exception& e) { @@ -89,12 +89,12 @@ namespace MWWorld //mPhysics->removeObject("Unnamed_43"); mWorld->getLocalScripts().clearCell (*iter); - mEnvironment.mMechanicsManager->dropActors (*iter); - mEnvironment.mSoundManager->stopSound (*iter); + MWBase::Environment::get().getMechanicsManager()->dropActors (*iter); + MWBase::Environment::get().getSoundManager()->stopSound (*iter); mActiveCells.erase(*iter); - - + + } void Scene::loadCell (Ptr::CellStore *cell) @@ -109,7 +109,7 @@ namespace MWWorld if(result.second) { - insertCell(*cell, mEnvironment); + insertCell(*cell); mRendering.cellAdded (cell); float verts = ESM::Land::LAND_SIZE; @@ -141,10 +141,10 @@ namespace MWWorld mWorld->getPlayer().setCell (cell); // TODO orientation - mEnvironment.mMechanicsManager->addActor (mWorld->getPlayer().getPlayer()); - mEnvironment.mMechanicsManager->watchActor (mWorld->getPlayer().getPlayer()); + MWBase::Environment::get().getMechanicsManager()->addActor (mWorld->getPlayer().getPlayer()); + MWBase::Environment::get().getMechanicsManager()->watchActor (mWorld->getPlayer().getPlayer()); - mEnvironment.mWindowManager->changeCell( mCurrentCell ); + MWBase::Environment::get().getWindowManager()->changeCell( mCurrentCell ); } void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) @@ -152,7 +152,7 @@ namespace MWWorld mRendering.preCellChange(mCurrentCell); // remove active - mEnvironment.mMechanicsManager->removeActor (mWorld->getPlayer().getPlayer()); + MWBase::Environment::get().getMechanicsManager()->removeActor (mWorld->getPlayer().getPlayer()); CellStoreCollection::iterator active = mActiveCells.begin(); @@ -222,12 +222,14 @@ namespace MWWorld // Sky system mWorld->adjustSky(); + mRendering.switchToExterior(); + mCellChanged = true; } //We need the ogre renderer and a scene node. - Scene::Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, PhysicsSystem *physics) - : mCurrentCell (0), mCellChanged (false), mEnvironment (environment), mWorld(world), + Scene::Scene (World *world, MWRender::RenderingManager& rendering, PhysicsSystem *physics) + : mCurrentCell (0), mCellChanged (false), mWorld(world), mPhysics(physics), mRendering(rendering) { } @@ -262,13 +264,14 @@ namespace MWWorld Ptr::CellStore *cell = mWorld->getInterior(cellName); loadCell (cell); - + // adjust player mCurrentCell = cell; playerCellChange (cell, position); - + // adjust fog + mRendering.switchToInterior(); mRendering.configureFog(*cell); // Sky system @@ -297,30 +300,29 @@ namespace MWWorld mCellChanged = false; } -void Scene::insertCell(ESMS::CellStore &cell, - MWWorld::Environment& environment) +void Scene::insertCell(ESMS::CellStore &cell) { // Loop through all references in the cell - insertCellRefList(mRendering, environment, cell.activators, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.potions, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.appas, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.armors, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.books, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.clothes, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.containers, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.creatures, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.doors, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.ingreds, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.creatureLists, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.itemLists, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.lights, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.lockpicks, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.miscItems, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.npcs, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.probes, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.repairs, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.statics, cell, *mPhysics); - insertCellRefList(mRendering, environment, cell.weapons, cell, *mPhysics); + insertCellRefList(mRendering, cell.activators, cell, *mPhysics); + insertCellRefList(mRendering, cell.potions, cell, *mPhysics); + insertCellRefList(mRendering, cell.appas, cell, *mPhysics); + insertCellRefList(mRendering, cell.armors, cell, *mPhysics); + insertCellRefList(mRendering, cell.books, cell, *mPhysics); + insertCellRefList(mRendering, cell.clothes, cell, *mPhysics); + insertCellRefList(mRendering, cell.containers, cell, *mPhysics); + insertCellRefList(mRendering, cell.creatures, cell, *mPhysics); + insertCellRefList(mRendering, cell.doors, cell, *mPhysics); + insertCellRefList(mRendering, cell.ingreds, cell, *mPhysics); + insertCellRefList(mRendering, cell.creatureLists, cell, *mPhysics); + insertCellRefList(mRendering, cell.itemLists, cell, *mPhysics); + insertCellRefList(mRendering, cell.lights, cell, *mPhysics); + insertCellRefList(mRendering, cell.lockpicks, cell, *mPhysics); + insertCellRefList(mRendering, cell.miscItems, cell, *mPhysics); + insertCellRefList(mRendering, cell.npcs, cell, *mPhysics); + insertCellRefList(mRendering, cell.probes, cell, *mPhysics); + insertCellRefList(mRendering, cell.repairs, cell, *mPhysics); + insertCellRefList(mRendering, cell.statics, cell, *mPhysics); + insertCellRefList(mRendering, cell.weapons, cell, *mPhysics); } diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 4d1bd6fb51..1a9f2f271a 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -46,7 +46,6 @@ namespace MWRender namespace MWWorld { - class Environment; class Player; class Scene @@ -62,7 +61,6 @@ namespace MWWorld Ptr::CellStore* mCurrentCell; // the cell, the player is in CellStoreCollection mActiveCells; bool mCellChanged; - Environment& mEnvironment; World *mWorld; PhysicsSystem *mPhysics; MWRender::RenderingManager& mRendering; @@ -73,7 +71,7 @@ namespace MWWorld public: - Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, PhysicsSystem *physics); + Scene (World *world, MWRender::RenderingManager& rendering, PhysicsSystem *physics); ~Scene(); @@ -100,7 +98,7 @@ namespace MWWorld void markCellAsUnchanged(); - void insertCell(ESMS::CellStore &cell, MWWorld::Environment& environment); + void insertCell(ESMS::CellStore &cell); void update (float duration); }; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index fb0480171d..bcbb96eecf 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -9,7 +9,9 @@ #include #include -#include +#include + +#include "../mwbase/environment.hpp" using namespace Ogre; using namespace MWWorld; @@ -34,15 +36,14 @@ const float WeatherGlobals::mThunderFrequency = .4; const float WeatherGlobals::mThunderThreshold = 0.6; const float WeatherGlobals::mThunderSoundDelay = 0.25; -WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::Environment* env) : +WeatherManager::WeatherManager(MWRender::RenderingManager* rendering) : mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0) { mRendering = rendering; - mEnvironment = env; - + #define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f) - + /// \todo read these from Morrowind.ini Weather clear; clear.mCloudTexture = "tx_sky_clear.dds"; @@ -71,7 +72,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E clear.mCloudSpeed = 1.25; clear.mGlareView = 1.0; mWeatherSettings["clear"] = clear; - + Weather cloudy; cloudy.mCloudTexture = "tx_sky_cloudy.dds"; cloudy.mCloudsMaximumPercent = 1.0; @@ -99,7 +100,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E cloudy.mCloudSpeed = 2; cloudy.mGlareView = 1.0; mWeatherSettings["cloudy"] = cloudy; - + Weather foggy; foggy.mCloudTexture = "tx_sky_foggy.dds"; foggy.mCloudsMaximumPercent = 1.0; @@ -127,7 +128,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E foggy.mCloudSpeed = 1.25; foggy.mGlareView = 0.25; mWeatherSettings["foggy"] = foggy; - + Weather thunderstorm; thunderstorm.mCloudTexture = "tx_sky_thunder.dds"; thunderstorm.mCloudsMaximumPercent = 0.66; @@ -156,7 +157,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E thunderstorm.mGlareView = 0; thunderstorm.mRainLoopSoundID = "rain heavy"; mWeatherSettings["thunderstorm"] = thunderstorm; - + Weather rain; rain.mCloudTexture = "tx_sky_rainy.dds"; rain.mCloudsMaximumPercent = 0.66; @@ -185,7 +186,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E rain.mGlareView = 0; rain.mRainLoopSoundID = "rain"; mWeatherSettings["rain"] = rain; - + Weather overcast; overcast.mCloudTexture = "tx_sky_overcast.dds"; overcast.mCloudsMaximumPercent = 1.0; @@ -213,7 +214,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E overcast.mCloudSpeed = 1.5; overcast.mGlareView = 0; mWeatherSettings["overcast"] = overcast; - + Weather ashstorm; ashstorm.mCloudTexture = "tx_sky_ashstorm.dds"; ashstorm.mCloudsMaximumPercent = 1.0; @@ -242,7 +243,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E ashstorm.mGlareView = 0; ashstorm.mAmbientLoopSoundID = "ashstorm"; mWeatherSettings["ashstorm"] = ashstorm; - + Weather blight; blight.mCloudTexture = "tx_sky_blight.dds"; blight.mCloudsMaximumPercent = 1.0; @@ -300,7 +301,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E snow.mCloudSpeed = 1.5; snow.mGlareView = 0; mWeatherSettings["snow"] = snow; - + Weather blizzard; blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds"; blizzard.mCloudsMaximumPercent = 1.0; @@ -484,15 +485,15 @@ WeatherResult WeatherManager::transition(float factor) void WeatherManager::update(float duration) { - mWeatherUpdateTime -= duration * mEnvironment->mWorld->getTimeScaleFactor(); + mWeatherUpdateTime -= duration * MWBase::Environment::get().getWorld()->getTimeScaleFactor(); - bool exterior = (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior()); + bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); if (exterior) { - std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region; + std::string regionstr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell->region; boost::algorithm::to_lower(regionstr); - + if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) { mCurrentRegion = regionstr; @@ -505,7 +506,7 @@ void WeatherManager::update(float duration) else { // get weather probabilities for the current region - const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr); + const ESM::Region *region = MWBase::Environment::get().getWorld()->getStore().regions.find (regionstr); float clear = region->data.clear/255.f; float cloudy = region->data.cloudy/255.f; @@ -521,7 +522,6 @@ void WeatherManager::update(float duration) // re-scale to 100 percent const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight;//+snow+blizzard; - srand(time(NULL)); float random = ((rand()%100)/100.f) * total; //if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) @@ -553,7 +553,7 @@ void WeatherManager::update(float duration) if (mNextWeather != "") { - mRemainingTransitionTime -= duration * mEnvironment->mWorld->getTimeScaleFactor(); + mRemainingTransitionTime -= duration * MWBase::Environment::get().getWorld()->getTimeScaleFactor(); if (mRemainingTransitionTime < 0) { mCurrentWeather = mNextWeather; @@ -588,8 +588,8 @@ void WeatherManager::update(float duration) int facing = (mHour > 13.f) ? 1 : -1; Vector3 final( - -(1-height)*facing, - -(1-height)*facing, + -(1-height)*facing, + -(1-height)*facing, height); mRendering->setSunDirection(final); @@ -609,13 +609,13 @@ void WeatherManager::update(float duration) float moonHeight = 1-std::abs((night-0.5)*2); int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1; Vector3 masser( - (1-moonHeight)*facing, - (1-moonHeight)*facing, + (1-moonHeight)*facing, + (1-moonHeight)*facing, moonHeight); Vector3 secunda( - (1-moonHeight)*facing*0.8, - (1-moonHeight)*facing*1.25, + (1-moonHeight)*facing*0.8, + (1-moonHeight)*facing*1.25, moonHeight); mRendering->getSkyManager()->setMasserDirection(masser); @@ -676,7 +676,7 @@ void WeatherManager::update(float duration) else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1; else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2; else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3; - mEnvironment->mSoundManager->playSound(soundname, 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound(soundname, 1.0, 1.0); mThunderSoundDelay = 1000; } @@ -729,7 +729,7 @@ void WeatherManager::update(float duration) if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end()) { mSoundsPlaying.push_back(ambientSnd); - mEnvironment->mSoundManager->playSound(ambientSnd, 1.0, 1.0, true); + MWBase::Environment::get().getSoundManager()->playSound(ambientSnd, 1.0, 1.0, true); } } @@ -740,7 +740,7 @@ void WeatherManager::update(float duration) if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end()) { mSoundsPlaying.push_back(rainSnd); - mEnvironment->mSoundManager->playSound(rainSnd, 1.0, 1.0, true); + MWBase::Environment::get().getSoundManager()->playSound(rainSnd, 1.0, 1.0, true); } } @@ -750,7 +750,7 @@ void WeatherManager::update(float duration) { if ( *it != ambientSnd && *it != rainSnd) { - mEnvironment->mSoundManager->stopSound(*it); + MWBase::Environment::get().getSoundManager()->stopSound(*it); it = mSoundsPlaying.erase(it); } else @@ -772,7 +772,7 @@ void WeatherManager::setDate(const int day, const int month) unsigned int WeatherManager::getWeatherID() const { // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather - + if (mCurrentWeather == "clear") return 0; else if (mCurrentWeather == "cloudy") @@ -793,7 +793,7 @@ unsigned int WeatherManager::getWeatherID() const return 8; else if (mCurrentWeather == "blizzard") return 9; - + else return 0; } diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index b9b40e6fad..5e0388751f 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -11,8 +11,6 @@ namespace MWRender namespace MWWorld { - class Environment; - /// Global weather manager properties (according to INI) struct WeatherGlobals { @@ -67,8 +65,8 @@ namespace MWWorld Snow Gravity Scale=0.1 Snow High Kill=700 Snow Low Kill=150 - - + + [Moons] Masser Size=94 Masser Fade In Start=14 @@ -94,14 +92,14 @@ namespace MWWorld Secunda Moon Shadow Early Fade Angle=0.5 Script Color=255,20,20 */ - + static const float mSunriseTime; static const float mSunsetTime; static const float mSunriseDuration; static const float mSunsetDuration; - + static const float mWeatherUpdateTime; - + // morrowind sets these per-weather, but since they are only used by 'thunderstorm' // weather setting anyway, we can just as well set them globally static const float mThunderFrequency; @@ -119,154 +117,153 @@ namespace MWWorld Ogre::String mCloudTexture; Ogre::String mNextCloudTexture; float mCloudBlendFactor; - + Ogre::ColourValue mFogColor; - + Ogre::ColourValue mAmbientColor; - + Ogre::ColourValue mSkyColor; - + Ogre::ColourValue mSunColor; - + Ogre::ColourValue mSunDiscColor; - + float mFogDepth; - + float mWindSpeed; - + float mCloudSpeed; - + float mCloudOpacity; - + float mGlareView; - + bool mNight; // use night skybox float mNightFade; // fading factor for night skybox - + Ogre::String mAmbientLoopSoundID; }; - - + + /// Defines a single weather setting (according to INI) struct Weather { Ogre::String mCloudTexture; - - // Sky (atmosphere) colors + + // Sky (atmosphere) colors Ogre::ColourValue mSkySunriseColor, mSkyDayColor, mSkySunsetColor, mSkyNightColor; - + // Fog colors Ogre::ColourValue mFogSunriseColor, mFogDayColor, mFogSunsetColor, mFogNightColor; - + // Ambient lighting colors Ogre::ColourValue mAmbientSunriseColor, mAmbientDayColor, mAmbientSunsetColor, mAmbientNightColor; - + // Sun (directional) lighting colors Ogre::ColourValue mSunSunriseColor, mSunDayColor, mSunSunsetColor, mSunNightColor; - + // Fog depth/density float mLandFogDayDepth, mLandFogNightDepth; - + // Color modulation for the sun itself during sunset (not completely sure) Ogre::ColourValue mSunDiscSunsetColor; - + // Duration of weather transition (in days) float mTransitionDelta; - + // No idea what this one is used for? float mWindSpeed; - + // Cloud animation speed multiplier float mCloudSpeed; - + // Multiplier for clouds transparency float mCloudsMaximumPercent; - + // Value between 0 and 1, defines the strength of the sun glare effect float mGlareView; - + // Sound effect // This is used for Blight, Ashstorm and Blizzard (Bloodmoon) Ogre::String mAmbientLoopSoundID; - + // Rain sound effect Ogre::String mRainLoopSoundID; - + /// \todo disease chance }; - + /// /// Interface for weather settings /// class WeatherManager { public: - WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*); - + WeatherManager(MWRender::RenderingManager*); + /** * Change the weather in the specified region * @param region that should be changed * @param ID of the weather setting to shift to */ void changeWeather(const std::string& region, const unsigned int id); - + /** * Per-frame update * @param duration */ void update(float duration); - + void setHour(const float hour); - + void setDate(const int day, const int month); - + unsigned int getWeatherID() const; - + private: float mHour; int mDay, mMonth; - + MWRender::RenderingManager* mRendering; - MWWorld::Environment* mEnvironment; - + std::map mWeatherSettings; std::map mRegionOverrides; std::vector mSoundsPlaying; - + Ogre::String mCurrentWeather; Ogre::String mNextWeather; - + std::string mCurrentRegion; - + bool mFirstUpdate; - + float mWeatherUpdateTime; - + float mRemainingTransitionTime; - + float mThunderFlash; float mThunderChance; float mThunderChanceNeeded; float mThunderSoundDelay; - + WeatherResult transition(const float factor); WeatherResult getResult(const Ogre::String& weather); - + void setWeather(const Ogre::String& weather, bool instant=false); }; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index f8b8de89a5..04bc999a09 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -6,6 +6,8 @@ #include #include +#include "../mwbase/environment.hpp" + #include "../mwrender/sky.hpp" #include "../mwrender/player.hpp" @@ -13,9 +15,9 @@ #include "../mwsound/soundmanager.hpp" +#include "../mwgui/window_manager.hpp" #include "ptr.hpp" -#include "environment.hpp" #include "class.hpp" #include "player.hpp" #include "weather.hpp" @@ -174,18 +176,18 @@ namespace MWWorld World::World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, - const std::string& master, const boost::filesystem::path& resDir, - bool newGame, Environment& environment, const std::string& encoding, std::map fallbackMap) + const std::string& master, const boost::filesystem::path& resDir, bool newGame, + const std::string& encoding, std::map fallbackMap) : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), - mSky (true), mEnvironment (environment), mNextDynamicRecord (0), mCells (mStore, mEsm, *this), + mSky (true), mNextDynamicRecord (0), mCells (mStore, mEsm, *this), mNumFacing(0) { mPhysics = new PhysicsSystem(renderer); mPhysEngine = mPhysics->getEngine(); - mRendering = new MWRender::RenderingManager(renderer, resDir, mPhysEngine, environment); + mRendering = new MWRender::RenderingManager(renderer, resDir, mPhysEngine); - mWeatherManager = new MWWorld::WeatherManager(mRendering, &environment); + mWeatherManager = new MWWorld::WeatherManager(mRendering); boost::filesystem::path masterPath (fileCollections.getCollection (".esm").getPath (master)); @@ -209,7 +211,7 @@ namespace MWWorld mGlobalVariables->setInt ("chargenstate", 1); } - mWorldScene = new Scene(environment, this, *mRendering, mPhysics); + mWorldScene = new Scene(this, *mRendering, mPhysics); setFallbackValues(fallbackMap); @@ -357,7 +359,7 @@ namespace MWWorld //render->enable (reference.getRefData().getHandle()); if(mWorldScene->getActiveCells().find (reference.getCell()) != mWorldScene->getActiveCells().end()) - Class::get (reference).enable (reference, mEnvironment); + Class::get (reference).enable (reference); } @@ -372,8 +374,8 @@ namespace MWWorld //render->disable (reference.getRefData().getHandle()); if(mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end()){ - Class::get (reference).disable (reference, mEnvironment); - mEnvironment.mSoundManager->stopSound3D (reference); + Class::get (reference).disable (reference); + MWBase::Environment::get().getSoundManager()->stopSound3D (reference); } @@ -547,7 +549,7 @@ namespace MWWorld if (mWorldScene->getActiveCells().find (ptr.getCell())!=mWorldScene->getActiveCells().end()){ // Class::get (ptr).disable (ptr, mEnvironment); /// \todo this line needs to be removed - mEnvironment.mSoundManager->stopSound3D (ptr); + MWBase::Environment::get().getSoundManager()->stopSound3D (ptr); mPhysics->removeObject (ptr.getRefData().getHandle()); mRendering->removeObject(ptr); @@ -737,6 +739,17 @@ namespace MWWorld mWeatherManager->update (duration); + // inform the GUI about focused object + try + { + MWBase::Environment::get().getWindowManager()->setFocusObject(getPtrViaHandle(mFacedHandle)); + } + catch (std::runtime_error&) + { + MWWorld::Ptr null; + MWBase::Environment::get().getWindowManager()->setFocusObject(null); + } + if (!mRendering->occlusionQuerySupported()) { // cast a ray from player to sun to detect if the sun is visible diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 8dd370ad76..77e5bcef62 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -51,7 +51,6 @@ namespace MWRender namespace MWWorld { class WeatherManager; - class Environment; class Player; /// \brief The game world and its visual representation @@ -81,7 +80,6 @@ namespace MWWorld MWWorld::Globals *mGlobalVariables; MWWorld::PhysicsSystem *mPhysics; bool mSky; - Environment& mEnvironment; int mNextDynamicRecord; Cells mCells; @@ -111,7 +109,7 @@ namespace MWWorld World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, const std::string& master, const boost::filesystem::path& resDir, bool newGame, - Environment& environment, const std::string& encoding, std::map fallbackMap); + const std::string& encoding, std::map fallbackMap); ~World(); diff --git a/components/esm/loadligh.hpp b/components/esm/loadligh.hpp index 178258a053..9e7934b15f 100644 --- a/components/esm/loadligh.hpp +++ b/components/esm/loadligh.hpp @@ -17,7 +17,7 @@ struct Light { Dynamic = 0x001, Carry = 0x002, // Can be carried - Negative = 0x004, // Negative light? + Negative = 0x004, // Negative light - i.e. darkness Flicker = 0x008, Fire = 0x010, OffDefault = 0x020, // Off by default diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index d7a4100aae..48bf050cda 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -90,6 +90,75 @@ namespace ESMS } }; + // Same as RecListT, but does not case-smash the IDs + // Note that lookups (search or find) are still case insensitive + template + struct RecListCaseT : RecList + { + virtual ~RecListCaseT() {} + + typedef std::map MapType; + + MapType list; + + // Load one object of this type + void load(ESMReader &esm, const std::string &id) + { + //std::string id2 = toLower (id); + + list[id].load(esm); + } + + // Find the given object ID, or return NULL if not found. + const X* search(const std::string &id) const + { + std::string id2 = toLower (id); + + for (typename MapType::const_iterator iter = list.begin(); + iter != list.end(); ++iter) + { + if (toLower(iter->first) == id2) + return &iter->second; + } + + return NULL; + } + + // non-const version + X* search(const std::string &id) + { + std::string id2 = toLower (id); + + for (typename MapType::iterator iter = list.begin(); + iter != list.end(); ++iter) + { + if (toLower(iter->first) == id2) + return &iter->second; + } + + return NULL; + } + + // Find the given object ID (throws an exception if not found) + const X* find(const std::string &id) const + { + const X *object = search (id); + + if (!object) + throw std::runtime_error ("object " + id + " not found"); + + return object; + } + + int getSize() { return list.size(); } + + virtual void listIdentifier (std::vector& identifier) const + { + for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter) + identifier.push_back (iter->first); + } + }; + /// Modified version of RecListT for records, that need to store their own ID template struct RecListWithIDT : RecList diff --git a/components/esm_store/store.cpp b/components/esm_store/store.cpp index 2b5b977aa0..c676601e54 100644 --- a/components/esm_store/store.cpp +++ b/components/esm_store/store.cpp @@ -71,15 +71,13 @@ void ESMStore::load(ESMReader &esm) if (n.val==ESM::REC_DIAL) { - RecListT& recList = static_cast& > (*it->second); + RecListCaseT& recList = static_cast& > (*it->second); - id = recList.toLower (id); + ESM::Dialogue* d = recList.search (id); - RecListT::MapType::iterator iter = recList.list.find (id); + assert (d != NULL); - assert (iter!=recList.list.end()); - - dialogue = &iter->second; + dialogue = d; } else dialogue = 0; diff --git a/components/esm_store/store.hpp b/components/esm_store/store.hpp index 8576820897..507196a869 100644 --- a/components/esm_store/store.hpp +++ b/components/esm_store/store.hpp @@ -40,9 +40,9 @@ namespace ESMS RecListT clothes; RecListT contChange; RecListT containers; - RecListWithIDT creatures; + RecListWithIDT creatures; RecListT creaChange; - RecListT dialogs; + RecListCaseT dialogs; RecListT doors; RecListT enchants; RecListT factions; @@ -53,7 +53,7 @@ namespace ESMS RecListT lights; RecListT lockpicks; RecListT miscItems; - RecListWithIDT npcs; + RecListWithIDT npcs; RecListT npcChange; RecListT probes; RecListT races; diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index e3a7b9999c..49055d2ede 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -50,6 +50,7 @@ configure_file("${SDIR}/openmw_messagebox_layout.xml" "${DDIR}/openmw_messagebox configure_file("${SDIR}/openmw_interactive_messagebox_layout.xml" "${DDIR}/openmw_interactive_messagebox_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_journal_layout.xml" "${DDIR}/openmw_journal_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_journal_skin.xml" "${DDIR}/openmw_journal_skin.xml" COPYONLY) +configure_file("${SDIR}/openmw_tooltips.xml" "${DDIR}/openmw_tooltips.xml" COPYONLY) configure_file("${SDIR}/smallbars.png" "${DDIR}/smallbars.png" COPYONLY) configure_file("${SDIR}/transparent.png" "${DDIR}/transparent.png" COPYONLY) configure_file("${SDIR}/EBGaramond-Regular.ttf" "${DDIR}/EBGaramond-Regular.ttf" COPYONLY) diff --git a/files/mygui/openmw_button.skin.xml b/files/mygui/openmw_button.skin.xml index 1c68930264..b88e994066 100644 --- a/files/mygui/openmw_button.skin.xml +++ b/files/mygui/openmw_button.skin.xml @@ -47,7 +47,6 @@ - @@ -59,11 +58,10 @@ - - - - - + + + + diff --git a/files/mygui/openmw_chargen_generate_class_result_layout.xml b/files/mygui/openmw_chargen_generate_class_result_layout.xml index 7ec926eb05..26ebe17e1f 100644 --- a/files/mygui/openmw_chargen_generate_class_result_layout.xml +++ b/files/mygui/openmw_chargen_generate_class_result_layout.xml @@ -1,27 +1,29 @@ - + - + + + - + - + - + diff --git a/files/mygui/openmw_dialogue_window_layout.xml b/files/mygui/openmw_dialogue_window_layout.xml index 29a3b511ec..b0e437074c 100644 --- a/files/mygui/openmw_dialogue_window_layout.xml +++ b/files/mygui/openmw_dialogue_window_layout.xml @@ -16,7 +16,7 @@ - + diff --git a/files/mygui/openmw_dialogue_window_skin.xml b/files/mygui/openmw_dialogue_window_skin.xml index ecdec8a5c0..31ce626be0 100644 --- a/files/mygui/openmw_dialogue_window_skin.xml +++ b/files/mygui/openmw_dialogue_window_skin.xml @@ -8,12 +8,12 @@ - - + + - + diff --git a/files/mygui/openmw_edit.skin.xml b/files/mygui/openmw_edit.skin.xml index a86317d620..02fee4b179 100644 --- a/files/mygui/openmw_edit.skin.xml +++ b/files/mygui/openmw_edit.skin.xml @@ -13,7 +13,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/files/mygui/openmw_interactive_messagebox_layout.xml b/files/mygui/openmw_interactive_messagebox_layout.xml index 744f212276..b8a71c670d 100644 --- a/files/mygui/openmw_interactive_messagebox_layout.xml +++ b/files/mygui/openmw_interactive_messagebox_layout.xml @@ -5,7 +5,7 @@ - + diff --git a/files/mygui/openmw_list.skin.xml b/files/mygui/openmw_list.skin.xml index 0ac8e03ba6..02075ad1a6 100644 --- a/files/mygui/openmw_list.skin.xml +++ b/files/mygui/openmw_list.skin.xml @@ -180,10 +180,14 @@ - - - - + + + + + + + + @@ -219,7 +223,7 @@ - <_BasisSkin type="MainSkin" offset = "0 0 0 0" align = "ALIGN_LEFT ALIGN_TOP"/> + diff --git a/files/mygui/openmw_messagebox_layout.xml b/files/mygui/openmw_messagebox_layout.xml index 81d1c0a57e..c99c00a49e 100644 --- a/files/mygui/openmw_messagebox_layout.xml +++ b/files/mygui/openmw_messagebox_layout.xml @@ -8,7 +8,7 @@ - + diff --git a/files/mygui/openmw_text.skin.xml b/files/mygui/openmw_text.skin.xml index 6ae14c558b..36d97e1538 100644 --- a/files/mygui/openmw_text.skin.xml +++ b/files/mygui/openmw_text.skin.xml @@ -93,20 +93,25 @@ + + + + + - + - + - + diff --git a/files/mygui/openmw_text_input_layout.xml b/files/mygui/openmw_text_input_layout.xml index 6a7ad27f01..c8f76b2575 100644 --- a/files/mygui/openmw_text_input_layout.xml +++ b/files/mygui/openmw_text_input_layout.xml @@ -4,10 +4,10 @@ - + - + diff --git a/files/mygui/openmw_tooltips.xml b/files/mygui/openmw_tooltips.xml new file mode 100644 index 0000000000..2d5a5da9f2 --- /dev/null +++ b/files/mygui/openmw_tooltips.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/files/openmw.bmp b/files/openmw.bmp new file mode 100644 index 0000000000..be3fd94ce7 Binary files /dev/null and b/files/openmw.bmp differ diff --git a/files/plugins.cfg.win32 b/files/plugins.cfg.win32 index f71e8d3250..ea12c03940 100644 --- a/files/plugins.cfg.win32 +++ b/files/plugins.cfg.win32 @@ -4,10 +4,10 @@ PluginFolder=.\ # Define plugins -Plugin=RenderSystem_Direct3D9_d -Plugin=RenderSystem_GL_d -Plugin=Plugin_ParticleFX_d -Plugin=Plugin_OctreeSceneManager_d -Plugin=Plugin_CgProgramManager_d +Plugin=RenderSystem_Direct3D9 +Plugin=RenderSystem_GL +Plugin=Plugin_ParticleFX +Plugin=Plugin_OctreeSceneManager +Plugin=Plugin_CgProgramManager diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 553a82e497..e4a0c020a5 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -86,6 +86,7 @@ num lights = 8 [Water] # Enable this to get fancy-looking water with reflections and refractions +# Only available if object shaders are on # All the settings below have no effect if this is false shader = true diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index a174981769..3d507d4eee 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -393,7 +393,7 @@ namespace Physic void PhysicEngine::stepSimulation(double deltaT) { - dynamicsWorld->stepSimulation(deltaT,1,1/50.); + dynamicsWorld->stepSimulation(deltaT,10); if(isDebugCreated) { mDebugDrawer->step(); diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index d0c14b6b95..e215d8ff63 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -2022,7 +2022,9 @@ void Ext_UpdateViewAngles(playerMove* const pm) void Pmove (playerMove* const pmove) { - int fmove = pmove->cmd.forwardmove; + // warning: unused variable ‘fmove’ + //int fmove = pmove->cmd.forwardmove; + pm = pmove; int finalTime; @@ -2047,12 +2049,16 @@ void Pmove (playerMove* const pmove) msec = finalTime - pmove->ps.commandTime; - if ( pmove->pmove_fixed ) + if ( pmove->pmove_fixed ) + { if ( msec > pmove->pmove_msec ) msec = pmove->pmove_msec; - else + } + else + { if ( msec > 66 ) msec = 66; + } pmove->cmd.serverTime = pmove->ps.commandTime + msec; diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index a14a1e660d..2c61b3e7d7 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -64,7 +64,7 @@ static const float pm_duckScale = 0.25f; static const float pm_flyaccelerate = 8.0f; static const float pm_wateraccelerate = 4.0f; -enum pmtype_t : unsigned char +enum pmtype_t { PM_NORMAL, // can accelerate and turn PM_NOCLIP, // noclip movement @@ -75,7 +75,7 @@ enum pmtype_t : unsigned char PM_SPINTERMISSION // no movement or status bar }; -enum waterlevel_t : unsigned char +enum waterlevel_t { WL_DRYLAND = 0, WL_ANKLE, diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 81c064c2d3..2d18aaa4da 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -103,13 +103,17 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z)); const btTransform from(btrot, btstart); - const btTransform to(btrot, btend); + const btTransform to(btrot, btend); + + // warning: unused variable ... + /* float x = from.getOrigin().getX(); float y = from.getOrigin().getY(); float z = from.getOrigin().getZ(); float x2 = to.getOrigin().getX(); float y2 = to.getOrigin().getY(); float z2 = to.getOrigin().getZ(); + */ //std::cout << "BtFrom: " << x << "," << y << "," << z << "\n"; //std::cout << "BtTo: " << x2 << "," << y2 << "," << z2 << "\n"; diff --git a/libs/openengine/bullet/trace.h b/libs/openengine/bullet/trace.h index fb666b6ebd..d446b6854c 100644 --- a/libs/openengine/bullet/trace.h +++ b/libs/openengine/bullet/trace.h @@ -18,7 +18,7 @@ enum traceWorldType bothWorldTrace = collisionWorldTrace | pickWorldTrace }; -enum collaborativePhysicsType : unsigned +enum collaborativePhysicsType { No_Physics = 0, // Both are empty (example: statics you can walk through, like tall grass) Only_Collision = 1, // This object only has collision physics but no pickup physics (example: statics) diff --git a/libs/openengine/gui/layout.hpp b/libs/openengine/gui/layout.hpp index 05a23e8aea..bda8935af2 100644 --- a/libs/openengine/gui/layout.hpp +++ b/libs/openengine/gui/layout.hpp @@ -85,7 +85,7 @@ namespace GUI // adjust the size of the window caption so that all text is visible // NOTE: this assumes that mMainWidget is of type Window. MyGUI::TextBox* box = static_cast(mMainWidget)->getCaptionWidget(); - box->setSize(box->getTextSize().width + 48, box->getSize().height); + box->setSize(box->getTextSize().width + 24, box->getSize().height); // in order to trigger alignment updates, we need to update the parent // mygui doesn't provide a proper way of doing this, so we are just changing size @@ -115,6 +115,13 @@ namespace GUI static_cast(pt)->setCaption(caption); } + void setState(const std::string& widget, const std::string& state) + { + MyGUI::Widget* pt; + getWidget(pt, widget); + pt->_setWidgetState(state); + } + void setTextColor(const std::string& name, float r, float g, float b) { MyGUI::Widget* pt; @@ -131,6 +138,13 @@ namespace GUI pt->setImageTexture(imgName); } + void adjustButtonSize(MyGUI::Button* button) + { + // adjust size of button to fit its text + MyGUI::IntSize size = button->getTextSize(); + button->setSize(size.width + 24, button->getSize().height); + } + protected: MyGUI::Widget* mMainWidget; diff --git a/libs/openengine/ogre/imagerotate.cpp b/libs/openengine/ogre/imagerotate.cpp index 1147559d6e..11fd5eea6a 100644 --- a/libs/openengine/ogre/imagerotate.cpp +++ b/libs/openengine/ogre/imagerotate.cpp @@ -54,7 +54,7 @@ void ImageRotate::rotate(const std::string& sourceImage, const std::string& dest TEX_TYPE_2D, width, height, 0, - PF_A8R8G8B8, + PF_FLOAT16_RGBA, TU_RENDERTARGET); RenderTarget* rtt = destTexture->getBuffer()->getRenderTarget(); @@ -63,7 +63,6 @@ void ImageRotate::rotate(const std::string& sourceImage, const std::string& dest vp->setOverlaysEnabled(false); vp->setShadowsEnabled(false); vp->setBackgroundColour(ColourValue(0,0,0,0)); - vp->setClearEveryFrame(true, FBT_DEPTH); rtt->update(); diff --git a/readme.txt b/readme.txt index 52c4e11a24..53f4a4c59e 100644 --- a/readme.txt +++ b/readme.txt @@ -87,7 +87,6 @@ Allowed options: win1252 - Western European (Latin) alphabet, used by default - --report-focus [=arg(=1)] (=0) write name of focussed object to cout --fallback arg fallback values