Beispiel #1
0
    void
    Scene::playerCellChange(
        MWWorld::CellStore *cell,
        const ESM::Position& pos,
        bool adjustPlayerPos)
    {
        bool hasWater = cell->cell->data.flags & cell->cell->HasWater;
        mPhysics->setCurrentWater(hasWater, cell->cell->water);

        MWBase::World *world = MWBase::Environment::get().getWorld();
        MWWorld::Ptr player = world->getPlayer().getPlayer();

        if (adjustPlayerPos) {
            world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);
            MWBase::Environment::get().getWorld()->getPlayer().setRot (pos.rot[0], pos.rot[1], pos.rot[2]);
        }
        world->getPlayer().setCell(cell);

        MWMechanics::MechanicsManager *mechMgr =
            MWBase::Environment::get().getMechanicsManager();

        mechMgr->addActor(player);
        mechMgr->watchActor(player);

        MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
    }
Beispiel #2
0
    void Scene::playerCellChange(MWWorld::CellStore *cell, const ESM::Position& pos, bool adjustPlayerPos)
    {
        bool hasWater = cell->mCell->mData.mFlags & ESM::Cell::HasWater;
        mPhysics->setCurrentWater(hasWater, cell->mCell->mWater);

        MWBase::World *world = MWBase::Environment::get().getWorld();
        world->getPlayer().setCell(cell);

        MWWorld::Ptr player = world->getPlayer().getPlayer();

        if (adjustPlayerPos) {
            world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);

            float x = Ogre::Radian(pos.rot[0]).valueDegrees();
            float y = Ogre::Radian(pos.rot[1]).valueDegrees();
            float z = Ogre::Radian(pos.rot[2]).valueDegrees();
            world->rotateObject(player, x, y, z);
        }

        MWBase::MechanicsManager *mechMgr =
            MWBase::Environment::get().getMechanicsManager();

        mechMgr->add(player);
        mechMgr->watchActor(player);

        MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
    }
Beispiel #3
0
    void ActionTeleport::executeImp (const Ptr& actor)
    {
        MWBase::World* world = MWBase::Environment::get().getWorld();

        //find any NPC that is following the actor and teleport him too
        std::list<MWWorld::Ptr> followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor);
        for(std::list<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();it++)
        {
            std::cout << "teleporting someone!" << (*it).getCellRef().mRefID;
            executeImp(*it);
        }

        if(actor == world->getPlayerPtr())
        {
            world->getPlayer().setTeleported(true);
            if (mCellName.empty())
                world->changeToExteriorCell (mPosition);
            else
                world->changeToInteriorCell (mCellName, mPosition);
        }
        else
        {
            if (mCellName.empty())
            {
                int cellX;
                int cellY;
                world->positionToIndex(mPosition.pos[0],mPosition.pos[1],cellX,cellY);
                world->moveObject(actor,world->getExterior(cellX,cellY),
                    mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
            }
            else
                world->moveObject(actor,world->getInterior(mCellName),mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
        }
    }
Beispiel #4
0
    void Actors::updateDrowning(const MWWorld::Ptr& ptr, float duration)
    {
        MWBase::World *world = MWBase::Environment::get().getWorld();
        NpcStats &stats = ptr.getClass().getNpcStats(ptr);
        if(world->isSubmerged(ptr) &&
           stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).mMagnitude == 0)
        {
            float timeLeft = 0.0f;
            if(stats.getFatigue().getCurrent() == 0)
                stats.setTimeToStartDrowning(0);
            else
            {
                timeLeft = stats.getTimeToStartDrowning() - duration;
                if(timeLeft < 0.0f)
                    timeLeft = 0.0f;
                stats.setTimeToStartDrowning(timeLeft);
            }
            if(timeLeft == 0.0f)
            {
                // If drowning, apply 3 points of damage per second
                ptr.getClass().setActorHealth(ptr, stats.getHealth().getCurrent() - 3.0f*duration);

                // Play a drowning sound as necessary for the player
                if(ptr == world->getPlayer().getPlayer())
                {
                    MWBase::SoundManager *sndmgr = MWBase::Environment::get().getSoundManager();
                    if(!sndmgr->getSoundPlaying(MWWorld::Ptr(), "drown"))
                        sndmgr->playSound("drown", 1.0f, 1.0f);
                }
            }
        }
        else
            stats.setTimeToStartDrowning(20);
    }
Beispiel #5
0
    void Scene::playerCellChange(CellStore *cell, const ESM::Position& pos, bool adjustPlayerPos)
    {
        MWBase::World *world = MWBase::Environment::get().getWorld();
        MWWorld::Ptr old = world->getPlayerPtr();
        world->getPlayer().setCell(cell);

        MWWorld::Ptr player = world->getPlayerPtr();
        mRendering.updatePlayerPtr(player);

        if (adjustPlayerPos) {
            world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);

            float x = Ogre::Radian(pos.rot[0]).valueDegrees();
            float y = Ogre::Radian(pos.rot[1]).valueDegrees();
            float z = Ogre::Radian(pos.rot[2]).valueDegrees();
            world->rotateObject(player, x, y, z);

            player.getClass().adjustPosition(player, true);
        }

        MWBase::MechanicsManager *mechMgr =
            MWBase::Environment::get().getMechanicsManager();

        mechMgr->updateCell(old, player);
        mechMgr->watchActor(player);

        mRendering.updateTerrain();

        // Delay the map update until scripts have been given a chance to run.
        // If we don't do this, objects that should be disabled will still appear on the map.
        mNeedMapUpdate = true;

        MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
    }
Beispiel #6
0
 void ActionTeleport::teleport(const Ptr &actor)
 {
     MWBase::World* world = MWBase::Environment::get().getWorld();
     if(actor == world->getPlayerPtr())
     {
         world->getPlayer().setTeleported(true);
         if (mCellName.empty())
             world->changeToExteriorCell (mPosition, true);
         else
             world->changeToInteriorCell (mCellName, mPosition, true);
     }
     else
     {
         if (mCellName.empty())
         {
             int cellX;
             int cellY;
             world->positionToIndex(mPosition.pos[0],mPosition.pos[1],cellX,cellY);
             world->moveObject(actor,world->getExterior(cellX,cellY),
                 mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
         }
         else
             world->moveObject(actor,world->getInterior(mCellName),mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
     }
 }
Beispiel #7
0
    void Scene::changePlayerCell(CellStore *cell, const ESM::Position &pos, bool adjustPlayerPos)
    {
        mCurrentCell = cell;

        MWBase::World *world = MWBase::Environment::get().getWorld();
        MWWorld::Ptr old = world->getPlayerPtr();
        world->getPlayer().setCell(cell);

        MWWorld::Ptr player = world->getPlayerPtr();
        mRendering.updatePlayerPtr(player);

        if (adjustPlayerPos) {
            world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);

            float x = Ogre::Radian(pos.rot[0]).valueDegrees();
            float y = Ogre::Radian(pos.rot[1]).valueDegrees();
            float z = Ogre::Radian(pos.rot[2]).valueDegrees();
            world->rotateObject(player, x, y, z);

            player.getClass().adjustPosition(player, true);
        }

        MWBase::MechanicsManager *mechMgr =
            MWBase::Environment::get().getMechanicsManager();

        mechMgr->updateCell(old, player);
        mechMgr->watchActor(player);

        MWBase::Environment::get().getWorld()->adjustSky();
    }
Beispiel #8
0
    void SoundManager::updateRegionSound(float duration)
    {
        static float sTimeToNextEnvSound = 0.0f;
        static int total = 0;
        static std::string regionName = "";
        static float sTimePassed = 0.0;
        MWBase::World *world = MWBase::Environment::get().getWorld();
        const MWWorld::Ptr player = world->getPlayer().getPlayer();
        const ESM::Cell *cell = player.getCell()->mCell;

        sTimePassed += duration;
        if(!cell->isExterior() || sTimePassed < sTimeToNextEnvSound)
            return;

        float a = std::rand() / (double)RAND_MAX;
        // NOTE: We should use the "Minimum Time Between Environmental Sounds" and
        // "Maximum Time Between Environmental Sounds" fallback settings here.
        sTimeToNextEnvSound = 5.0f*a + 15.0f*(1.0f-a);
        sTimePassed = 0;

        if(regionName != cell->mRegion)
        {
            regionName = cell->mRegion;
            total = 0;
        }

        const ESM::Region *regn = world->getStore().get<ESM::Region>().search(regionName);
        if(regn == NULL)
            return;

        std::vector<ESM::Region::SoundRef>::const_iterator soundIter;
        if(total == 0)
        {
            soundIter = regn->mSoundList.begin();
            while(soundIter != regn->mSoundList.end())
            {
                total += (int)soundIter->mChance;
                ++soundIter;
            }
            if(total == 0)
                return;
        }

        int r = (int)(rand()/((double)RAND_MAX+1) * total);
        int pos = 0;

        soundIter = regn->mSoundList.begin();
        while(soundIter != regn->mSoundList.end())
        {
            if(r - pos < soundIter->mChance)
            {
                playSound(soundIter->mSound.toString(), 1.0f, 1.0f);
                break;
            }
            pos += soundIter->mChance;

            ++soundIter;
        }
    }
Beispiel #9
0
    void HUD::onWorldClicked(MyGUI::Widget* _sender)
    {
        if (!MWBase::Environment::get().getWindowManager ()->isGuiMode ())
            return;

        if (mDragAndDrop->mIsOnDragAndDrop)
        {
            // drop item into the gameworld
            MWWorld::Ptr object = mDragAndDrop->mItem.mBase;

            MWBase::World* world = MWBase::Environment::get().getWorld();

            MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
            MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
            float mouseX = cursorPosition.left / float(viewSize.width);
            float mouseY = cursorPosition.top / float(viewSize.height);

            int origCount = object.getRefData().getCount();
            object.getRefData().setCount(mDragAndDrop->mDraggedCount);

            if (world->canPlaceObject(mouseX, mouseY))
                world->placeObject(object, mouseX, mouseY);
            else
                world->dropObjectOnGround(world->getPlayer().getPlayer(), object);

            MWBase::Environment::get().getWindowManager()->changePointer("arrow");

            std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
            MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);

            object.getRefData().setCount(origCount);

            // remove object from the container it was coming from
            mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
            mDragAndDrop->finish();
        }
        else
        {
            GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode();

            if ( (mode != GM_Console) && (mode != GM_Container) && (mode != GM_Inventory) )
                return;

            MWWorld::Ptr object = MWBase::Environment::get().getWorld()->getFacedObject();

            if (mode == GM_Console)
                MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object);
            else if ((mode == GM_Container) || (mode == GM_Inventory))
            {
                // pick up object
                MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object);
            }
        }
    }
Beispiel #10
0
                virtual void execute (Interpreter::Runtime& runtime)
                {
                    Interpreter::Type_Integer x = runtime[0].mInteger;
                    runtime.pop();

                    Interpreter::Type_Integer y = runtime[0].mInteger;
                    runtime.pop();

                    ESM::Position pos;
                    MWBase::World *world = MWBase::Environment::get().getWorld();
                    world->getPlayer().setTeleported(true);
                    world->indexToPosition (x, y, pos.pos[0], pos.pos[1], true);
                    pos.pos[2] = 0;

                    pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;

                    world->changeToExteriorCell (pos);
                }
Beispiel #11
0
                virtual void execute (Interpreter::Runtime& runtime)
                {
                    std::string cell = runtime.getStringLiteral (runtime[0].mInteger);
                    runtime.pop();

                    ESM::Position pos;
                    MWBase::World *world = MWBase::Environment::get().getWorld();

                    world->getPlayer().setTeleported(true);
                    if (world->findExteriorPosition(cell, pos))
                    {
                        world->changeToExteriorCell(pos);
                    }
                    else
                    {
                        // Change to interior even if findInteriorPosition()
                        // yields false. In this case position will be zero-point.
                        world->findInteriorPosition(cell, pos);
                        world->changeToInteriorCell(cell, pos);
                    }
                }
Beispiel #12
0
    void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
    {

        const MWWorld::Store<ESM::GameSetting> &gmst =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

        std::string loadingInteriorText;
        loadingInteriorText = gmst.find ("sLoadingMessage2")->getString();

        CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName);
        bool loadcell = (mCurrentCell == NULL);
        if(!loadcell)
            loadcell = *mCurrentCell != *cell;

        if(!loadcell)
        {
            MWBase::World *world = MWBase::Environment::get().getWorld();
            world->moveObject(world->getPlayer().getPlayer(), position.pos[0], position.pos[1], position.pos[2]);

            float x = Ogre::Radian(position.rot[0]).valueDegrees();
            float y = Ogre::Radian(position.rot[1]).valueDegrees();
            float z = Ogre::Radian(position.rot[2]).valueDegrees();
            world->rotateObject(world->getPlayer().getPlayer(), x, y, z);
            return;
        }

        std::cout << "Changing to interior\n";

        // remove active
        CellStoreCollection::iterator active = mActiveCells.begin();

        // count number of cells to unload
        int numUnload = 0;
        while (active!=mActiveCells.end())
        {
            ++active;
            ++numUnload;
        }

        // unload
        int current = 0;
        active = mActiveCells.begin();
        while (active!=mActiveCells.end())
        {
            unloadCell (active++);
            ++current;
        }

        // Load cell.
        std::cout << "cellName: " << cell->mCell->mName << std::endl;

        //Loading Interior loading text
        MWBase::Environment::get().getWindowManager ()->setLoadingProgress (loadingInteriorText, 0, 0, 1);

        loadCell (cell);

        mCurrentCell = cell;

        // adjust fog
        mRendering.switchToInterior();
        mRendering.configureFog(*mCurrentCell);

        // adjust player
        playerCellChange (mCurrentCell, position);

        // Sky system
        MWBase::Environment::get().getWorld()->adjustSky();

        mCellChanged = true;

        MWBase::Environment::get().getWindowManager ()->loadingDone ();
    }
Beispiel #13
0
void RenderingManager::update (float duration, bool paused)
{
    MWBase::World *world = MWBase::Environment::get().getWorld();

    MWWorld::Ptr player = world->getPlayer().getPlayer();

    int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude;
    mRendering.getFader()->setFactor(std::max(0.f, 1.f-(blind / 100.f)));
    setAmbientMode();

    // player position
    MWWorld::RefData &data = player.getRefData();
    Ogre::Vector3 playerPos(data.getPosition().pos);

    mCamera->setCameraDistance();
    if(!mCamera->isFirstPerson())
    {
        Ogre::Vector3 orig, dest;
        mCamera->getPosition(orig, dest);

        btVector3 btOrig(orig.x, orig.y, orig.z);
        btVector3 btDest(dest.x, dest.y, dest.z);
        std::pair<bool,float> test = mPhysicsEngine->sphereCast(mRendering.getCamera()->getNearClipDistance()*2.5, btOrig, btDest);
        if(test.first)
            mCamera->setCameraDistance(test.second * orig.distance(dest), false, false);
    }

    mOcclusionQuery->update(duration);

    mVideoPlayer->update ();

    mRendering.update(duration);

    Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f);

    Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();

    applyFog(world->isUnderwater(player.getCell(), cam));

    mCamera->update(duration, paused);

    if(paused)
        return;

    mActors.update (duration);
    mObjects.update (duration);


    mSkyManager->update(duration);

    mSkyManager->setGlare(mOcclusionQuery->getSunVisibility());

    Ogre::SceneNode *node = data.getBaseNode();
    Ogre::Quaternion orient = node->_getDerivedOrientation();

    mLocalMap->updatePlayer(playerPos, orient);

    mWater->updateUnderwater(world->isUnderwater(player.getCell(), cam));

    mWater->update(duration, playerPos);
}
Beispiel #14
0
    bool AiTravel::execute (const MWWorld::Ptr& actor,float duration)
    {
        MWBase::World *world = MWBase::Environment::get().getWorld();
        ESM::Position pos = actor.getRefData().getPosition();
        Movement &movement = actor.getClass().getMovementSettings(actor);
        const ESM::Cell *cell = actor.getCell()->mCell;

        MWWorld::Ptr player = world->getPlayer().getPlayer();
        if(cell->mData.mX != player.getCell()->mCell->mData.mX)
        {
            int sideX = sgn(cell->mData.mX - player.getCell()->mCell->mData.mX);
            //check if actor is near the border of an inactive cell. If so, stop walking.
            if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) >
               sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
            {
                movement.mPosition[1] = 0;
                return false;
            }
        }
        if(cell->mData.mY != player.getCell()->mCell->mData.mY)
        {
            int sideY = sgn(cell->mData.mY - player.getCell()->mCell->mData.mY);
            //check if actor is near the border of an inactive cell. If so, stop walking.
            if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) >
               sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
            {
                movement.mPosition[1] = 0;
                return false;
            }
        }

        const ESM::Pathgrid *pathgrid = world->getStore().get<ESM::Pathgrid>().search(*cell);
        bool cellChange = cell->mData.mX != cellX || cell->mData.mY != cellY;
        if(!mPathFinder.isPathConstructed() || cellChange)
        {
            cellX = cell->mData.mX;
            cellY = cell->mData.mY;
            float xCell = 0;
            float yCell = 0;

            if(cell->isExterior())
            {
                xCell = cell->mData.mX * ESM::Land::REAL_SIZE;
                yCell = cell->mData.mY * ESM::Land::REAL_SIZE;
            }

            ESM::Pathgrid::Point dest;
            dest.mX = mX;
            dest.mY = mY;
            dest.mZ = mZ;

            ESM::Pathgrid::Point start;
            start.mX = pos.pos[0];
            start.mY = pos.pos[1];
            start.mZ = pos.pos[2];

            mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, true);
        }

        if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2]))
        {
            movement.mPosition[1] = 0;
            return true;
        }

        float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]);
        // TODO: use movement settings instead of rotating directly
        world->rotateObject(actor, 0, 0, zAngle, false);
        movement.mPosition[1] = 1;

        return false;
    }