mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
		
						commit
						e893d0d7d3
					
				
					 34 changed files with 322 additions and 157 deletions
				
			
		| 
						 | 
				
			
			@ -362,9 +362,6 @@ endif()
 | 
			
		|||
if (CMAKE_COMPILER_IS_GNUCC)
 | 
			
		||||
    SET(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
 | 
			
		||||
 | 
			
		||||
    # Silence warnings in OGRE headers. Remove once OGRE got fixed!
 | 
			
		||||
    SET(CMAKE_CXX_FLAGS "-Wno-ignored-qualifiers ${CMAKE_CXX_FLAGS}")
 | 
			
		||||
 | 
			
		||||
    execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
 | 
			
		||||
                OUTPUT_VARIABLE GCC_VERSION)
 | 
			
		||||
    if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -143,7 +143,7 @@ namespace MWBase
 | 
			
		|||
            virtual bool isCellQuasiExterior() const = 0;
 | 
			
		||||
 | 
			
		||||
            virtual Ogre::Vector2 getNorthVector (MWWorld::CellStore* cell) = 0;
 | 
			
		||||
            ///< get north vector (OGRE coordinates) for given interior cell
 | 
			
		||||
            ///< get north vector for given interior cell
 | 
			
		||||
 | 
			
		||||
            virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector<DoorMarker>& out) = 0;
 | 
			
		||||
            ///< get a list of teleport door markers for a given cell, to be displayed on the local map
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -276,7 +276,6 @@ namespace MWGui
 | 
			
		|||
        {
 | 
			
		||||
            // in choice, not allowed to escape, but give access to main menu to allow loading other saves
 | 
			
		||||
            MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
 | 
			
		||||
            MWBase::Environment::get().getSoundManager()->pauseSounds (MWBase::SoundManager::Play_TypeSfx);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -543,6 +543,9 @@ namespace MWGui
 | 
			
		|||
        if (MWBase::Environment::get().getWindowManager()->getSpellWindow())
 | 
			
		||||
            MWBase::Environment::get().getWindowManager()->getSpellWindow()->updateSpells();
 | 
			
		||||
 | 
			
		||||
        MWBase::Environment::get().getMechanicsManager()->updateMagicEffects(
 | 
			
		||||
                    MWBase::Environment::get().getWorld()->getPlayerPtr());
 | 
			
		||||
 | 
			
		||||
        mPreviewDirty = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,6 +56,43 @@ void ItemView::initialiseOverride()
 | 
			
		|||
    mScrollView->setCanvasAlign(MyGUI::Align::Left | MyGUI::Align::Top);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ItemView::layoutWidgets()
 | 
			
		||||
{
 | 
			
		||||
    if (!mScrollView->getChildCount())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    int x = 0;
 | 
			
		||||
    int y = 0;
 | 
			
		||||
    int maxHeight = mScrollView->getSize().height - 58;
 | 
			
		||||
 | 
			
		||||
    MyGUI::Widget* dragArea = mScrollView->getChildAt(0);
 | 
			
		||||
 | 
			
		||||
    for (unsigned int i=0; i<dragArea->getChildCount(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        MyGUI::Widget* w = dragArea->getChildAt(i);
 | 
			
		||||
 | 
			
		||||
        w->setPosition(x, y);
 | 
			
		||||
 | 
			
		||||
        y += 42;
 | 
			
		||||
        if (y > maxHeight)
 | 
			
		||||
        {
 | 
			
		||||
            x += 42;
 | 
			
		||||
            y = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    x += 42;
 | 
			
		||||
 | 
			
		||||
    MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height);
 | 
			
		||||
 | 
			
		||||
    // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
 | 
			
		||||
    mScrollView->setVisibleVScroll(false);
 | 
			
		||||
    mScrollView->setVisibleHScroll(false);
 | 
			
		||||
    mScrollView->setCanvasSize(size);
 | 
			
		||||
    mScrollView->setVisibleVScroll(true);
 | 
			
		||||
    mScrollView->setVisibleHScroll(true);
 | 
			
		||||
    dragArea->setSize(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ItemView::update()
 | 
			
		||||
{
 | 
			
		||||
    while (mScrollView->getChildCount())
 | 
			
		||||
| 
						 | 
				
			
			@ -64,10 +101,6 @@ void ItemView::update()
 | 
			
		|||
    if (!mModel)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    int x = 0;
 | 
			
		||||
    int y = 0;
 | 
			
		||||
    int maxHeight = mScrollView->getSize().height - 58;
 | 
			
		||||
 | 
			
		||||
    mModel->update();
 | 
			
		||||
 | 
			
		||||
    MyGUI::Widget* dragArea = mScrollView->createWidget<MyGUI::Widget>("",0,0,mScrollView->getWidth(),mScrollView->getHeight(),
 | 
			
		||||
| 
						 | 
				
			
			@ -80,9 +113,8 @@ void ItemView::update()
 | 
			
		|||
    {
 | 
			
		||||
        const ItemStack& item = mModel->getItem(i);
 | 
			
		||||
 | 
			
		||||
        /// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
 | 
			
		||||
        ItemWidget* itemWidget = dragArea->createWidget<ItemWidget>("MW_ItemIcon",
 | 
			
		||||
            MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
 | 
			
		||||
            MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
 | 
			
		||||
        itemWidget->setUserString("ToolTipType", "ItemModelIndex");
 | 
			
		||||
        itemWidget->setUserData(std::make_pair(i, mModel));
 | 
			
		||||
        ItemWidget::ItemState state = ItemWidget::None;
 | 
			
		||||
| 
						 | 
				
			
			@ -104,25 +136,9 @@ void ItemView::update()
 | 
			
		|||
        text->setTextShadow(true);
 | 
			
		||||
        text->setTextShadowColour(MyGUI::Colour(0,0,0));
 | 
			
		||||
        text->setCaption(getCountString(item.mCount));
 | 
			
		||||
 | 
			
		||||
        y += 42;
 | 
			
		||||
        if (y > maxHeight)
 | 
			
		||||
        {
 | 
			
		||||
            x += 42;
 | 
			
		||||
            y = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    x += 42;
 | 
			
		||||
    MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height);
 | 
			
		||||
 | 
			
		||||
    // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
 | 
			
		||||
    mScrollView->setVisibleVScroll(false);
 | 
			
		||||
    mScrollView->setVisibleHScroll(false);
 | 
			
		||||
    mScrollView->setCanvasSize(size);
 | 
			
		||||
    mScrollView->setVisibleVScroll(true);
 | 
			
		||||
    mScrollView->setVisibleHScroll(true);
 | 
			
		||||
    dragArea->setSize(size);
 | 
			
		||||
    layoutWidgets();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ItemView::onSelectedItem(MyGUI::Widget *sender)
 | 
			
		||||
| 
						 | 
				
			
			@ -149,7 +165,7 @@ void ItemView::setSize(const MyGUI::IntSize &_value)
 | 
			
		|||
    bool changed = (_value.width != getWidth() || _value.height != getHeight());
 | 
			
		||||
    Base::setSize(_value);
 | 
			
		||||
    if (changed)
 | 
			
		||||
        update();
 | 
			
		||||
        layoutWidgets();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ItemView::setSize(int _width, int _height)
 | 
			
		||||
| 
						 | 
				
			
			@ -162,7 +178,7 @@ void ItemView::setCoord(const MyGUI::IntCoord &_value)
 | 
			
		|||
    bool changed = (_value.width != getWidth() || _value.height != getHeight());
 | 
			
		||||
    Base::setCoord(_value);
 | 
			
		||||
    if (changed)
 | 
			
		||||
        update();
 | 
			
		||||
        layoutWidgets();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ItemView::setCoord(int _left, int _top, int _width, int _height)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,8 @@ namespace MWGui
 | 
			
		|||
    private:
 | 
			
		||||
        virtual void initialiseOverride();
 | 
			
		||||
 | 
			
		||||
        void layoutWidgets();
 | 
			
		||||
 | 
			
		||||
        virtual void setSize(const MyGUI::IntSize& _value);
 | 
			
		||||
        virtual void setCoord(const MyGUI::IntCoord& _value);
 | 
			
		||||
        void setSize(int _width, int _height);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -201,10 +201,6 @@ namespace
 | 
			
		|||
 | 
			
		||||
            setBookMode ();
 | 
			
		||||
 | 
			
		||||
            /// \todo Wiping the whole book layout each time the journal is opened is probably too costly for a large journal (eg 300+ pages).
 | 
			
		||||
            /// There should be a way to keep the existing layout and append new entries to the end of it.
 | 
			
		||||
            /// However, that still leaves the problem of having to add links to previously unknown, but now known topics, so
 | 
			
		||||
            /// we maybe need to find another way to speed things up.
 | 
			
		||||
            Book journalBook;
 | 
			
		||||
            if (mModel->isEmpty ())
 | 
			
		||||
                journalBook = createEmptyJournalBook ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,7 +92,6 @@ namespace MWGui
 | 
			
		|||
        MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
 | 
			
		||||
        if (name == "return")
 | 
			
		||||
        {
 | 
			
		||||
            MWBase::Environment::get().getSoundManager ()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
 | 
			
		||||
            MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu);
 | 
			
		||||
        }
 | 
			
		||||
        else if (name == "options")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -544,15 +544,9 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    void MapWindow::open()
 | 
			
		||||
    {
 | 
			
		||||
        // force markers to foreground
 | 
			
		||||
        for (unsigned int i=0; i<mGlobalMapOverlay->getChildCount (); ++i)
 | 
			
		||||
        {
 | 
			
		||||
            if (mGlobalMapOverlay->getChildAt (i)->getName().substr(0,4) == "Door")
 | 
			
		||||
                mGlobalMapOverlay->getChildAt (i)->castType<MyGUI::Button>()->setImageResource("DoorMarker");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        globalMapUpdatePlayer();
 | 
			
		||||
 | 
			
		||||
        mPlayerArrowGlobal->setImageTexture ("");
 | 
			
		||||
        mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,6 @@ namespace MWGui
 | 
			
		|||
      , mHairIndex(0)
 | 
			
		||||
      , mCurrentAngle(0)
 | 
			
		||||
      , mPreviewDirty(true)
 | 
			
		||||
      , mPreview(NULL)
 | 
			
		||||
    {
 | 
			
		||||
        // Centre dialog
 | 
			
		||||
        center();
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +114,14 @@ namespace MWGui
 | 
			
		|||
        updateSkills();
 | 
			
		||||
        updateSpellPowers();
 | 
			
		||||
 | 
			
		||||
        mPreview = new MWRender::RaceSelectionPreview();
 | 
			
		||||
        mPreview.reset(NULL);
 | 
			
		||||
 | 
			
		||||
        mPreviewImage->setImageTexture("");
 | 
			
		||||
 | 
			
		||||
        const std::string textureName = "CharacterHeadPreview";
 | 
			
		||||
        MyGUI::RenderManager::getInstance().destroyTexture(MyGUI::RenderManager::getInstance().getTexture(textureName));
 | 
			
		||||
 | 
			
		||||
        mPreview.reset(new MWRender::RaceSelectionPreview());
 | 
			
		||||
        mPreview->setup();
 | 
			
		||||
        mPreview->update (0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +135,7 @@ namespace MWGui
 | 
			
		|||
        index = proto.mHair.substr(proto.mHair.size() - 2, 2);
 | 
			
		||||
        mHairIndex = boost::lexical_cast<int>(index) - 1;
 | 
			
		||||
 | 
			
		||||
        mPreviewImage->setImageTexture ("CharacterHeadPreview");
 | 
			
		||||
        mPreviewImage->setImageTexture (textureName);
 | 
			
		||||
 | 
			
		||||
        mPreviewDirty = true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -157,8 +163,7 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    void RaceDialog::close()
 | 
			
		||||
    {
 | 
			
		||||
        delete mPreview;
 | 
			
		||||
        mPreview = 0;
 | 
			
		||||
        mPreview.reset(NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // widget controls
 | 
			
		||||
| 
						 | 
				
			
			@ -306,6 +311,10 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    void RaceDialog::doRenderUpdate()
 | 
			
		||||
    {
 | 
			
		||||
        if (!mPreview.get())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        mPreview->onFrame();
 | 
			
		||||
        if (mPreviewDirty)
 | 
			
		||||
        {
 | 
			
		||||
            mPreview->render();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,7 +100,7 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
        float mCurrentAngle;
 | 
			
		||||
 | 
			
		||||
        MWRender::RaceSelectionPreview* mPreview;
 | 
			
		||||
        std::auto_ptr<MWRender::RaceSelectionPreview> mPreview;
 | 
			
		||||
 | 
			
		||||
        bool mPreviewDirty;
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -689,12 +689,10 @@ namespace MWInput
 | 
			
		|||
        if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) //No open GUIs, open up the MainMenu
 | 
			
		||||
        {
 | 
			
		||||
            MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
 | 
			
		||||
            MWBase::Environment::get().getSoundManager()->pauseSounds (MWBase::SoundManager::Play_TypeSfx);
 | 
			
		||||
        }
 | 
			
		||||
        else //Close current GUI
 | 
			
		||||
        {
 | 
			
		||||
            MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
 | 
			
		||||
            MWBase::Environment::get().getSoundManager()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -301,20 +301,31 @@ namespace MWMechanics
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // start combat if we are in combat with any followers of this actor
 | 
			
		||||
        const std::list<MWWorld::Ptr>& followers = getActorsFollowing(actor2);
 | 
			
		||||
        // start combat if target actor is in combat with one of our followers
 | 
			
		||||
        const std::list<MWWorld::Ptr>& followers = getActorsFollowing(actor1);
 | 
			
		||||
        const CreatureStats& creatureStats2 = actor2.getClass().getCreatureStats(actor2);
 | 
			
		||||
        for (std::list<MWWorld::Ptr>::const_iterator it = followers.begin(); it != followers.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (creatureStats.getAiSequence().isInCombat(*it))
 | 
			
		||||
            // need to check both ways since player doesn't use AI packages
 | 
			
		||||
            if (creatureStats2.getAiSequence().isInCombat(*it)
 | 
			
		||||
                    || it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor2))
 | 
			
		||||
                aggressive = true;
 | 
			
		||||
        }
 | 
			
		||||
        // start combat if we are in combat with someone this actor is following
 | 
			
		||||
        const CreatureStats& creatureStats2 = actor2.getClass().getCreatureStats(actor2);
 | 
			
		||||
        for (std::list<MWMechanics::AiPackage*>::const_iterator it = creatureStats2.getAiSequence().begin(); it != creatureStats2.getAiSequence().end(); ++it)
 | 
			
		||||
 | 
			
		||||
        // start combat if target actor is in combat with someone we are following
 | 
			
		||||
        for (std::list<MWMechanics::AiPackage*>::const_iterator it = creatureStats.getAiSequence().begin(); it != creatureStats.getAiSequence().end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow &&
 | 
			
		||||
                    creatureStats.getAiSequence().isInCombat(dynamic_cast<MWMechanics::AiFollow*>(*it)->getTarget()))
 | 
			
		||||
                aggressive = true;
 | 
			
		||||
            if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow)
 | 
			
		||||
            {
 | 
			
		||||
                MWWorld::Ptr followTarget = dynamic_cast<MWMechanics::AiFollow*>(*it)->getTarget();
 | 
			
		||||
                if (followTarget.isEmpty())
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                // need to check both ways since player doesn't use AI packages
 | 
			
		||||
                if (creatureStats2.getAiSequence().isInCombat(followTarget)
 | 
			
		||||
                        || followTarget.getClass().getCreatureStats(followTarget).getAiSequence().isInCombat(actor2))
 | 
			
		||||
                    aggressive = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(aggressive)
 | 
			
		||||
| 
						 | 
				
			
			@ -1374,11 +1385,19 @@ namespace MWMechanics
 | 
			
		|||
        {
 | 
			
		||||
            const MWWorld::Class &cls = iter->first.getClass();
 | 
			
		||||
            CreatureStats &stats = cls.getCreatureStats(iter->first);
 | 
			
		||||
            if(!stats.isDead() && stats.getAiSequence().getTypeId() == AiPackage::TypeIdFollow)
 | 
			
		||||
            if (stats.isDead())
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            for (std::list<MWMechanics::AiPackage*>::const_iterator it = stats.getAiSequence().begin(); it != stats.getAiSequence().end(); ++it)
 | 
			
		||||
            {
 | 
			
		||||
                MWMechanics::AiFollow* package = static_cast<MWMechanics::AiFollow*>(stats.getAiSequence().getActivePackage());
 | 
			
		||||
                if(package->getFollowedActor() == actor.getCellRef().getRefId())
 | 
			
		||||
                    list.push_front(iter->first);
 | 
			
		||||
                if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow)
 | 
			
		||||
                {
 | 
			
		||||
                    MWWorld::Ptr followTarget = dynamic_cast<MWMechanics::AiFollow*>(*it)->getTarget();
 | 
			
		||||
                    if (followTarget.isEmpty())
 | 
			
		||||
                        continue;
 | 
			
		||||
                    if (followTarget == actor)
 | 
			
		||||
                        list.push_back(iter->first);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return list;
 | 
			
		||||
| 
						 | 
				
			
			@ -1439,4 +1458,10 @@ namespace MWMechanics
 | 
			
		|||
        mActors.clear();
 | 
			
		||||
        mDeathCount.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Actors::updateMagicEffects(const MWWorld::Ptr &ptr)
 | 
			
		||||
    {
 | 
			
		||||
        adjustMagicEffects(ptr);
 | 
			
		||||
        calculateCreatureStatModifiers(ptr, 0.f);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
            /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently
 | 
			
		||||
            /// paused we may want to do it manually (after equipping permanent enchantment)
 | 
			
		||||
            void updateMagicEffects (const MWWorld::Ptr& ptr) { adjustMagicEffects(ptr); }
 | 
			
		||||
            void updateMagicEffects (const MWWorld::Ptr& ptr);
 | 
			
		||||
 | 
			
		||||
            void addActor (const MWWorld::Ptr& ptr, bool updateImmediately=false);
 | 
			
		||||
            ///< Register an actor for stats management
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,24 +16,33 @@
 | 
			
		|||
#include "steering.hpp"
 | 
			
		||||
 | 
			
		||||
MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z)
 | 
			
		||||
: mAlwaysFollow(false), mCommanded(false), mRemainingDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId("")
 | 
			
		||||
: mAlwaysFollow(false), mCommanded(false), mRemainingDuration(duration), mX(x), mY(y), mZ(z)
 | 
			
		||||
, mActorRefId(actorId), mCellId(""), mActorId(-1)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
MWMechanics::AiFollow::AiFollow(const std::string &actorId,const std::string &cellId,float duration, float x, float y, float z)
 | 
			
		||||
: mAlwaysFollow(false), mCommanded(false), mRemainingDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId(cellId)
 | 
			
		||||
: mAlwaysFollow(false), mCommanded(false), mRemainingDuration(duration), mX(x), mY(y), mZ(z)
 | 
			
		||||
, mActorRefId(actorId), mCellId(cellId), mActorId(-1)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MWMechanics::AiFollow::AiFollow(const std::string &actorId, bool commanded)
 | 
			
		||||
: mAlwaysFollow(true), mCommanded(commanded), mRemainingDuration(0), mX(0), mY(0), mZ(0), mActorId(actorId), mCellId("")
 | 
			
		||||
: mAlwaysFollow(true), mCommanded(commanded), mRemainingDuration(0), mX(0), mY(0), mZ(0)
 | 
			
		||||
, mActorRefId(actorId), mCellId(""), mActorId(-1)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
 | 
			
		||||
{
 | 
			
		||||
    const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mActorId, false); //The target to follow
 | 
			
		||||
    MWWorld::Ptr target = getTarget();
 | 
			
		||||
 | 
			
		||||
    if(target == MWWorld::Ptr()) return true;   //Target doesn't exist
 | 
			
		||||
    if (target.isEmpty())
 | 
			
		||||
        return true; //Target doesn't exist
 | 
			
		||||
 | 
			
		||||
    // Only the player can be actively followed. AiFollow packages with targets other than the player
 | 
			
		||||
    // are only used for defining combat alliances, since NPCs will defend whoever they are following or being followed by.
 | 
			
		||||
    if (target != MWBase::Environment::get().getWorld()->getPlayerPtr())
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +95,7 @@ bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
 | 
			
		|||
 | 
			
		||||
std::string MWMechanics::AiFollow::getFollowedActor()
 | 
			
		||||
{
 | 
			
		||||
    return mActorId;
 | 
			
		||||
    return mActorRefId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +119,7 @@ void MWMechanics::AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) co
 | 
			
		|||
    follow->mData.mX = mX;
 | 
			
		||||
    follow->mData.mY = mY;
 | 
			
		||||
    follow->mData.mZ = mZ;
 | 
			
		||||
    follow->mTargetId = mActorId;
 | 
			
		||||
    follow->mTargetId = mActorRefId;
 | 
			
		||||
    follow->mRemainingDuration = mRemainingDuration;
 | 
			
		||||
    follow->mCellId = mCellId;
 | 
			
		||||
    follow->mAlwaysFollow = mAlwaysFollow;
 | 
			
		||||
| 
						 | 
				
			
			@ -125,13 +134,31 @@ void MWMechanics::AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) co
 | 
			
		|||
MWMechanics::AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow)
 | 
			
		||||
    : mAlwaysFollow(follow->mAlwaysFollow), mRemainingDuration(follow->mRemainingDuration)
 | 
			
		||||
    , mX(follow->mData.mX), mY(follow->mData.mY), mZ(follow->mData.mZ)
 | 
			
		||||
    , mActorId(follow->mTargetId), mCellId(follow->mCellId)
 | 
			
		||||
    , mActorRefId(follow->mTargetId), mCellId(follow->mCellId)
 | 
			
		||||
    , mCommanded(follow->mCommanded)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MWWorld::Ptr MWMechanics::AiFollow::getTarget() const
 | 
			
		||||
MWWorld::Ptr MWMechanics::AiFollow::getTarget()
 | 
			
		||||
{
 | 
			
		||||
    return MWBase::Environment::get().getWorld()->searchPtr(mActorId, false);
 | 
			
		||||
    if (mActorId == -2)
 | 
			
		||||
        return MWWorld::Ptr();
 | 
			
		||||
 | 
			
		||||
    if (mActorId == -1)
 | 
			
		||||
    {
 | 
			
		||||
        MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mActorRefId, false);
 | 
			
		||||
        if (target.isEmpty())
 | 
			
		||||
        {
 | 
			
		||||
            mActorId = -2;
 | 
			
		||||
            return target;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            mActorId = target.getClass().getCreatureStats(target).getActorId();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (mActorId != -1)
 | 
			
		||||
        return MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId);
 | 
			
		||||
    else
 | 
			
		||||
        return MWWorld::Ptr();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
            AiFollow(const ESM::AiSequence::AiFollow* follow);
 | 
			
		||||
 | 
			
		||||
            MWWorld::Ptr getTarget() const;
 | 
			
		||||
            MWWorld::Ptr getTarget();
 | 
			
		||||
 | 
			
		||||
            virtual AiFollow *clone() const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +55,8 @@ namespace MWMechanics
 | 
			
		|||
            float mX;
 | 
			
		||||
            float mY;
 | 
			
		||||
            float mZ;
 | 
			
		||||
            std::string mActorId;
 | 
			
		||||
            std::string mActorRefId;
 | 
			
		||||
            int mActorId;
 | 
			
		||||
            std::string mCellId;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,8 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
    void AiWander::init()
 | 
			
		||||
    {
 | 
			
		||||
        // NOTE: mDistance and mDuration must be set already
 | 
			
		||||
 | 
			
		||||
        mCellX = std::numeric_limits<int>::max();
 | 
			
		||||
        mCellY = std::numeric_limits<int>::max();
 | 
			
		||||
        mXCell = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +49,7 @@ namespace MWMechanics
 | 
			
		|||
        mRotate = false;
 | 
			
		||||
        mTargetAngle = 0;
 | 
			
		||||
        mSaidGreeting = Greet_None;
 | 
			
		||||
        greetingTimer = 0;
 | 
			
		||||
        mGreetingTimer = 0;
 | 
			
		||||
        mHasReturnPosition = false;
 | 
			
		||||
        mReturnPosition = Ogre::Vector3(0,0,0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -430,19 +432,19 @@ namespace MWMechanics
 | 
			
		|||
            {
 | 
			
		||||
                if ((playerDistSqr <= helloDistance*helloDistance) && MWBase::Environment::get().getWorld()->getLOS(player, actor)
 | 
			
		||||
                    && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, actor))
 | 
			
		||||
                    greetingTimer++;
 | 
			
		||||
                    mGreetingTimer++;
 | 
			
		||||
                
 | 
			
		||||
                if (greetingTimer >= GREETING_SHOULD_START)
 | 
			
		||||
                if (mGreetingTimer >= GREETING_SHOULD_START)
 | 
			
		||||
                {
 | 
			
		||||
                    mSaidGreeting = Greet_InProgress;
 | 
			
		||||
                    MWBase::Environment::get().getDialogueManager()->say(actor, "hello");
 | 
			
		||||
                    greetingTimer = 0;
 | 
			
		||||
                    mGreetingTimer = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            if(mSaidGreeting == Greet_InProgress)
 | 
			
		||||
            {
 | 
			
		||||
                greetingTimer++;
 | 
			
		||||
                mGreetingTimer++;
 | 
			
		||||
                
 | 
			
		||||
                if(mWalking)
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -470,10 +472,10 @@ namespace MWMechanics
 | 
			
		|||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                if (greetingTimer >= GREETING_SHOULD_END)
 | 
			
		||||
                if (mGreetingTimer >= GREETING_SHOULD_END)
 | 
			
		||||
                {
 | 
			
		||||
                    mSaidGreeting = Greet_Done;
 | 
			
		||||
                    greetingTimer = 0;
 | 
			
		||||
                    mGreetingTimer = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
| 
						 | 
				
			
			@ -680,8 +682,6 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
    AiWander::AiWander (const ESM::AiSequence::AiWander* wander)
 | 
			
		||||
    {
 | 
			
		||||
        init();
 | 
			
		||||
 | 
			
		||||
        mDistance = wander->mData.mDistance;
 | 
			
		||||
        mDuration = wander->mData.mDuration;
 | 
			
		||||
        mStartTime = MWWorld::TimeStamp(wander->mStartTime);
 | 
			
		||||
| 
						 | 
				
			
			@ -690,6 +690,8 @@ namespace MWMechanics
 | 
			
		|||
            mIdle.push_back(wander->mData.mIdle[i]);
 | 
			
		||||
 | 
			
		||||
        mRepeat = wander->mData.mShouldRepeat;
 | 
			
		||||
 | 
			
		||||
        init();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,7 @@ namespace MWMechanics
 | 
			
		|||
 | 
			
		||||
            AiWander (const ESM::AiSequence::AiWander* wander);
 | 
			
		||||
 | 
			
		||||
            // NOTE: mDistance and mDuration must be set already
 | 
			
		||||
            void init();
 | 
			
		||||
 | 
			
		||||
            virtual AiPackage *clone() const;
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +69,7 @@ namespace MWMechanics
 | 
			
		|||
                Greet_Done
 | 
			
		||||
            };
 | 
			
		||||
            GreetingState mSaidGreeting;
 | 
			
		||||
            int greetingTimer;
 | 
			
		||||
            int mGreetingTimer;
 | 
			
		||||
 | 
			
		||||
            bool mHasReturnPosition; // NOTE: Could be removed if mReturnPosition was initialized to actor position,
 | 
			
		||||
                                    // if we had the actor in the AiWander constructor...
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1430,9 +1430,12 @@ void ObjectAnimation::removeParticles()
 | 
			
		|||
{
 | 
			
		||||
    for (unsigned int i=0; i<mObjectRoot->mParticles.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        mObjectRoot->mSceneMgr->destroyParticleSystem(mObjectRoot->mParticles[i]);
 | 
			
		||||
        // Don't destroyParticleSystem, the ParticleSystemController is still holding a pointer to it.
 | 
			
		||||
        // Don't setVisible, this could conflict with a VisController.
 | 
			
		||||
        // The following will remove all spawned particles, then set the speed factor to zero so that no new ones will be spawned.
 | 
			
		||||
        mObjectRoot->mParticles[i]->setSpeedFactor(0.f);
 | 
			
		||||
        mObjectRoot->mParticles[i]->clear();
 | 
			
		||||
    }
 | 
			
		||||
    mObjectRoot->mParticles.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -298,6 +298,9 @@ namespace MWRender
 | 
			
		|||
    void RaceSelectionPreview::render()
 | 
			
		||||
    {
 | 
			
		||||
        mTexture->load();
 | 
			
		||||
 | 
			
		||||
        if (!mRenderTarget)
 | 
			
		||||
            setupRenderTarget();
 | 
			
		||||
        mRenderTarget->update();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,10 @@ namespace MWRender
 | 
			
		|||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GlobalMap::~GlobalMap()
 | 
			
		||||
    {
 | 
			
		||||
        Ogre::TextureManager::getSingleton().remove(mOverlayTexture->getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void GlobalMap::render (Loading::Listener* loadingListener)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -168,9 +172,8 @@ namespace MWRender
 | 
			
		|||
 | 
			
		||||
        tex->load();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        mOverlayTexture = Ogre::TextureManager::getSingleton().createManual("GlobalMapOverlay", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
 | 
			
		||||
            Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, Ogre::PF_A8B8G8R8, Ogre::TU_DYNAMIC_WRITE_ONLY);
 | 
			
		||||
            Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, Ogre::PF_A8B8G8R8, Ogre::TU_DYNAMIC, this);
 | 
			
		||||
 | 
			
		||||
        clear();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -194,9 +197,11 @@ namespace MWRender
 | 
			
		|||
 | 
			
		||||
    void GlobalMap::exploreCell(int cellX, int cellY)
 | 
			
		||||
    {
 | 
			
		||||
        float originX = (cellX - mMinX) * 24;
 | 
			
		||||
        const int size = 24;
 | 
			
		||||
 | 
			
		||||
        float originX = (cellX - mMinX) * size;
 | 
			
		||||
        // NB y + 1, because we want the top left corner, not bottom left where the origin of the cell is
 | 
			
		||||
        float originY = mHeight - (cellY+1 - mMinY) * 24;
 | 
			
		||||
        float originY = mHeight - (cellY+1 - mMinY) * size;
 | 
			
		||||
 | 
			
		||||
        if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY)
 | 
			
		||||
            return;
 | 
			
		||||
| 
						 | 
				
			
			@ -204,31 +209,47 @@ namespace MWRender
 | 
			
		|||
        Ogre::TexturePtr localMapTexture = Ogre::TextureManager::getSingleton().getByName("Cell_"
 | 
			
		||||
            + boost::lexical_cast<std::string>(cellX) + "_" + boost::lexical_cast<std::string>(cellY));
 | 
			
		||||
 | 
			
		||||
        // mipmap version - can't get ogre to generate automips..
 | 
			
		||||
        /*if (!localMapTexture.isNull())
 | 
			
		||||
        {
 | 
			
		||||
            assert(localMapTexture->getBuffer(0, 4)->getWidth() == 64); // 1024 / 2^4
 | 
			
		||||
 | 
			
		||||
            mOverlayTexture->getBuffer()->blit(localMapTexture->getBuffer(0, 4), Ogre::Image::Box(0,0,64, 64),
 | 
			
		||||
                         Ogre::Image::Box(originX,originY,originX+24,originY+24));
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        if (!localMapTexture.isNull())
 | 
			
		||||
        {
 | 
			
		||||
            mOverlayTexture->load();
 | 
			
		||||
            mOverlayTexture->getBuffer()->blit(localMapTexture->getBuffer(), Ogre::Image::Box(0,0,512,512),
 | 
			
		||||
                         Ogre::Image::Box(originX,originY,originX+24,originY+24));
 | 
			
		||||
                         Ogre::Image::Box(originX,originY,originX+size,originY+size));
 | 
			
		||||
 | 
			
		||||
            Ogre::Image backup;
 | 
			
		||||
            std::vector<Ogre::uchar> data;
 | 
			
		||||
            data.resize(size*size*4, 0);
 | 
			
		||||
            backup.loadDynamicImage(&data[0], size, size, Ogre::PF_A8B8G8R8);
 | 
			
		||||
 | 
			
		||||
            localMapTexture->getBuffer()->blitToMemory(Ogre::Image::Box(0,0,512,512), backup.getPixelBox());
 | 
			
		||||
 | 
			
		||||
            for (int x=0; x<size; ++x)
 | 
			
		||||
                for (int y=0; y<size; ++y)
 | 
			
		||||
                {
 | 
			
		||||
                    assert (originX+x < mOverlayImage.getWidth());
 | 
			
		||||
                    assert (originY+y < mOverlayImage.getHeight());
 | 
			
		||||
                    assert (x < int(backup.getWidth()));
 | 
			
		||||
                    assert (y < int(backup.getHeight()));
 | 
			
		||||
                    mOverlayImage.setColourAt(backup.getColourAt(x, y, 0), originX+x, originY+y, 0);
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void GlobalMap::clear()
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<Ogre::uint32> buffer;
 | 
			
		||||
        // initialize to (0,0,0,0)
 | 
			
		||||
        buffer.resize(mWidth * mHeight, 0);
 | 
			
		||||
        Ogre::uchar* buffer =  OGRE_ALLOC_T(Ogre::uchar, mWidth * mHeight * 4, Ogre::MEMCATEGORY_GENERAL);
 | 
			
		||||
        memset(buffer, 0, mWidth * mHeight * 4);
 | 
			
		||||
 | 
			
		||||
        Ogre::PixelBox pb(mWidth, mHeight, 1, Ogre::PF_A8B8G8R8, &buffer[0]);
 | 
			
		||||
        mOverlayImage.loadDynamicImage(&buffer[0], mWidth, mHeight, 1, Ogre::PF_A8B8G8R8, true); // pass ownership of buffer to image
 | 
			
		||||
 | 
			
		||||
        mOverlayTexture->getBuffer()->blitFromMemory(pb);
 | 
			
		||||
        mOverlayTexture->load();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void GlobalMap::loadResource(Ogre::Resource *resource)
 | 
			
		||||
    {
 | 
			
		||||
        Ogre::Texture* tex = dynamic_cast<Ogre::Texture*>(resource);
 | 
			
		||||
        Ogre::ConstImagePtrList list;
 | 
			
		||||
        list.push_back(&mOverlayImage);
 | 
			
		||||
        tex->_loadImages(list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void GlobalMap::write(ESM::GlobalMap& map)
 | 
			
		||||
| 
						 | 
				
			
			@ -238,9 +259,7 @@ namespace MWRender
 | 
			
		|||
        map.mBounds.mMinY = mMinY;
 | 
			
		||||
        map.mBounds.mMaxY = mMaxY;
 | 
			
		||||
 | 
			
		||||
        Ogre::Image image;
 | 
			
		||||
        mOverlayTexture->convertToImage(image);
 | 
			
		||||
        Ogre::DataStreamPtr encoded = image.encode("png");
 | 
			
		||||
        Ogre::DataStreamPtr encoded = mOverlayImage.encode("png");
 | 
			
		||||
        map.mImageData.resize(encoded->size());
 | 
			
		||||
        encoded->read(&map.mImageData[0], encoded->size());
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -303,8 +322,15 @@ namespace MWRender
 | 
			
		|||
                                                                                 image.getHeight(), 0, Ogre::PF_A8B8G8R8);
 | 
			
		||||
        tex->loadImage(image);
 | 
			
		||||
 | 
			
		||||
        mOverlayTexture->load();
 | 
			
		||||
        mOverlayTexture->getBuffer()->blit(tex->getBuffer(), srcBox, destBox);
 | 
			
		||||
 | 
			
		||||
        if (srcBox.left == destBox.left && srcBox.right == destBox.right
 | 
			
		||||
                && srcBox.top == destBox.top && srcBox.bottom == destBox.bottom)
 | 
			
		||||
            mOverlayImage = image;
 | 
			
		||||
        else
 | 
			
		||||
            mOverlayTexture->convertToImage(mOverlayImage);
 | 
			
		||||
 | 
			
		||||
        Ogre::TextureManager::getSingleton().remove("@temp");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,10 +18,11 @@ namespace ESM
 | 
			
		|||
namespace MWRender
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    class GlobalMap
 | 
			
		||||
    class GlobalMap : public Ogre::ManualResourceLoader
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        GlobalMap(const std::string& cacheDir);
 | 
			
		||||
        ~GlobalMap();
 | 
			
		||||
 | 
			
		||||
        void render(Loading::Listener* loadingListener);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -29,13 +30,13 @@ namespace MWRender
 | 
			
		|||
        int getHeight() { return mHeight; }
 | 
			
		||||
 | 
			
		||||
        void worldPosToImageSpace(float x, float z, float& imageX, float& imageY);
 | 
			
		||||
        ///< @param x x ogre coords
 | 
			
		||||
        /// @param z z ogre coords
 | 
			
		||||
 | 
			
		||||
        void cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY);
 | 
			
		||||
 | 
			
		||||
        void exploreCell (int cellX, int cellY);
 | 
			
		||||
 | 
			
		||||
        virtual void loadResource(Ogre::Resource* resource);
 | 
			
		||||
 | 
			
		||||
        /// Clears the overlay
 | 
			
		||||
        void clear();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +49,7 @@ namespace MWRender
 | 
			
		|||
        std::vector< std::pair<int,int> > mExploredCells;
 | 
			
		||||
 | 
			
		||||
        Ogre::TexturePtr mOverlayTexture;
 | 
			
		||||
        Ogre::Image mOverlayImage; // Backup in system memory
 | 
			
		||||
 | 
			
		||||
        int mWidth;
 | 
			
		||||
        int mHeight;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -324,6 +324,7 @@ void LocalMap::createFogOfWar(const std::string& texturePrefix)
 | 
			
		|||
    buffer.resize(sFogOfWarResolution*sFogOfWarResolution, 0xFF000000);
 | 
			
		||||
 | 
			
		||||
    // upload to the texture
 | 
			
		||||
    tex->load();
 | 
			
		||||
    memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &buffer[0], sFogOfWarResolution*sFogOfWarResolution*4);
 | 
			
		||||
    tex->getBuffer()->unlock();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,8 +61,6 @@ namespace MWRender
 | 
			
		|||
         * Set the position & direction of the player.
 | 
			
		||||
         * @remarks This is used to draw a "fog of war" effect
 | 
			
		||||
         * to hide areas on the map the player has not discovered yet.
 | 
			
		||||
         * @param position (OGRE coordinates)
 | 
			
		||||
         * @param camera orientation (OGRE coordinates)
 | 
			
		||||
         */
 | 
			
		||||
        void updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +72,7 @@ namespace MWRender
 | 
			
		|||
 | 
			
		||||
        /**
 | 
			
		||||
         * Get the interior map texture index and normalized position
 | 
			
		||||
         * on this texture, given a world position (in ogre coordinates)
 | 
			
		||||
         * on this texture, given a world position
 | 
			
		||||
         */
 | 
			
		||||
        void getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -784,6 +784,13 @@ namespace MWWorld
 | 
			
		|||
        mMovementQueue.push_back(std::make_pair(ptr, movement));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void PhysicsSystem::clearQueuedMovement()
 | 
			
		||||
    {
 | 
			
		||||
        mMovementQueue.clear();
 | 
			
		||||
        mCollisions.clear();
 | 
			
		||||
        mStandingCollisions.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const PtrVelocityList& PhysicsSystem::applyQueuedMovement(float dt)
 | 
			
		||||
    {
 | 
			
		||||
        // Collision events are only tracked for a single frame, so reset first
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,8 +85,12 @@ namespace MWWorld
 | 
			
		|||
            /// be overwritten. Valid until the next call to applyQueuedMovement.
 | 
			
		||||
            void queueObjectMovement(const Ptr &ptr, const Ogre::Vector3 &velocity);
 | 
			
		||||
 | 
			
		||||
            /// Apply all queued movements, then clear the list.
 | 
			
		||||
            const PtrVelocityList& applyQueuedMovement(float dt);
 | 
			
		||||
 | 
			
		||||
            /// Clear the queued movements list without applying.
 | 
			
		||||
            void clearQueuedMovement();
 | 
			
		||||
 | 
			
		||||
            /// Return true if \a actor has been standing on \a object in this frame
 | 
			
		||||
            /// This will trigger whenever the object is directly below the actor.
 | 
			
		||||
            /// It doesn't matter if the actor is stationary or moving.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -350,36 +350,59 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
    void World::ensureNeededRecords()
 | 
			
		||||
    {
 | 
			
		||||
        if (!mStore.get<ESM::GameSetting>().search("sCompanionShare"))
 | 
			
		||||
        std::map<std::string, ESM::Variant> gmst;
 | 
			
		||||
        // Companion (tribunal)
 | 
			
		||||
        gmst["sCompanionShare"] = ESM::Variant("Companion Share");
 | 
			
		||||
        gmst["sCompanionWarningMessage"] = ESM::Variant("Warning message");
 | 
			
		||||
        gmst["sCompanionWarningButtonOne"] = ESM::Variant("Button 1");
 | 
			
		||||
        gmst["sCompanionWarningButtonTwo"] = ESM::Variant("Button 2");
 | 
			
		||||
        gmst["sCompanionShare"] = ESM::Variant("Companion Share");
 | 
			
		||||
        gmst["sProfitValue"] = ESM::Variant("Profit Value");
 | 
			
		||||
        gmst["sTeleportDisabled"] = ESM::Variant("Teleport disabled");
 | 
			
		||||
        gmst["sLevitateDisabled"] = ESM::Variant("Levitate disabled");
 | 
			
		||||
 | 
			
		||||
        // Missing in unpatched MW 1.0
 | 
			
		||||
        gmst["sDifficulty"] = ESM::Variant("Difficulty");
 | 
			
		||||
        gmst["fDifficultyMult"] = ESM::Variant(5.f);
 | 
			
		||||
        gmst["sAuto_Run"] = ESM::Variant("Auto Run");
 | 
			
		||||
        gmst["sServiceRefusal"] = ESM::Variant("Service Refusal");
 | 
			
		||||
        gmst["sNeedOneSkill"] = ESM::Variant("Need one skill");
 | 
			
		||||
        gmst["sNeedTwoSkills"] = ESM::Variant("Need two skills");
 | 
			
		||||
        gmst["sEasy"] = ESM::Variant("Easy");
 | 
			
		||||
        gmst["sHard"] = ESM::Variant("Hard");
 | 
			
		||||
        gmst["sDeleteNote"] = ESM::Variant("Delete Note");
 | 
			
		||||
        gmst["sEditNote"] = ESM::Variant("Edit Note");
 | 
			
		||||
 | 
			
		||||
        // Werewolf (BM)
 | 
			
		||||
        gmst["fWereWolfRunMult"] = ESM::Variant(1.f);
 | 
			
		||||
        gmst["fWereWolfSilverWeaponDamageMult"] = ESM::Variant(1.f);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        std::map<std::string, ESM::Variant> globals;
 | 
			
		||||
        // vanilla Morrowind does not define dayspassed.
 | 
			
		||||
        globals["dayspassed"] = ESM::Variant(1); // but the addons start counting at 1 :(
 | 
			
		||||
        globals["WerewolfClawMult"] = ESM::Variant(1.f);
 | 
			
		||||
 | 
			
		||||
        for (std::map<std::string, ESM::Variant>::iterator it = gmst.begin(); it != gmst.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            ESM::GameSetting sCompanionShare;
 | 
			
		||||
            sCompanionShare.mId = "sCompanionShare";
 | 
			
		||||
            ESM::Variant value;
 | 
			
		||||
            value.setType(ESM::VT_String);
 | 
			
		||||
            value.setString("Companion Share");
 | 
			
		||||
            sCompanionShare.mValue = value;
 | 
			
		||||
            mStore.insertStatic(sCompanionShare);
 | 
			
		||||
            if (!mStore.get<ESM::GameSetting>().search(it->first))
 | 
			
		||||
            {
 | 
			
		||||
                ESM::GameSetting setting;
 | 
			
		||||
                setting.mId = it->first;
 | 
			
		||||
                setting.mValue = it->second;
 | 
			
		||||
                mStore.insertStatic(setting);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!mStore.get<ESM::Global>().search("dayspassed"))
 | 
			
		||||
 | 
			
		||||
        for (std::map<std::string, ESM::Variant>::iterator it = globals.begin(); it != globals.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            // vanilla Morrowind does not define dayspassed.
 | 
			
		||||
            ESM::Global dayspassed;
 | 
			
		||||
            dayspassed.mId = "dayspassed";
 | 
			
		||||
            ESM::Variant value;
 | 
			
		||||
            value.setType(ESM::VT_Long);
 | 
			
		||||
            value.setInteger(1); // but the addons start counting at 1 :(
 | 
			
		||||
            dayspassed.mValue = value;
 | 
			
		||||
            mStore.insertStatic(dayspassed);
 | 
			
		||||
        }
 | 
			
		||||
        if (!mStore.get<ESM::GameSetting>().search("fWereWolfRunMult"))
 | 
			
		||||
        {
 | 
			
		||||
            ESM::GameSetting fWereWolfRunMult;
 | 
			
		||||
            fWereWolfRunMult.mId = "fWereWolfRunMult";
 | 
			
		||||
            ESM::Variant value;
 | 
			
		||||
            value.setType(ESM::VT_Float);
 | 
			
		||||
            value.setFloat(1.f);
 | 
			
		||||
            fWereWolfRunMult.mValue = value;
 | 
			
		||||
            mStore.insertStatic(fWereWolfRunMult);
 | 
			
		||||
            if (!mStore.get<ESM::Global>().search(it->first))
 | 
			
		||||
            {
 | 
			
		||||
                ESM::Global setting;
 | 
			
		||||
                setting.mId = it->first;
 | 
			
		||||
                setting.mValue = it->second;
 | 
			
		||||
                mStore.insertStatic(setting);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -840,6 +863,8 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
    void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
 | 
			
		||||
    {
 | 
			
		||||
        mPhysics->clearQueuedMovement();
 | 
			
		||||
 | 
			
		||||
        if (mCurrentWorldSpace != cellName)
 | 
			
		||||
        {
 | 
			
		||||
            // changed worldspace
 | 
			
		||||
| 
						 | 
				
			
			@ -855,6 +880,8 @@ namespace MWWorld
 | 
			
		|||
 | 
			
		||||
    void World::changeToExteriorCell (const ESM::Position& position)
 | 
			
		||||
    {
 | 
			
		||||
        mPhysics->clearQueuedMovement();
 | 
			
		||||
 | 
			
		||||
        if (mCurrentWorldSpace != "sys::default") // FIXME
 | 
			
		||||
        {
 | 
			
		||||
            // changed worldspace
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -205,7 +205,7 @@ namespace MWWorld
 | 
			
		|||
            virtual bool isCellQuasiExterior() const;
 | 
			
		||||
 | 
			
		||||
            virtual Ogre::Vector2 getNorthVector (CellStore* cell);
 | 
			
		||||
            ///< get north vector (OGRE coordinates) for given interior cell
 | 
			
		||||
            ///< get north vector for given interior cell
 | 
			
		||||
 | 
			
		||||
            virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector<DoorMarker>& out);
 | 
			
		||||
            ///< get a list of teleport door markers for a given cell, to be displayed on the local map
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ public:
 | 
			
		|||
  //  indirectly to the load() method.
 | 
			
		||||
  int mIdx;
 | 
			
		||||
  void setIndex(const int index) {mIdx = index; mCtx.index = index;}
 | 
			
		||||
  const int getIndex() {return mIdx;}
 | 
			
		||||
  int getIndex() {return mIdx;}
 | 
			
		||||
 | 
			
		||||
  void setGlobalReaderList(std::vector<ESMReader> *list) {mGlobalReaderList = list;}
 | 
			
		||||
  std::vector<ESMReader> *getGlobalReaderList() {return mGlobalReaderList;}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,30 @@ namespace
 | 
			
		|||
 | 
			
		||||
ESM::Variant::Variant() : mType (VT_None), mData (0) {}
 | 
			
		||||
 | 
			
		||||
ESM::Variant::Variant(const std::string &value)
 | 
			
		||||
{
 | 
			
		||||
    mData = 0;
 | 
			
		||||
    mType = VT_None;
 | 
			
		||||
    setType(VT_String);
 | 
			
		||||
    setString(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM::Variant::Variant(int value)
 | 
			
		||||
{
 | 
			
		||||
    mData = 0;
 | 
			
		||||
    mType = VT_None;
 | 
			
		||||
    setType(VT_Long);
 | 
			
		||||
    setInteger(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM::Variant::Variant(float value)
 | 
			
		||||
{
 | 
			
		||||
    mData = 0;
 | 
			
		||||
    mType = VT_None;
 | 
			
		||||
    setType(VT_Float);
 | 
			
		||||
    setFloat(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM::Variant::~Variant()
 | 
			
		||||
{
 | 
			
		||||
    delete mData;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,10 @@ namespace ESM
 | 
			
		|||
 | 
			
		||||
            Variant();
 | 
			
		||||
 | 
			
		||||
            Variant (const std::string& value);
 | 
			
		||||
            Variant (int value);
 | 
			
		||||
            Variant (float value);
 | 
			
		||||
 | 
			
		||||
            ~Variant();
 | 
			
		||||
 | 
			
		||||
            Variant& operator= (const Variant& variant);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,9 +118,6 @@ ObjectScene::~ObjectScene()
 | 
			
		|||
 | 
			
		||||
void ObjectScene::setVisibilityFlags (unsigned int flags)
 | 
			
		||||
{
 | 
			
		||||
    if (mSkelBase)
 | 
			
		||||
        mSkelBase->setVisibilityFlags (flags);
 | 
			
		||||
 | 
			
		||||
    for (std::vector<Ogre::Entity*>::iterator iter (mEntities.begin()); iter!=mEntities.end();
 | 
			
		||||
        ++iter)
 | 
			
		||||
        (*iter)->setVisibilityFlags (flags);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,7 +79,7 @@ void Manager::saveUser(const std::string& file)
 | 
			
		|||
    fout.close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::string Manager::getString (const std::string& setting, const std::string& category)
 | 
			
		||||
std::string Manager::getString (const std::string& setting, const std::string& category)
 | 
			
		||||
{
 | 
			
		||||
    if (mNewSettings.find(std::make_pair(category, setting)) != mNewSettings.end())
 | 
			
		||||
        return mNewSettings[std::make_pair(category, setting)];
 | 
			
		||||
| 
						 | 
				
			
			@ -92,17 +92,17 @@ const std::string Manager::getString (const std::string& setting, const std::str
 | 
			
		|||
    return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const float Manager::getFloat (const std::string& setting, const std::string& category)
 | 
			
		||||
float Manager::getFloat (const std::string& setting, const std::string& category)
 | 
			
		||||
{
 | 
			
		||||
    return Ogre::StringConverter::parseReal( getString(setting, category) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const int Manager::getInt (const std::string& setting, const std::string& category)
 | 
			
		||||
int Manager::getInt (const std::string& setting, const std::string& category)
 | 
			
		||||
{
 | 
			
		||||
    return Ogre::StringConverter::parseInt( getString(setting, category) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const bool Manager::getBool (const std::string& setting, const std::string& category)
 | 
			
		||||
bool Manager::getBool (const std::string& setting, const std::string& category)
 | 
			
		||||
{
 | 
			
		||||
    return Ogre::StringConverter::parseBool( getString(setting, category) );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,10 +36,10 @@ namespace Settings
 | 
			
		|||
        static const CategorySettingVector apply();
 | 
			
		||||
        ///< returns the list of changed settings and then clears it
 | 
			
		||||
 | 
			
		||||
        static const int getInt (const std::string& setting, const std::string& category);
 | 
			
		||||
        static const float getFloat (const std::string& setting, const std::string& category);
 | 
			
		||||
        static const std::string getString (const std::string& setting, const std::string& category);
 | 
			
		||||
        static const bool getBool (const std::string& setting, const std::string& category);
 | 
			
		||||
        static int getInt (const std::string& setting, const std::string& category);
 | 
			
		||||
        static float getFloat (const std::string& setting, const std::string& category);
 | 
			
		||||
        static std::string getString (const std::string& setting, const std::string& category);
 | 
			
		||||
        static bool getBool (const std::string& setting, const std::string& category);
 | 
			
		||||
 | 
			
		||||
        static void setInt (const std::string& setting, const std::string& category, const int value);
 | 
			
		||||
        static void setFloat (const std::string& setting, const std::string& category, const float value);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue