virtual void execute (Interpreter::Runtime& runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

                    Interpreter::Type_Float x = runtime[0].mFloat;
                    runtime.pop();
                    Interpreter::Type_Float y = runtime[0].mFloat;
                    runtime.pop();
                    Interpreter::Type_Float z = runtime[0].mFloat;
                    runtime.pop();
                    Interpreter::Type_Float zRot = runtime[0].mFloat;
                    runtime.pop();
                    int cx,cy;
                    MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
                    MWBase::Environment::get().getWorld()->moveObject(ptr,
                        *MWBase::Environment::get().getWorld()->getExterior(cx,cy),x,y,z);
                    float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees();
                    float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees();
                    if(ptr.getTypeName() == typeid(ESM::NPC).name())//some morrowind oddity
                    {
                        ax = ax/60.;
                        ay = ay/60.;
                        zRot = zRot/60.;
                    }
                    MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
                }
예제 #2
0
    void InventoryWindow::pickUpObject (MWWorld::Ptr object)
    {
        /// \todo scripts

        // make sure the object is of a type that can be picked up
        std::string type = object.getTypeName();
        if ( (type != typeid(ESM::Apparatus).name())
            && (type != typeid(ESM::Armor).name())
            && (type != typeid(ESM::Book).name())
            && (type != typeid(ESM::Clothing).name())
            && (type != typeid(ESM::Ingredient).name())
            && (type != typeid(ESM::Light).name())
            && (type != typeid(ESM::Miscellaneous).name())
            && (type != typeid(ESM::Tool).name())
            && (type != typeid(ESM::Probe).name())
            && (type != typeid(ESM::Repair).name())
            && (type != typeid(ESM::Weapon).name())
            && (type != typeid(ESM::Potion).name()))
            return;

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

        int count = object.getRefData().getCount();

        // add to player inventory
        // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
        MWWorld::Ptr newObject = *MWWorld::Class::get (player).getContainerStore (player).add (object);
        // remove from world
        MWBase::Environment::get().getWorld()->deleteObject (object);

        mDragAndDrop->mIsOnDragAndDrop = true;
        mDragAndDrop->mDraggedCount = count;

        std::string path = std::string("icons\\");
        path += MWWorld::Class::get(newObject).getInventoryIcon(newObject);
        MyGUI::ImageBox* baseWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
        baseWidget->detachFromWidget();
        baseWidget->attachToWidget(mDragAndDrop->mDragAndDropWidget);
        baseWidget->setUserData(newObject);
        mDragAndDrop->mDraggedWidget = baseWidget;
        ImageBox* image = baseWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
        int pos = path.rfind(".");
        path.erase(pos);
        path.append(".dds");
        image->setImageTexture(path);
        image->setNeedMouseFocus(false);

        // text widget that shows item count
        MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
        text->setTextAlign(MyGUI::Align::Right);
        text->setNeedMouseFocus(false);
        text->setTextShadow(true);
        text->setTextShadowColour(MyGUI::Colour(0,0,0));
        text->setCaption(getCountString(count));
        mDragAndDrop->mDraggedFrom = this;
    }
예제 #3
0
    float ratePotion (const MWWorld::Ptr &item, const MWWorld::Ptr& actor)
    {
        if (item.getTypeName() != typeid(ESM::Potion).name())
            return 0.f;

        const ESM::Potion* potion = item.get<ESM::Potion>()->mBase;
        return rateEffects(potion->mEffects, actor, MWWorld::Ptr());
    }
예제 #4
0
 bool CreatureStats::getCreatureTargetted() const
 {
     MWWorld::Ptr targetPtr;
     if (mAiSequence.getCombatTarget(targetPtr))
     {
         return targetPtr.getTypeName() == typeid(ESM::Creature).name();
     }
     return false;
 }
예제 #5
0
void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
{
    if (!mObjectRoot)
        return;

    MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
    MWWorld::ContainerStoreIterator it = inv.getSlot(slot);

    if (it == inv.end())
    {
        scene.reset();
        return;
    }
    MWWorld::Ptr item = *it;

    std::string bonename;
    if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
        bonename = "Weapon Bone";
    else
        bonename = "Shield Bone";

    osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item));
    osg::ref_ptr<osg::Node> attached = SceneUtil::attach(node, mObjectRoot, bonename, bonename);
    mResourceSystem->getSceneManager()->notifyAttached(attached);
    if (mSkeleton)
        mSkeleton->markDirty();

    scene.reset(new PartHolder(attached));

    if (!item.getClass().getEnchantment(item).empty())
        addGlow(attached, getEnchantmentColor(item));

    // Crossbows start out with a bolt attached
    // FIXME: code duplicated from NpcAnimation
    if (slot == MWWorld::InventoryStore::Slot_CarriedRight &&
            item.getTypeName() == typeid(ESM::Weapon).name() &&
            item.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow)
    {
        MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
        if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt)
            attachArrow();
        else
            mAmmunition.reset();
    }
    else
        mAmmunition.reset();

    boost::shared_ptr<SceneUtil::ControllerSource> source;

    if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
        source = mWeaponAnimationTime;
    else
        source.reset(new NullAnimationTime);

    SceneUtil::AssignControllerSourcesVisitor assignVisitor(source);
    attached->accept(assignVisitor);
}
예제 #6
0
파일: player.cpp 프로젝트: stradian/openmw
    void Player::use()
    {
        MWWorld::InventoryStore& store = MWWorld::Class::get(getPlayer()).getInventoryStore(getPlayer());
        MWWorld::ContainerStoreIterator equipped = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);

        if (getDrawState() == MWMechanics::DrawState_Weapon)
        {
            if (equipped != store.end())
            {
                MWWorld::Ptr item = *equipped;
                MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(getPlayer());
                MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject();

                if (anim->isPriorityActive(MWMechanics::Priority_Weapon))
                    return;

                std::string resultMessage, resultSound;

                if (item.getTypeName() == typeid(ESM::Lockpick).name())
                {
                    if (!target.isEmpty())
                        MWMechanics::Security(getPlayer()).pickLock(target, item, resultMessage, resultSound);
                    anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "start", "stop", 0.0, 0);
                }
                else if (item.getTypeName() == typeid(ESM::Probe).name())
                {
                    if (!target.isEmpty())
                        MWMechanics::Security(getPlayer()).probeTrap(target, item, resultMessage, resultSound);
                    anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "start", "stop", 0.0, 0);
                }

                if (!resultMessage.empty())
                    MWBase::Environment::get().getWindowManager()->messageBox(resultMessage);
                if (!resultSound.empty())
                    MWBase::Environment::get().getSoundManager()->playSound(resultSound,1,1);

                // tool used up?
                if (!item.getRefData().getCount())
                    MWBase::Environment::get().getWindowManager()->unsetSelectedWeapon();
                else
                    MWBase::Environment::get().getWindowManager()->setSelectedWeapon(item);
            }
        }
    }
예제 #7
0
 bool CreatureStats::getCreatureTargetted() const
 {
     std::string target;
     if (mAiSequence.getCombatTarget(target))
     {
         MWWorld::Ptr targetPtr;
         targetPtr = MWBase::Environment::get().getWorld()->getPtr(target, true);
         return targetPtr.getTypeName() == typeid(ESM::Creature).name();
     }
     return false;
 }
예제 #8
0
bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{
    PtrControllerMap::iterator iter = mObjects.find(ptr);
    if(iter != mObjects.end())
    {
        return iter->second->playGroup(groupName, mode, number);
    }
    else
    {
        std::cerr<< "Error in Objects::playAnimationGroup:  Unable to find " << ptr.getTypeName() << std::endl;
        return false;
    }
}
예제 #9
0
    void InventoryWindow::pickUpObject (MWWorld::Ptr object)
    {
        // If the inventory is not yet enabled, don't pick anything up
        if (!MWBase::Environment::get().getWindowManager()->isAllowed(GW_Inventory))
            return;
        // make sure the object is of a type that can be picked up
        std::string type = object.getTypeName();
        if ( (type != typeid(ESM::Apparatus).name())
            && (type != typeid(ESM::Armor).name())
            && (type != typeid(ESM::Book).name())
            && (type != typeid(ESM::Clothing).name())
            && (type != typeid(ESM::Ingredient).name())
            && (type != typeid(ESM::Light).name())
            && (type != typeid(ESM::Miscellaneous).name())
            && (type != typeid(ESM::Lockpick).name())
            && (type != typeid(ESM::Probe).name())
            && (type != typeid(ESM::Repair).name())
            && (type != typeid(ESM::Weapon).name())
            && (type != typeid(ESM::Potion).name()))
            return;

        if (object.getClass().getName(object) == "") // objects without name presented to user can never be picked up
            return;

        int count = object.getRefData().getCount();

        MWWorld::Ptr player = MWMechanics::getPlayer();
        MWBase::Environment::get().getWorld()->breakInvisibility(player);

        MWBase::Environment::get().getMechanicsManager()->itemTaken(player, object, MWWorld::Ptr(), count);

        // add to player inventory
        // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
        MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player);
        // remove from world
        MWBase::Environment::get().getWorld()->deleteObject (object);

        // get ModelIndex to the item
        mTradeModel->update();
        size_t i=0;
        for (; i<mTradeModel->getItemCount(); ++i)
        {
            if (mTradeModel->getItem(i).mBase == newObject)
                break;
        }
        if (i == mTradeModel->getItemCount())
            throw std::runtime_error("Added item not found");
        mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);

        MWBase::Environment::get().getWindowManager()->updateSpellWindow();
    }
                virtual void execute (Interpreter::Runtime& runtime)
                {
                    MWWorld::Ptr ptr = R()(runtime);

                    Interpreter::Type_Float x = runtime[0].mFloat;
                    runtime.pop();
                    Interpreter::Type_Float y = runtime[0].mFloat;
                    runtime.pop();
                    Interpreter::Type_Float z = runtime[0].mFloat;
                    runtime.pop();
                    Interpreter::Type_Float zRot = runtime[0].mFloat;
                    runtime.pop();
                    std::string cellID = runtime.getStringLiteral (runtime[0].mInteger);
                    runtime.pop();

                    MWWorld::CellStore* store = 0;
                    try
                    {
                        store = MWBase::Environment::get().getWorld()->getInterior(cellID);
                    }
                    catch(std::exception &e)
                    {
                        const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID);
                        if(cell)
                        {
                            int cx,cy;
                            MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
                            store = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
                        }
                    }
                    if(store)
                    {
                        MWBase::Environment::get().getWorld()->moveObject(ptr,*store,x,y,z);
                        float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees();
                        float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees();
                        if(ptr.getTypeName() == typeid(ESM::NPC).name())//some morrowind oddity
                        {
                            ax = ax/60.;
                            ay = ay/60.;
                            zRot = zRot/60.;
                        }
                        MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
                    }
                    else
                    {
                        throw std::runtime_error ("unknown cell");
                    }
                }
예제 #11
0
파일: animation.cpp 프로젝트: Chiur/openmw
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model)
  : Animation(ptr, ptr.getRefData().getBaseNode())
{
    setObjectRoot(model, false);

    Ogre::Vector3 extents = getWorldBounds().getSize();
    float size = std::max(std::max(extents.x, extents.y), extents.z);

    bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) &&
                 Settings::Manager::getBool("limit small object distance", "Viewing distance");
    // do not fade out doors. that will cause holes and look stupid
    if(ptr.getTypeName().find("Door") != std::string::npos)
        small = false;

    float dist = small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0.0f;
    Ogre::Vector3 col = getEnchantmentColor(ptr);
    setRenderProperties(mObjectRoot, (mPtr.getTypeName() == typeid(ESM::Static).name()) ?
                                     (small ? RV_StaticsSmall : RV_Statics) : RV_Misc,
                        RQG_Main, RQG_Alpha, dist, !ptr.getClass().getEnchantment(ptr).empty(), &col);
}
예제 #12
0
파일: actors.cpp 프로젝트: jjphatt/openmw
void Actors::adjustMagicEffects (const MWWorld::Ptr& creature)
{
    CreatureStats& creatureStats =  MWWorld::Class::get (creature).getCreatureStats (creature);

    MagicEffects now = creatureStats.mSpells.getMagicEffects();

    if (creature.getTypeName()==typeid (ESM::NPC).name())
    {
        MWWorld::InventoryStore& store = MWWorld::Class::get (creature).getInventoryStore (creature);
        now += store.getMagicEffects();
    }

    now += creatureStats.mActiveSpells.getMagicEffects();

    MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now);

    creatureStats.mMagicEffects = now;

    // TODO apply diff to other stats
}
예제 #13
0
    bool SortFilterItemModel::filterAccepts (const ItemStack& item)
    {
        MWWorld::Ptr base = item.mBase;

        int category = 0;
        if (base.getTypeName() == typeid(ESM::Armor).name()
                || base.getTypeName() == typeid(ESM::Clothing).name())
            category = Category_Apparel;
        else if (base.getTypeName() == typeid(ESM::Weapon).name())
            category = Category_Weapon;
        else if (base.getTypeName() == typeid(ESM::Ingredient).name()
                     || base.getTypeName() == typeid(ESM::Potion).name())
            category = Category_Magic;
        else if (base.getTypeName() == typeid(ESM::Miscellaneous).name()
                 || base.getTypeName() == typeid(ESM::Ingredient).name()
                 || base.getTypeName() == typeid(ESM::Repair).name()
                 || base.getTypeName() == typeid(ESM::Lockpick).name()
                 || base.getTypeName() == typeid(ESM::Light).name()
                 || base.getTypeName() == typeid(ESM::Apparatus).name()
                 || base.getTypeName() == typeid(ESM::Book).name()
                 || base.getTypeName() == typeid(ESM::Probe).name())
            category = Category_Misc;

        if (item.mFlags & ItemStack::Flag_Enchanted)
            category |= Category_Magic;

        if (!(category & mCategory))
            return false;

        if ((mFilter & Filter_OnlyIngredients) && base.getTypeName() != typeid(ESM::Ingredient).name())
            return false;
        if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted))
            return false;
        if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name()
                                                     || base.getCellRef().getSoul() == ""))
            return false;
        if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted
                                               || (base.getTypeName() != typeid(ESM::Armor).name()
                                                   && base.getTypeName() != typeid(ESM::Clothing).name()
                                                   && base.getTypeName() != typeid(ESM::Weapon).name()
                                                   && base.getTypeName() != typeid(ESM::Book).name())))
            return false;
        if ((mFilter & Filter_OnlyEnchantable) && base.getTypeName() == typeid(ESM::Book).name()
                && !base.get<ESM::Book>()->mBase->mData.mIsScroll)
            return false;

        if ((mFilter & Filter_OnlyUsableItems) && base.getClass().getScript(base).empty())
        {
            boost::shared_ptr<MWWorld::Action> actionOnUse = base.getClass().use(base);
            if (!actionOnUse || actionOnUse->isNullAction())
                return false;
        }

        if ((mFilter & Filter_OnlyRepairable) && (
                    !base.getClass().hasItemHealth(base)
                    || (base.getClass().getItemHealth(base) == base.getClass().getItemMaxHealth(base))
                    || (base.getTypeName() != typeid(ESM::Weapon).name()
                        && base.getTypeName() != typeid(ESM::Armor).name())))
            return false;

        if (mFilter & Filter_OnlyRechargable)
        {
            if (!(item.mFlags & ItemStack::Flag_Enchanted))
                return false;

            std::string enchId = base.getClass().getEnchantment(base);
            const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().search(enchId);
            if (!ench)
            {
                std::cerr << "Warning: Can't find enchantment '" << enchId << "' on item " << base.getCellRef().getRefId() << std::endl;
                return false;
            }

            if (base.getCellRef().getEnchantmentCharge() >= ench->mData.mCharge
                    || base.getCellRef().getEnchantmentCharge() == -1)
                return false;
        }

        return true;
    }
예제 #14
0
파일: objects.cpp 프로젝트: darkf/openmw
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light)
{
    Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
    assert(insert);

    Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
    NifOgre::ObjectList objects = NifOgre::Loader::createObjects(insert, mesh);
    for(size_t i = 0;i < objects.mEntities.size();i++)
        bounds.merge(objects.mEntities[i]->getWorldBoundingBox(true));

    Ogre::Vector3 extents = bounds.getSize();
    extents *= insert->getScale();
    float size = std::max(std::max(extents.x, extents.y), extents.z);

    bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance");

    // do not fade out doors. that will cause holes and look stupid
    if (ptr.getTypeName().find("Door") != std::string::npos)
        small = false;

    if (mBounds.find(ptr.getCell()) == mBounds.end())
        mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
    mBounds[ptr.getCell()].merge(bounds);

    bool anyTransparency = false;
    for(size_t i = 0;!anyTransparency && i < objects.mEntities.size();i++)
    {
        Ogre::Entity *ent = objects.mEntities[i];
        for(unsigned int i=0;!anyTransparency && i < ent->getNumSubEntities(); ++i)
        {
            anyTransparency = ent->getSubEntity(i)->getMaterial()->isTransparent();
        }
    }

    if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") ||
       anyTransparency || objects.mParticles.size() > 0)
    {
        for(size_t i = 0;i < objects.mEntities.size();i++)
        {
            Ogre::Entity *ent = objects.mEntities[i];
            for(unsigned int i=0; i < ent->getNumSubEntities(); ++i)
            {
                Ogre::SubEntity* subEnt = ent->getSubEntity(i);
                subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
            }
            ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
            ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
        }
        for(size_t i = 0;i < objects.mParticles.size();i++)
        {
            Ogre::ParticleSystem *part = objects.mParticles[i];
            // TODO: Check the particle system's material for actual transparency
            part->setRenderQueueGroup(RQG_Alpha);
            part->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
            part->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
        }
    }
    else
    {
        Ogre::StaticGeometry* sg = 0;

        if (small)
        {
            if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end())
            {
                uniqueID = uniqueID +1;
                sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
                mStaticGeometrySmall[ptr.getCell()] = sg;

                sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance"));
            }
            else
                sg = mStaticGeometrySmall[ptr.getCell()];
        }
        else
        {
            if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end())
            {

                uniqueID = uniqueID +1;
                sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
                mStaticGeometry[ptr.getCell()] = sg;
            }
            else
                sg = mStaticGeometry[ptr.getCell()];
        }

        // This specifies the size of a single batch region.
        // If it is set too high:
        //  - there will be problems choosing the correct lights
        //  - the culling will be more inefficient
        // If it is set too low:
        //  - there will be too many batches.
        sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500));

        sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics);

        sg->setCastShadows(true);

        sg->setRenderQueueGroup(RQG_Main);

        std::vector<Ogre::Entity*>::reverse_iterator iter = objects.mEntities.rbegin();
        while(iter != objects.mEntities.rend())
        {
            Ogre::Node *node = (*iter)->getParentNode();
            sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale());

            (*iter)->detachFromParent();
            mRenderer.getScene()->destroyEntity(*iter);
            iter++;
        }
    }

    if (light)
    {
        insertLight(ptr, objects.mSkelBase, bounds.getCenter() - insert->_getDerivedPosition());
    }
}
예제 #15
0
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
{
    Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
    assert(insert);

    Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
    NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(insert, NULL, mesh);
    for(size_t i = 0;i < entities.mEntities.size();i++)
    {
        const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox();
        bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(),
                                          insert->_getDerivedPosition() + tmp.getMaximum())
        );
    }
    Ogre::Vector3 extents = bounds.getSize();
    extents *= insert->getScale();
    float size = std::max(std::max(extents.x, extents.y), extents.z);

    bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance");

    // do not fade out doors. that will cause holes and look stupid
    if (ptr.getTypeName().find("Door") != std::string::npos)
        small = false;

    if (mBounds.find(ptr.getCell()) == mBounds.end())
        mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
    mBounds[ptr.getCell()].merge(bounds);

    bool transparent = false;
    for(size_t i = 0;i < entities.mEntities.size();i++)
    {
        Ogre::Entity *ent = entities.mEntities[i];
        for (unsigned int i=0; i<ent->getNumSubEntities(); ++i)
        {
            Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial();
            Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
            while (techIt.hasMoreElements())
            {
                Ogre::Technique* tech = techIt.getNext();
                Ogre::Technique::PassIterator passIt = tech->getPassIterator();
                while (passIt.hasMoreElements())
                {
                    Ogre::Pass* pass = passIt.getNext();

                    if (pass->getDepthWriteEnabled() == false)
                        transparent = true;
                }
            }
        }
    }

    if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent)
    {
        for(size_t i = 0;i < entities.mEntities.size();i++)
        {
            Ogre::Entity *ent = entities.mEntities[i];

            ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
            ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
            ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
        }
    }
    else
    {
        Ogre::StaticGeometry* sg = 0;

        if (small)
        {
            if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end())
            {
                uniqueID = uniqueID +1;
                sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
                mStaticGeometrySmall[ptr.getCell()] = sg;

                sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance"));
            }
            else
                sg = mStaticGeometrySmall[ptr.getCell()];
        }
        else
        {
            if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end())
            {

                uniqueID = uniqueID +1;
                sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
                mStaticGeometry[ptr.getCell()] = sg;
            }
            else
                sg = mStaticGeometry[ptr.getCell()];
        }

        // This specifies the size of a single batch region.
        // If it is set too high:
        //  - there will be problems choosing the correct lights
        //  - the culling will be more inefficient
        // If it is set too low:
        //  - there will be too many batches.
        sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500));

        sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics);

        sg->setCastShadows(true);

        sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);

        for(size_t i = 0;i < entities.mEntities.size();i++)
        {
            Ogre::Entity *ent = entities.mEntities[i];
            insert->detachObject(ent);
            sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());

            mRenderer.getScene()->destroyEntity(ent);
        }
    }
}
예제 #16
0
    float rateWeapon (const MWWorld::Ptr &item, const MWWorld::Ptr& actor, const MWWorld::Ptr& target, int type,
                      float arrowRating, float boltRating)
    {
        if (item.getTypeName() != typeid(ESM::Weapon).name())
            return 0.f;

        const ESM::Weapon* weapon = item.get<ESM::Weapon>()->mBase;

        if (type != -1 && weapon->mData.mType != type)
            return 0.f;

        float rating=0.f;

        if (weapon->mData.mType >= ESM::Weapon::MarksmanBow)
        {
            rating = (weapon->mData.mChop[0] + weapon->mData.mChop[1]) / 2.f;
        }
        else
        {
            for (int i=0; i<2; ++i)
            {
                rating += weapon->mData.mSlash[i];
                rating += weapon->mData.mThrust[i];
                rating += weapon->mData.mChop[i];
            }
            rating /= 6.f;
        }

        if (item.getClass().hasItemHealth(item))
        {
            if (item.getClass().getItemHealth(item) == 0)
                return 0.f;
            rating *= item.getClass().getItemHealth(item) / float(item.getClass().getItemMaxHealth(item));
        }

        if (weapon->mData.mType == ESM::Weapon::MarksmanBow)
        {
            if (arrowRating <= 0.f)
                rating = 0.f;
            else
                rating += arrowRating;
        }
        else if (weapon->mData.mType == ESM::Weapon::MarksmanCrossbow)
        {
            if (boltRating <= 0.f)
                rating = 0.f;
            else
                rating += boltRating;
        }

        if (!weapon->mEnchant.empty())
        {
            const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(weapon->mEnchant);
            if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes
                    && (item.getCellRef().getEnchantmentCharge() == -1
                        || item.getCellRef().getEnchantmentCharge() >= enchantment->mData.mCost))
                rating += rateEffects(enchantment->mEffects, actor, target);
        }

        int skill = item.getClass().getEquipmentSkill(item);
        if (skill != -1)
            rating *= actor.getClass().getSkill(actor, skill) / 100.f;

        return rating;
    }
예제 #17
0
    bool SortFilterItemModel::filterAccepts (const ItemStack& item)
    {
        MWWorld::Ptr base = item.mBase;

        if (item.mType == ItemStack::Type_Equipped && !mShowEquipped)
            return false;

        int category = 0;
        if (base.getTypeName() == typeid(ESM::Armor).name()
                || base.getTypeName() == typeid(ESM::Clothing).name())
            category = Category_Apparel;
        else if (base.getTypeName() == typeid(ESM::Weapon).name())
            category = Category_Weapon;
        else if (base.getTypeName() == typeid(ESM::Ingredient).name()
                     || base.getTypeName() == typeid(ESM::Potion).name())
            category = Category_Magic;
        else if (base.getTypeName() == typeid(ESM::Miscellaneous).name()
                 || base.getTypeName() == typeid(ESM::Ingredient).name()
                 || base.getTypeName() == typeid(ESM::Repair).name()
                 || base.getTypeName() == typeid(ESM::Lockpick).name()
                 || base.getTypeName() == typeid(ESM::Light).name()
                 || base.getTypeName() == typeid(ESM::Apparatus).name()
                 || base.getTypeName() == typeid(ESM::Book).name()
                 || base.getTypeName() == typeid(ESM::Probe).name())
            category = Category_Misc;

        if (item.mFlags & ItemStack::Flag_Enchanted)
            category |= Category_Magic;

        if (!(category & mCategory))
            return false;

        if ((mFilter & Filter_OnlyIngredients) && base.getTypeName() != typeid(ESM::Ingredient).name())
            return false;
        if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted))
            return false;
        if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name()
                                                     || base.getCellRef().getSoul() == ""))
            return false;
        if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted
                                               || (base.getTypeName() != typeid(ESM::Armor).name()
                                                   && base.getTypeName() != typeid(ESM::Clothing).name()
                                                   && base.getTypeName() != typeid(ESM::Weapon).name()
                                                   && base.getTypeName() != typeid(ESM::Book).name())))
            return false;
        if ((mFilter & Filter_OnlyEnchantable) && base.getTypeName() == typeid(ESM::Book).name()
                && !base.get<ESM::Book>()->mBase->mData.mIsScroll)
            return false;

        if ((mFilter & Filter_OnlyUsableItems) && typeid(*base.getClass().use(base)) == typeid(MWWorld::NullAction)
                && base.getClass().getScript(base).empty())
            return false;

        return true;
    }
예제 #18
0
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const
{
    MWWorld::Ptr player = MWMechanics::getPlayer();

    switch (select.getFunction())
    {
        case SelectWrapper::Function_Journal:

            return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName());

        case SelectWrapper::Function_Item:
        {
            MWWorld::ContainerStore& store = player.getClass().getContainerStore (player);

            return store.count(select.getName());
        }

        case SelectWrapper::Function_Dead:

            return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName());

        case SelectWrapper::Function_Choice:

            return mChoice;

        case SelectWrapper::Function_AiSetting:

            return mActor.getClass().getCreatureStats (mActor).getAiSetting (
                        (MWMechanics::CreatureStats::AiSetting)select.getArgument()).getModified();

        case SelectWrapper::Function_PcAttribute:

            return player.getClass().getCreatureStats (player).
                getAttribute (select.getArgument()).getModified();

        case SelectWrapper::Function_PcSkill:

            return static_cast<int> (player.getClass().
                getNpcStats (player).getSkill (select.getArgument()).getModified());

        case SelectWrapper::Function_FriendlyHit:
        {
            int hits = mActor.getClass().getCreatureStats (mActor).getFriendlyHits();

            return hits>4 ? 4 : hits;
        }

        case SelectWrapper::Function_PcLevel:

            return player.getClass().getCreatureStats (player).getLevel();

        case SelectWrapper::Function_PcGender:

            return player.get<ESM::NPC>()->mBase->isMale() ? 0 : 1;

        case SelectWrapper::Function_PcClothingModifier:
        {
            MWWorld::InventoryStore& store = player.getClass().getInventoryStore (player);

            int value = 0;

            for (int i=0; i<=15; ++i) // everything except things held in hands and ammunition
            {
                MWWorld::ContainerStoreIterator slot = store.getSlot (i);

                if (slot!=store.end())
                    value += slot->getClass().getValue (*slot);
            }

            return value;
        }

        case SelectWrapper::Function_PcCrimeLevel:

            return player.getClass().getNpcStats (player).getBounty();

        case SelectWrapper::Function_RankRequirement:
        {
            std::string faction = mActor.getClass().getPrimaryFaction(mActor);
            if (faction.empty())
                return 0;

            int rank = getFactionRank (player, faction);

            if (rank>=9)
                return 0; // max rank

            int result = 0;

            if (hasFactionRankSkillRequirements (player, faction, rank+1))
                result += 1;

            if (hasFactionRankReputationRequirements (player, faction, rank+1))
                result += 2;

            return result;
        }

        case SelectWrapper::Function_Level:

            return mActor.getClass().getCreatureStats (mActor).getLevel();

        case SelectWrapper::Function_PCReputation:

            return player.getClass().getNpcStats (player).getReputation();

        case SelectWrapper::Function_Weather:

            return MWBase::Environment::get().getWorld()->getCurrentWeather();

        case SelectWrapper::Function_Reputation:

            return mActor.getClass().getNpcStats (mActor).getReputation();

        case SelectWrapper::Function_FactionRankDiff:
        {
            std::string faction = mActor.getClass().getPrimaryFaction(mActor);

            if (faction.empty())
                return 0;

            int rank = getFactionRank (player, faction);
            int npcRank = mActor.getClass().getPrimaryFactionRank(mActor);
            return rank-npcRank;
        }

        case SelectWrapper::Function_WerewolfKills:

            return player.getClass().getNpcStats (player).getWerewolfKills();

        case SelectWrapper::Function_RankLow:
        case SelectWrapper::Function_RankHigh:
        {
            bool low = select.getFunction()==SelectWrapper::Function_RankLow;

            std::string factionId = mActor.getClass().getPrimaryFaction(mActor);

            if (factionId.empty())
                return 0;

            int value = 0;

            MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats (player);

            std::map<std::string, int>::const_iterator playerFactionIt = playerStats.getFactionRanks().begin();
            for (; playerFactionIt != playerStats.getFactionRanks().end(); ++playerFactionIt)
            {
                int reaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(factionId, playerFactionIt->first);
                if (low ? reaction < value : reaction > value)
                    value = reaction;
            }

            return value;
        }

        case SelectWrapper::Function_CreatureTargetted:

            {
                MWWorld::Ptr target;
                mActor.getClass().getCreatureStats(mActor).getAiSequence().getCombatTarget(target);
                if (target)
                {
                    if (target.getClass().isNpc() && target.getClass().getNpcStats(target).isWerewolf())
                        return 2;
                    if (target.getTypeName() == typeid(ESM::Creature).name())
                        return 1;
                }
            }
            return 0;

        default:

            throw std::runtime_error ("unknown integer select function");
    }
}
예제 #19
0
파일: tradewindow.cpp 프로젝트: wix0/openmw
    bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
    {
        int services = 0;
        if (mPtr.getTypeName() == typeid(ESM::NPC).name())
        {
            MWWorld::LiveCellRef<ESM::NPC>* ref = mPtr.get<ESM::NPC>();
            if (ref->mBase->mHasAI)
                services = ref->mBase->mAiData.mServices;
        }
        else if (mPtr.getTypeName() == typeid(ESM::Creature).name())
        {
            MWWorld::LiveCellRef<ESM::Creature>* ref = mPtr.get<ESM::Creature>();
            if (ref->mBase->mHasAI)
                services = ref->mBase->mAiData.mServices;
        }

        /// \todo what about potions, there doesn't seem to be a flag for them??

        if      (item.getTypeName() == typeid(ESM::Weapon).name())
            return services & ESM::NPC::Weapon;
        else if (item.getTypeName() == typeid(ESM::Armor).name())
            return services & ESM::NPC::Armor;
        else if (item.getTypeName() == typeid(ESM::Clothing).name())
            return services & ESM::NPC::Clothing;
        else if (item.getTypeName() == typeid(ESM::Book).name())
            return services & ESM::NPC::Books;
        else if (item.getTypeName() == typeid(ESM::Ingredient).name())
            return services & ESM::NPC::Ingredients;
        else if (item.getTypeName() == typeid(ESM::Tool).name())
            return services & ESM::NPC::Picks;
        else if (item.getTypeName() == typeid(ESM::Probe).name())
            return services & ESM::NPC::Probes;
        else if (item.getTypeName() == typeid(ESM::Light).name())
            return services & ESM::NPC::Lights;
        else if (item.getTypeName() == typeid(ESM::Apparatus).name())
            return services & ESM::NPC::Apparatus;
        else if (item.getTypeName() == typeid(ESM::Repair).name())
            return services & ESM::NPC::RepairItem;
        else if (item.getTypeName() == typeid(ESM::Miscellaneous).name())
            return services & ESM::NPC::Misc;

        return false;
    }