diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index 6a7274e0a..077b62be1 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -7,6 +7,8 @@ #include #include #include +#include + MwIniImporter::MwIniImporter() : mVerbose(false) @@ -793,7 +795,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { for(std::vector::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { std::string filetype(entry->substr(entry->length()-4, 3)); - std::transform(filetype.begin(), filetype.end(), filetype.begin(), ::tolower); + Misc::StringUtils::toLower(filetype); if(filetype.compare("esm") == 0) { esmFiles.push_back(*entry); diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 1b2d1e349..963997924 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -12,6 +12,7 @@ #include #include "columnbase.hpp" +#include namespace CSMWorld { @@ -152,10 +153,7 @@ namespace CSMWorld template void IdCollection::add (const ESXRecordT& record) { - std::string id; - - std::transform (record.mId.begin(), record.mId.end(), std::back_inserter (id), - (int(*)(int)) std::tolower); + std::string id = Misc::StringUtils::lowerCase(record.mId); std::map::iterator iter = mIndex.find (id); @@ -281,10 +279,7 @@ namespace CSMWorld template int IdCollection::searchId (const std::string& id) const { - std::string id2; - - std::transform (id.begin(), id.end(), std::back_inserter (id2), - (int(*)(int)) std::tolower); + std::string id2 = Misc::StringUtils::lowerCase(id); std::map::const_iterator iter = mIndex.find (id2); diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index aadeb7f3a..b19cafab7 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -164,9 +164,6 @@ void OMW::Engine::loadBSA() dataDirectory = iter->string(); std::cout << "Data dir " << dataDirectory << std::endl; Bsa::addDir(dataDirectory, mFSStrict); - - // Workaround until resource listing capabilities are added to DirArchive, we need those to list available splash screens - addResourcesDirectory (dataDirectory); } } @@ -336,7 +333,8 @@ void OMW::Engine::go() // Create the world mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster, - mResDir, mCfgMgr.getCachePath(), mNewGame, &encoder, mFallbackMap)); + mResDir, mCfgMgr.getCachePath(), mNewGame, &encoder, mFallbackMap, + mActivationDistanceOverride)); //Load translation data mTranslationDataStorage.setEncoder(&encoder); @@ -427,12 +425,7 @@ void OMW::Engine::activate() if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); - - if (handle.empty()) - return; - - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaHandle (handle); + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getFacedObject(); if (ptr.isEmpty()) return; @@ -514,3 +507,9 @@ void OMW::Engine::setStartupScript (const std::string& path) { mStartupScript = path; } + + +void OMW::Engine::setActivationDistanceOverride (int distance) +{ + mActivationDistanceOverride = distance; +} diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 00889197e..601cc7765 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -76,6 +76,7 @@ namespace OMW std::map mFallbackMap; bool mScriptConsoleMode; std::string mStartupScript; + int mActivationDistanceOverride; Compiler::Extensions mExtensions; Compiler::Context *mScriptContext; @@ -167,6 +168,9 @@ namespace OMW /// Set path for a script that is run on startup in the console. void setStartupScript (const std::string& path); + /// Override the game setting specified activation distance. + void setActivationDistanceOverride (int distance); + private: Files::ConfigurationManager& mCfgMgr; }; diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 96dbf8987..d1a498610 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -149,6 +149,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("fallback", bpo::value()->default_value(FallbackMap(), "") ->multitoken()->composing(), "fallback values") + ("activate-dist", bpo::value ()->default_value (-1), "activation distance override"); + ; bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) @@ -236,6 +238,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat engine.setFallbackValues(variables["fallback"].as().mMap); engine.setScriptConsoleMode (variables["script-console"].as()); engine.setStartupScript (variables["script-run"].as()); + engine.setActivationDistanceOverride (variables["activate-dist"].as()); return true; } diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 25d999c93..a576912c0 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -199,8 +199,8 @@ namespace MWBase virtual void markCellAsUnchanged() = 0; - virtual std::string getFacedHandle() = 0; - ///< Return handle of the object the player is looking at + virtual MWWorld::Ptr getFacedObject() = 0; + ///< Return pointer to the object the player is looking at, if it is within activation range virtual void deleteObject (const MWWorld::Ptr& ptr) = 0; @@ -280,7 +280,7 @@ namespace MWBase /// @param cursor Y (relative 0-1) /// @return true if the object was placed, or false if it was rejected because the position is too far away - virtual void dropObjectOnGround (const MWWorld::Ptr& object) = 0; + virtual void dropObjectOnGround (const MWWorld::Ptr& actor, const MWWorld::Ptr& object) = 0; virtual bool canPlaceObject (float cursorX, float cursorY) = 0; ///< @return true if it is possible to place on object at specified cursor location diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 76c1c40f1..bbe005955 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -97,11 +97,11 @@ namespace MWClass // make key id lowercase std::string keyId = ptr.getCellRef().mKey; - std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower); + Misc::StringUtils::toLower(keyId); for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) { std::string refId = it->getCellRef().mRefID; - std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower); + Misc::StringUtils::toLower(refId); if (refId == keyId) { hasKey = true; diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 09a15a2cb..fb6329939 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -84,11 +84,11 @@ namespace MWClass // make key id lowercase std::string keyId = ptr.getCellRef().mKey; - std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower); + Misc::StringUtils::toLower(keyId); for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) { std::string refId = it->getCellRef().mRefID; - std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower); + Misc::StringUtils::toLower(refId); if (refId == keyId) { hasKey = true; diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 83a002447..586f9638d 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -65,7 +65,7 @@ namespace MWClass if (!ref->mBase->mFaction.empty()) { std::string faction = ref->mBase->mFaction; - boost::algorithm::to_lower(faction); + Misc::StringUtils::toLower(faction); if(ref->mBase->mNpdt52.mGold != -10) { data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt52.mRank; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 0deef7fd0..7c590c8ef 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -17,24 +17,11 @@ #include "selectwrapper.hpp" -namespace -{ - std::string toLower (const std::string& name) - { - std::string lowerCase; - - std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); - - return lowerCase; - } -} - bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const { // actor id if (!info.mActor.empty()) - if (toLower (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor)) + if ( Misc::StringUtils::lowerCase (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor)) return false; bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name()); @@ -47,7 +34,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const MWWorld::LiveCellRef *cellRef = mActor.get(); - if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace)) + if (Misc::StringUtils::lowerCase (info.mRace)!= Misc::StringUtils::lowerCase (cellRef->mBase->mRace)) return false; } @@ -59,7 +46,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const MWWorld::LiveCellRef *cellRef = mActor.get(); - if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass)) + if ( Misc::StringUtils::lowerCase (info.mClass)!= Misc::StringUtils::lowerCase (cellRef->mBase->mClass)) return false; } @@ -70,7 +57,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const return false; MWMechanics::NpcStats& stats = MWWorld::Class::get (mActor).getNpcStats (mActor); - std::map::iterator iter = stats.getFactionRanks().find (toLower (info.mNpcFaction)); + std::map::iterator iter = stats.getFactionRanks().find ( Misc::StringUtils::lowerCase (info.mNpcFaction)); if (iter==stats.getFactionRanks().end()) return false; @@ -99,7 +86,7 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const if (!info.mPcFaction.empty()) { MWMechanics::NpcStats& stats = MWWorld::Class::get (player).getNpcStats (player); - std::map::iterator iter = stats.getFactionRanks().find (toLower (info.mPcFaction)); + std::map::iterator iter = stats.getFactionRanks().find (Misc::StringUtils::lowerCase (info.mPcFaction)); if(iter==stats.getFactionRanks().end()) return false; @@ -111,7 +98,7 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const // check cell if (!info.mCell.empty()) - if (toLower (player.getCell()->mCell->mName) != toLower (info.mCell)) + if (Misc::StringUtils::lowerCase (player.getCell()->mCell->mName) != Misc::StringUtils::lowerCase (info.mCell)) return false; return true; @@ -242,7 +229,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con std::string name = select.getName(); for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) - if (toLower(iter->getCellRef().mRefID) == name) + if (Misc::StringUtils::lowerCase(iter->getCellRef().mRefID) == name) sum += iter->getRefData().getCount(); return sum; @@ -408,23 +395,23 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_Id: - return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor)); + return select.getName()==Misc::StringUtils::lowerCase (MWWorld::Class::get (mActor).getId (mActor)); case SelectWrapper::Function_Faction: - return toLower (mActor.get()->mBase->mFaction)==select.getName(); + return Misc::StringUtils::lowerCase (mActor.get()->mBase->mFaction)==select.getName(); case SelectWrapper::Function_Class: - return toLower (mActor.get()->mBase->mClass)==select.getName(); + return Misc::StringUtils::lowerCase (mActor.get()->mBase->mClass)==select.getName(); case SelectWrapper::Function_Race: - return toLower (mActor.get()->mBase->mRace)==select.getName(); + return Misc::StringUtils::lowerCase (mActor.get()->mBase->mRace)==select.getName(); case SelectWrapper::Function_Cell: - return toLower (mActor.getCell()->mCell->mName)==select.getName(); + return Misc::StringUtils::lowerCase (mActor.getCell()->mCell->mName)==select.getName(); case SelectWrapper::Function_SameGender: @@ -433,8 +420,8 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_SameRace: - return toLower (mActor.get()->mBase->mRace)!= - toLower (player.get()->mBase->mRace); + return Misc::StringUtils::lowerCase (mActor.get()->mBase->mRace)!= + Misc::StringUtils::lowerCase (player.get()->mBase->mRace); case SelectWrapper::Function_SameFaction: diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 1462ee8ba..9cc528a11 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -8,18 +8,10 @@ #include #include +#include + namespace { - std::string toLower (const std::string& name) - { - std::string lowerCase; - - std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); - - return lowerCase; - } - template bool selectCompareImp (char comp, T1 value1, T2 value2) { @@ -307,5 +299,5 @@ bool MWDialogue::SelectWrapper::selectCompare (bool value) const std::string MWDialogue::SelectWrapper::getName() const { - return toLower (mSelect.mSelectRule.substr (5)); + return Misc::StringUtils::lowerCase (mSelect.mSelectRule.substr (5)); } diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 5b04cc37e..f62bf2a05 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -37,10 +37,7 @@ namespace { std::string lower_string(const std::string& str) { - std::string lowerCase; - - std::transform (str.begin(), str.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); + std::string lowerCase = Misc::StringUtils::lowerCase (str); return lowerCase; } diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 689baf488..a2c3a318b 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -220,7 +220,7 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) if (world->canPlaceObject(mouseX, mouseY)) world->placeObject(object, mouseX, mouseY); else - world->dropObjectOnGround(object); + world->dropObjectOnGround(world->getPlayer().getPlayer(), object); MyGUI::PointerManager::getInstance().setPointer("arrow"); @@ -244,8 +244,7 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) if ( (mode != GM_Console) && (mode != GM_Container) && (mode != GM_Inventory) ) return; - std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); - MWWorld::Ptr object = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle); + MWWorld::Ptr object = MWBase::Environment::get().getWorld()->getFacedObject(); if (mode == GM_Console) MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object); diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index a508bcd34..dd5289edb 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -6,6 +6,7 @@ #include #include + #include #include @@ -16,6 +17,9 @@ #include "../mwbase/windowmanager.hpp" +#include + + namespace MWGui { @@ -214,27 +218,15 @@ namespace MWGui void LoadingScreen::changeWallpaper () { if (mResources.isNull ()) - { - mResources = Ogre::StringVectorPtr (new Ogre::StringVector); + mResources = Ogre::ResourceGroupManager::getSingleton ().findResourceNames ("General", "Splash_*.tga"); - Ogre::StringVectorPtr resources = Ogre::ResourceGroupManager::getSingleton ().listResourceNames ("General", false); - for (Ogre::StringVector::const_iterator it = resources->begin(); it != resources->end(); ++it) - { - if (it->size() < 6) - continue; - std::string start = it->substr(0, 6); - boost::to_lower(start); - - if (start == "splash") - mResources->push_back (*it); - } - } if (mResources->size()) { - std::string randomSplash = mResources->at (rand() % mResources->size()); + std::string const & randomSplash = mResources->at (rand() % mResources->size()); Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().load (randomSplash, "General"); + mBackgroundImage->setImageTexture (randomSplash); } else diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 97df211ac..c7acf568d 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -80,9 +80,8 @@ void ToolTips::onFrame(float frameDuration) || (mWindowManager->getMode() == GM_Container) || (mWindowManager->getMode() == GM_Inventory))) { - std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); + mFocusObject = MWBase::Environment::get().getWorld()->getFacedObject(); - mFocusObject = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle); if (mFocusObject.isEmpty ()) return; diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index f53ccdce3..ee1e9da36 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -263,11 +263,11 @@ namespace MWMechanics bool ActiveSpells::isSpellActive(std::string id) const { - boost::algorithm::to_lower(id); + Misc::StringUtils::toLower(id); for (TContainer::iterator iter = mSpells.begin(); iter != mSpells.end(); ++iter) { std::string left = iter->first; - boost::algorithm::to_lower(left); + Misc::StringUtils::toLower(left); if (iter->first == id) return true; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 079f8520b..dae417d44 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -377,16 +377,6 @@ namespace MWMechanics mUpdatePlayer = true; } - std::string toLower (const std::string& name) - { - std::string lowerCase; - - std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); - - return lowerCase; - } - int MechanicsManager::getDerivedDisposition(const MWWorld::Ptr& ptr) { MWMechanics::NpcStats npcSkill = MWWorld::Class::get(ptr).getNpcStats(ptr); @@ -398,7 +388,7 @@ namespace MWMechanics MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr); MWMechanics::NpcStats playerNpcStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr); - if (toLower(npc->mBase->mRace) == toLower(player->mBase->mRace)) x += MWBase::Environment::get().getWorld()->getStore().get().find("fDispRaceMod")->getFloat(); + if (Misc::StringUtils::lowerCase(npc->mBase->mRace) == Misc::StringUtils::lowerCase(player->mBase->mRace)) x += MWBase::Environment::get().getWorld()->getStore().get().find("fDispRaceMod")->getFloat(); x += MWBase::Environment::get().getWorld()->getStore().get().find("fDispPersonalityMult")->getFloat() * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - MWBase::Environment::get().getWorld()->getStore().get().find("fDispPersonalityBase")->getFloat()); @@ -408,21 +398,21 @@ namespace MWMechanics std::string npcFaction = ""; if(!npcSkill.getFactionRanks().empty()) npcFaction = npcSkill.getFactionRanks().begin()->first; - if (playerNpcStats.getFactionRanks().find(toLower(npcFaction)) != playerNpcStats.getFactionRanks().end()) + if (playerNpcStats.getFactionRanks().find(Misc::StringUtils::lowerCase(npcFaction)) != playerNpcStats.getFactionRanks().end()) { - for(std::vector::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get().find(toLower(npcFaction))->mReactions.begin(); - it != MWBase::Environment::get().getWorld()->getStore().get().find(toLower(npcFaction))->mReactions.end(); it++) + for(std::vector::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.begin(); + it != MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.end(); it++) { - if(toLower(it->mFaction) == toLower(npcFaction)) reaction = it->mReaction; + if(Misc::StringUtils::lowerCase(it->mFaction) == Misc::StringUtils::lowerCase(npcFaction)) reaction = it->mReaction; } - rank = playerNpcStats.getFactionRanks().find(toLower(npcFaction))->second; + rank = playerNpcStats.getFactionRanks().find(Misc::StringUtils::lowerCase(npcFaction))->second; } else if (npcFaction != "") { - for(std::vector::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get().find(toLower(npcFaction))->mReactions.begin(); - it != MWBase::Environment::get().getWorld()->getStore().get().find(toLower(npcFaction))->mReactions.end();it++) + for(std::vector::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.begin(); + it != MWBase::Environment::get().getWorld()->getStore().get().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.end();it++) { - if(playerNpcStats.getFactionRanks().find(toLower(it->mFaction)) != playerNpcStats.getFactionRanks().end() ) + if(playerNpcStats.getFactionRanks().find(Misc::StringUtils::lowerCase(it->mFaction)) != playerNpcStats.getFactionRanks().end() ) { if(it->mReactionmReaction; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index f8d470a4e..d3a97db36 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -90,6 +90,7 @@ namespace MWMechanics virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange); + void toLower(std::string npcFaction); ///< Perform a persuasion action on NPC }; } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index e6a8006e2..d33bdda91 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -80,7 +80,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor mHairModel = "meshes\\" + store.get().find(mNpc->mHair)->mModel; mBodyPrefix = "b_n_" + mNpc->mRace; - std::transform(mBodyPrefix.begin(), mBodyPrefix.end(), mBodyPrefix.begin(), ::tolower); + Misc::StringUtils::toLower(mBodyPrefix); mInsert = node; assert(mInsert); diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 7c009f095..283f149de 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -311,4 +311,9 @@ op 0x20001f4: AddSoulGem, explicit reference op 0x20001f5: RemoveSoulGem op 0x20001f6: RemoveSoulGem, explicit reference op 0x20001f7: PlayBink -opcodes 0x20001f8-0x3ffffff unused +op 0x20001f8: Drop +op 0x20001f9: Drop, explicit reference +op 0x20001fa: DropSoulGem +op 0x20001fb: DropSoulGem, explicit reference + +opcodes 0x20001fa-0x3ffffff unused diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 7d437f3c0..bfe69c79e 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -102,7 +102,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { std::string cell = (runtime.getStringLiteral (runtime[0].mInteger)); - boost::algorithm::to_lower(cell); + Misc::StringUtils::toLower(cell); runtime.pop(); // "Will match complete or partial cells, so ShowMap, "Vivec" will show cells Vivec and Vivec, Fred's House as well." @@ -115,7 +115,7 @@ namespace MWScript for (; it != cells.extEnd(); ++it) { std::string name = it->mName; - boost::algorithm::to_lower(name); + Misc::StringUtils::toLower(name); if (name.find(cell) != std::string::npos) MWBase::Environment::get().getWindowManager()->addVisitedLocation ( it->mName, diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a348a0a49..f329e30d9 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -383,6 +383,88 @@ namespace MWScript } }; + template + class OpDrop : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + + MWWorld::Ptr ptr = R()(runtime); + + std::string item = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer amount = runtime[0].mInteger; + runtime.pop(); + + MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr); + + + for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) + { + if (::Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item)) + { + if(iter->getRefData().getCount() <= amount) + { + MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter); + iter->getRefData().setCount(0); + } + else + { + int original = iter->getRefData().getCount(); + iter->getRefData().setCount(amount); + MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter); + iter->getRefData().setCount(original - amount); + } + + break; + } + } + } + }; + + template + class OpDropSoulGem : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + + MWWorld::Ptr ptr = R()(runtime); + + std::string soul = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr); + + + for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) + { + if (::Misc::StringUtils::ciEqual(iter->getCellRef().mSoul, soul)) + { + + if(iter->getRefData().getCount() <= 1) + { + MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter); + iter->getRefData().setCount(0); + } + else + { + int original = iter->getRefData().getCount(); + iter->getRefData().setCount(1); + MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter); + iter->getRefData().setCount(original - 1); + } + + break; + } + } + } + }; + template class OpGetAttacked : public Interpreter::Opcode0 { @@ -495,6 +577,10 @@ namespace MWScript const int opcodeAddSoulGemExplicit = 0x20001f4; const int opcodeRemoveSoulGem = 0x20001f5; const int opcodeRemoveSoulGemExplicit = 0x20001f6; + const int opcodeDrop = 0x20001f8; + const int opcodeDropExplicit = 0x20001f9; + const int opcodeDropSoulGem = 0x20001fa; + const int opcodeDropSoulGemExplicit = 0x20001fb; const int opcodeGetAttacked = 0x20001d3; const int opcodeGetAttackedExplicit = 0x20001d4; const int opcodeGetWeaponDrawn = 0x20001d7; @@ -538,6 +624,8 @@ namespace MWScript extensions.registerFunction ("geteffect", 'l', "l", opcodeGetEffect, opcodeGetEffectExplicit); extensions.registerInstruction ("addsoulgem", "cc", opcodeAddSoulGem, opcodeAddSoulGemExplicit); extensions.registerInstruction ("removesoulgem", "c", opcodeRemoveSoulGem, opcodeRemoveSoulGemExplicit); + extensions.registerInstruction ("drop", "cl", opcodeDrop, opcodeDropExplicit); + extensions.registerInstruction ("dropsoulgem", "c", opcodeDropSoulGem, opcodeDropSoulGemExplicit); extensions.registerFunction ("getattacked", 'l', "", opcodeGetAttacked, opcodeGetAttackedExplicit); extensions.registerFunction ("getweapondrawn", 'l', "", opcodeGetWeaponDrawn, opcodeGetWeaponDrawnExplicit); extensions.registerFunction ("getspelleffects", 'l', "c", opcodeGetSpellEffects, opcodeGetSpellEffectsExplicit); @@ -576,6 +664,10 @@ namespace MWScript interpreter.installSegment5 (opcodeAddSoulGemExplicit, new OpAddSoulGem); interpreter.installSegment5 (opcodeRemoveSoulGem, new OpRemoveSoulGem); interpreter.installSegment5 (opcodeRemoveSoulGemExplicit, new OpRemoveSoulGem); + interpreter.installSegment5 (opcodeDrop, new OpDrop); + interpreter.installSegment5 (opcodeDropExplicit, new OpDrop); + interpreter.installSegment5 (opcodeDropSoulGem, new OpDropSoulGem); + interpreter.installSegment5 (opcodeDropSoulGemExplicit, new OpDropSoulGem); interpreter.installSegment5 (opcodeGetAttacked, new OpGetAttacked); interpreter.installSegment5 (opcodeGetAttackedExplicit, new OpGetAttacked); interpreter.installSegment5 (opcodeGetWeaponDrawn, new OpGetWeaponDrawn); diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 9e630aedf..31ea7518b 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -512,7 +512,7 @@ namespace MWScript factionID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); } - boost::algorithm::to_lower(factionID); + Misc::StringUtils::toLower(factionID); if(factionID != "") { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); @@ -541,7 +541,7 @@ namespace MWScript factionID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); } - boost::algorithm::to_lower(factionID); + Misc::StringUtils::toLower(factionID); if(factionID != "") { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); @@ -574,7 +574,7 @@ namespace MWScript factionID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); } - boost::algorithm::to_lower(factionID); + Misc::StringUtils::toLower(factionID); if(factionID != "") { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); @@ -612,7 +612,7 @@ namespace MWScript factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first; } } - boost::algorithm::to_lower(factionID); + Misc::StringUtils::toLower(factionID); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); if(factionID!="") { @@ -674,7 +674,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - runtime.push (MWWorld::Class::get (ptr).getNpcStats (ptr).getBaseDisposition()); + runtime.push (MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr)); } }; @@ -714,7 +714,7 @@ namespace MWScript if (factionId.empty()) throw std::runtime_error ("failed to determine faction"); - boost::algorithm::to_lower (factionId); + Misc::StringUtils::toLower (factionId); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); runtime.push ( @@ -750,7 +750,7 @@ namespace MWScript if (factionId.empty()) throw std::runtime_error ("failed to determine faction"); - boost::algorithm::to_lower (factionId); + Misc::StringUtils::toLower (factionId); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Class::get (player).getNpcStats (player).setFactionReputation (factionId, value); @@ -785,7 +785,7 @@ namespace MWScript if (factionId.empty()) throw std::runtime_error ("failed to determine faction"); - boost::algorithm::to_lower (factionId); + Misc::StringUtils::toLower (factionId); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Class::get (player).getNpcStats (player).setFactionReputation (factionId, @@ -830,11 +830,11 @@ namespace MWScript MWWorld::Ptr ptr = R()(runtime); std::string race = runtime.getStringLiteral(runtime[0].mInteger); - boost::algorithm::to_lower(race); + Misc::StringUtils::toLower(race); runtime.pop(); std::string npcRace = ptr.get()->mBase->mRace; - boost::algorithm::to_lower(npcRace); + Misc::StringUtils::toLower(npcRace); runtime.push (npcRace == race); } @@ -878,7 +878,7 @@ namespace MWScript factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first; } } - boost::algorithm::to_lower(factionID); + Misc::StringUtils::toLower(factionID); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); if(factionID!="") { @@ -929,7 +929,7 @@ namespace MWScript if(factionID!="") { std::set& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled (); - boost::algorithm::to_lower(factionID); + Misc::StringUtils::toLower(factionID); expelled.insert(factionID); } } @@ -965,7 +965,7 @@ namespace MWScript if(factionID!="") { std::set& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled (); - boost::algorithm::to_lower(factionID); + Misc::StringUtils::toLower(factionID); expelled.erase (factionID); } } diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp index d8c019644..60260a812 100644 --- a/apps/openmw/mwworld/actionequip.cpp +++ b/apps/openmw/mwworld/actionequip.cpp @@ -2,6 +2,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/windowmanager.hpp" #include "inventorystore.hpp" #include "player.hpp" @@ -15,8 +16,7 @@ namespace MWWorld void ActionEquip::executeImp (const Ptr& actor) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player); + MWWorld::InventoryStore& invStore = MWWorld::Class::get(actor).getInventoryStore(actor); // slots that this item can be equipped in std::pair, bool> slots = MWWorld::Class::get(getTarget()).getEquipmentSlots(getTarget()); @@ -32,11 +32,61 @@ namespace MWWorld } assert(it != invStore.end()); + + std::string npcRace = actor.get()->mBase->mRace; // equip the item in the first free slot for (std::vector::const_iterator slot=slots.first.begin(); slot!=slots.first.end(); ++slot) { + + // Beast races cannot equip shoes / boots, or full helms (head part vs hair part) + if(npcRace == "argonian" || npcRace == "khajiit") + { + if(*slot == MWWorld::InventoryStore::Slot_Helmet){ + std::vector parts; + + if(it.getType() == MWWorld::ContainerStore::Type_Clothing) + parts = it->get()->mBase->mParts.mParts; + else + parts = it->get()->mBase->mParts.mParts; + + bool allow = true; + for(std::vector::iterator itr = parts.begin(); itr != parts.end(); ++itr) + { + if((*itr).mPart == ESM::PartReferenceType::PRT_Head) + { + if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() ) + MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage13}", std::vector()); + + allow = false; + break; + } + } + + if(!allow) + break; + } + + if (*slot == MWWorld::InventoryStore::Slot_Boots) + { + // Only notify the player, not npcs + if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() ) + { + if(it.getType() == MWWorld::ContainerStore::Type_Clothing){ // It's shoes + MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage15}", std::vector()); + } + + else // It's boots + { + MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage14}", std::vector()); + } + } + break; + } + + } + // if all slots are occupied, replace the last slot if (slot == --slots.first.end()) { diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 696a469f7..622c8a10a 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -153,10 +153,7 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& ce if (cell.mState==Ptr::CellStore::State_Preloaded) { - std::string lowerCase; - - std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); + std::string lowerCase = Misc::StringUtils::lowerCase(name); if (std::binary_search (cell.mIds.begin(), cell.mIds.end(), lowerCase)) { diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 1ef2d36a2..fb5e45556 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -56,10 +56,7 @@ namespace MWWorld // Get each reference in turn while (mCell->getNextRef (esm, ref)) { - std::string lowerCase; - - std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); + std::string lowerCase = Misc::StringUtils::lowerCase (ref.mRefID); mIds.push_back (lowerCase); } @@ -82,10 +79,7 @@ namespace MWWorld // Get each reference in turn while(mCell->getNextRef(esm, ref)) { - std::string lowerCase; - - std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); + std::string lowerCase = Misc::StringUtils::lowerCase(ref.mRefID); int rec = store.find(ref.mRefID); diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index e47f2191a..db4537daf 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -37,7 +37,7 @@ namespace bool compare_string_ci(std::string str1, std::string str2) { - boost::algorithm::to_lower(str1); + Misc::StringUtils::toLower(str1); return str1 == str2; } } diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 5359c4eb2..9e2e94143 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -43,7 +43,7 @@ namespace MWWorld return mEngine; } - std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world) + std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world, float queryDistance) { btVector3 dir(0, 1, 0); dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); @@ -56,11 +56,14 @@ namespace MWWorld mPlayerData.eyepos.z); origin += dir * 5; - btVector3 dest = origin + dir * 500; - return mEngine->rayTest(origin, dest); + btVector3 dest = origin + dir * queryDistance; + std::pair result; + /*auto*/ result = mEngine->rayTest(origin, dest); + result.second *= queryDistance; + return std::make_pair (result.second, result.first); } - std::vector < std::pair > PhysicsSystem::getFacedObjects () + std::vector < std::pair > PhysicsSystem::getFacedHandles (float queryDistance) { btVector3 dir(0, 1, 0); dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); @@ -73,22 +76,32 @@ namespace MWWorld mPlayerData.eyepos.z); origin += dir * 5; - btVector3 dest = origin + dir * 500; - return mEngine->rayTest2(origin, dest); + btVector3 dest = origin + dir * queryDistance; + std::vector < std::pair > results; + /* auto */ results = mEngine->rayTest2(origin, dest); + std::vector < std::pair >::iterator i; + for (/* auto */ i = results.begin (); i != results.end (); ++i) + i->first *= queryDistance; + return results; } - std::vector < std::pair > PhysicsSystem::getFacedObjects (float mouseX, float mouseY) + std::vector < std::pair > PhysicsSystem::getFacedHandles (float mouseX, float mouseY, float queryDistance) { Ray ray = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY); Ogre::Vector3 from = ray.getOrigin(); - Ogre::Vector3 to = ray.getPoint(500); /// \todo make this distance (ray length) configurable + Ogre::Vector3 to = ray.getPoint(queryDistance); btVector3 _from, _to; // OGRE to MW coordinates _from = btVector3(from.x, -from.z, from.y); _to = btVector3(to.x, -to.z, to.y); - return mEngine->rayTest2(_from,_to); + std::vector < std::pair > results; + /* auto */ results = mEngine->rayTest2(_from,_to); + std::vector < std::pair >::iterator i; + for (/* auto */ i = results.begin (); i != results.end (); ++i) + i->first *= queryDistance; + return results; } void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight) @@ -110,7 +123,7 @@ namespace MWWorld Ray centerRay = mRender.getCamera()->getCameraToViewportRay( mRender.getViewport()->getWidth()/2, mRender.getViewport()->getHeight()/2); - btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y); /// \todo make this distance (ray length) configurable + btVector3 result(centerRay.getPoint(extent).x,-centerRay.getPoint(extent).z,centerRay.getPoint(extent).y); return result; } @@ -118,7 +131,7 @@ namespace MWWorld { //get a ray pointing to the center of the viewport Ray centerRay = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY); - btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y); /// \todo make this distance (ray length) configurable + btVector3 result(centerRay.getPoint(extent).x,-centerRay.getPoint(extent).z,centerRay.getPoint(extent).y); return result; } diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index 8bd73fd6c..81715c31e 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -41,14 +41,13 @@ namespace MWWorld bool toggleCollisionMode(); - std::pair getFacedHandle (MWWorld::World& world); + std::pair getFacedHandle (MWWorld::World& world, float queryDistance); + std::vector < std::pair > getFacedHandles (float queryDistance); + std::vector < std::pair > getFacedHandles (float mouseX, float mouseY, float queryDistance); btVector3 getRayPoint(float extent); btVector3 getRayPoint(float extent, float mouseX, float mouseY); - std::vector < std::pair > getFacedObjects (); - - std::vector < std::pair > getFacedObjects (float mouseX, float mouseY); // cast ray, return true if it hit something bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to); diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 19bc881f7..917a8d7d4 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -497,7 +497,7 @@ void WeatherManager::update(float duration) if (exterior) { std::string regionstr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion; - boost::algorithm::to_lower(regionstr); + Misc::StringUtils::toLower(regionstr); if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) { diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index d59623ae5..f49b4bf9b 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -170,10 +170,10 @@ namespace MWWorld World::World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame, - ToUTF8::Utf8Encoder* encoder, std::map fallbackMap) + ToUTF8::Utf8Encoder* encoder, std::map fallbackMap, int mActivationDistanceOverride) : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), mSky (true), mCells (mStore, mEsm), - mNumFacing(0) + mNumFacing(0), mActivationDistanceOverride (mActivationDistanceOverride) { mPhysics = new PhysicsSystem(renderer); mPhysEngine = mPhysics->getEngine(); @@ -573,23 +573,55 @@ namespace MWWorld return mWorldScene->markCellAsUnchanged(); } - std::string World::getFacedHandle() + float World::getMaxActivationDistance () { + if (mActivationDistanceOverride >= 0) + return mActivationDistanceOverride; + + return (std::max) (getNpcActivationDistance (), getObjectActivationDistance ()); + } + + float World::getNpcActivationDistance () + { + if (mActivationDistanceOverride >= 0) + return mActivationDistanceOverride; + + return getStore().get().find ("iMaxActivateDist")->getInt()*5/4; + } + + float World::getObjectActivationDistance () + { + if (mActivationDistanceOverride >= 0) + return mActivationDistanceOverride; + + return getStore().get().find ("iMaxActivateDist")->getInt(); + } + + MWWorld::Ptr World::getFacedObject() + { + std::pair result; + if (!mRendering->occlusionQuerySupported()) - { - std::pair result = mPhysics->getFacedHandle (*this); + result = mPhysics->getFacedHandle (*this, getMaxActivationDistance ()); + else + result = std::make_pair (mFacedDistance, mFacedHandle); - if (result.first.empty() || - result.second>getStore().get().find ("iMaxActivateDist")->getInt()) - return ""; + if (result.second.empty()) + return MWWorld::Ptr (); - return result.first; - } + MWWorld::Ptr object = searchPtrViaHandle (result.second); + + float ActivationDistance; + + if (object.getTypeName ().find("NPC") != std::string::npos) + ActivationDistance = getNpcActivationDistance (); else - { - // updated every few frames in update() - return mFacedHandle; - } + ActivationDistance = getObjectActivationDistance (); + + if (result.first > ActivationDistance) + return MWWorld::Ptr (); + + return object; } void World::deleteObject (const Ptr& ptr) @@ -884,8 +916,6 @@ namespace MWWorld void World::update (float duration, bool paused) { - /// \todo split this function up into subfunctions - mWorldScene->update (duration, paused); float pitch, yaw; @@ -895,8 +925,15 @@ namespace MWWorld mWeatherManager->update (duration); + performUpdateSceneQueries (); + + updateWindowManager (); + } + + void World::updateWindowManager () + { // inform the GUI about focused object - MWWorld::Ptr object = searchPtrViaHandle(mFacedHandle); + MWWorld::Ptr object = getFacedObject (); MWBase::Environment::get().getWindowManager()->setFocusObject(object); @@ -918,7 +955,10 @@ namespace MWWorld screenCoords[0], screenCoords[1], screenCoords[2], screenCoords[3]); } } + } + void World::performUpdateSceneQueries () + { if (!mRendering->occlusionQuerySupported()) { // cast a ray from player to sun to detect if the sun is visible @@ -937,119 +977,152 @@ namespace MWWorld MWRender::OcclusionQuery* query = mRendering->getOcclusionQuery(); if (!query->occlusionTestPending()) { - // get result of last query - if (mNumFacing == 0) mFacedHandle = ""; - else if (mNumFacing == 1) - { - bool result = query->getTestResult(); - mFacedHandle = result ? mFaced1Name : ""; - } - else if (mNumFacing == 2) - { - bool result = query->getTestResult(); - mFacedHandle = result ? mFaced2Name : mFaced1Name; - } + processFacedQueryResults (query); + beginFacedQueryProcess (query); + } + } + } - // send new query - // figure out which object we want to test against - std::vector < std::pair < float, std::string > > results; - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - float x, y; - MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); - results = mPhysics->getFacedObjects(x, y); - } - else - results = mPhysics->getFacedObjects(); + void World::processFacedQueryResults (MWRender::OcclusionQuery* query) + { + // get result of last query + if (mNumFacing == 0) + { + mFacedHandle = ""; + mFacedDistance = FLT_MAX; + } + else if (mNumFacing == 1) + { + bool result = query->getTestResult(); + mFacedHandle = result ? mFaced1Name : ""; + mFacedDistance = result ? mFaced1Distance : FLT_MAX; + } + else if (mNumFacing == 2) + { + bool result = query->getTestResult(); + mFacedHandle = result ? mFaced2Name : mFaced1Name; + mFacedDistance = result ? mFaced1Distance : mFaced1Distance; + } + } - // ignore the player and other things we're not interested in - std::vector < std::pair < float, std::string > >::iterator it = results.begin(); - while (it != results.end()) - { - if ( (*it).second.find("HeightField") != std::string::npos // not interested in terrain - || getPtrViaHandle((*it).second) == mPlayer->getPlayer() ) // not interested in player (unless you want to talk to yourself) - { - it = results.erase(it); - } - else - ++it; - } + void World::beginFacedQueryProcess (MWRender::OcclusionQuery* query) + { + // send new query + // figure out which object we want to test against + std::vector < std::pair < float, std::string > > results; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + float x, y; + MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); + results = mPhysics->getFacedHandles(x, y, getMaxActivationDistance ()); + } + else + { + results = mPhysics->getFacedHandles(getMaxActivationDistance ()); + } - if (results.size() == 0) - { - mNumFacing = 0; - } - else if (results.size() == 1) - { - mFaced1 = getPtrViaHandle(results.front().second); - mFaced1Name = results.front().second; - mNumFacing = 1; + // ignore the player and other things we're not interested in + std::vector < std::pair < float, std::string > >::iterator it = results.begin(); + while (it != results.end()) + { + if ( (*it).second.find("HeightField") != std::string::npos // not interested in terrain + || getPtrViaHandle((*it).second) == mPlayer->getPlayer() ) // not interested in player (unless you want to talk to yourself) + { + it = results.erase(it); + } + else + ++it; + } - btVector3 p; - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - float x, y; - MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); - p = mPhysics->getRayPoint(results.front().first, x, y); - } - else - p = mPhysics->getRayPoint(results.front().first); - Ogre::Vector3 pos(p.x(), p.z(), -p.y()); - Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode(); + if (results.size() == 0) + { + mNumFacing = 0; + } + else if (results.size() == 1) + { + beginSingleFacedQueryProcess (query, results); + } + else + { + beginDoubleFacedQueryProcess (query, results); + } + } - //std::cout << "Num facing 1 : " << mFaced1Name << std::endl; - //std::cout << "Type 1 " << mFaced1.getTypeName() << std::endl; + void World::beginSingleFacedQueryProcess (MWRender::OcclusionQuery* query, std::vector < std::pair < float, std::string > > const & results) + { + mFaced1 = getPtrViaHandle(results.front().second); + mFaced1Name = results.front().second; + mFaced1Distance = results.front().first; + mNumFacing = 1; - query->occlusionTest(pos, node); - } - else - { - mFaced1Name = results.front().second; - mFaced2Name = results[1].second; - mFaced1 = getPtrViaHandle(results.front().second); - mFaced2 = getPtrViaHandle(results[1].second); - mNumFacing = 2; - - btVector3 p; - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - float x, y; - MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); - p = mPhysics->getRayPoint(results[1].first, x, y); - } - else - p = mPhysics->getRayPoint(results[1].first); - Ogre::Vector3 pos(p.x(), p.z(), -p.y()); - Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode(); - Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode(); + btVector3 p; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + float x, y; + MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); + p = mPhysics->getRayPoint(results.front().first, x, y); + } + else + p = mPhysics->getRayPoint(results.front().first); + Ogre::Vector3 pos(p.x(), p.z(), -p.y()); + Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode(); - // no need to test if the first node is not occluder - if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos)) - { - mFacedHandle = mFaced1Name; - //std::cout << "node1 Not an occluder" << std::endl; - return; - } + //std::cout << "Num facing 1 : " << mFaced1Name << std::endl; + //std::cout << "Type 1 " << mFaced1.getTypeName() << std::endl; - // no need to test if the second object is static (thus cannot be activated) - if (mFaced2.getTypeName().find("Static") != std::string::npos) - { - mFacedHandle = mFaced1Name; - return; - } + query->occlusionTest(pos, node); + } - // work around door problems - if (mFaced1.getTypeName().find("Static") != std::string::npos - && mFaced2.getTypeName().find("Door") != std::string::npos) - { - mFacedHandle = mFaced2Name; - return; - } + void World::beginDoubleFacedQueryProcess (MWRender::OcclusionQuery* query, std::vector < std::pair < float, std::string > > const & results) + { + mFaced1Name = results.at (0).second; + mFaced2Name = results.at (1).second; + mFaced1Distance = results.at (0).first; + mFaced2Distance = results.at (1).first; + mFaced1 = getPtrViaHandle(results.at (0).second); + mFaced2 = getPtrViaHandle(results.at (1).second); + mNumFacing = 2; - query->occlusionTest(pos, node2); - } - } + btVector3 p; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + float x, y; + MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); + p = mPhysics->getRayPoint(results.at (1).first, x, y); } + else + p = mPhysics->getRayPoint(results.at (1).first); + Ogre::Vector3 pos(p.x(), p.z(), -p.y()); + Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode(); + Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode(); + + // no need to test if the first node is not occluder + if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos)) + { + mFacedHandle = mFaced1Name; + mFacedDistance = mFaced1Distance; + //std::cout << "node1 Not an occluder" << std::endl; + return; + } + + // no need to test if the second object is static (thus cannot be activated) + if (mFaced2.getTypeName().find("Static") != std::string::npos) + { + mFacedHandle = mFaced1Name; + mFacedDistance = mFaced1Distance; + return; + } + + // work around door problems + if (mFaced1.getTypeName().find("Static") != std::string::npos + && mFaced2.getTypeName().find("Door") != std::string::npos) + { + mFacedHandle = mFaced2Name; + mFacedDistance = mFaced2Distance; + return; + } + + query->occlusionTest(pos, node2); } bool World::isCellExterior() const @@ -1213,12 +1286,12 @@ namespace MWWorld } } - void World::dropObjectOnGround (const Ptr& object) + void World::dropObjectOnGround (const Ptr& actor, const Ptr& object) { - MWWorld::Ptr::CellStore* cell = getPlayer().getPlayer().getCell(); + MWWorld::Ptr::CellStore* cell = actor.getCell(); ESM::Position pos = - getPlayer().getPlayer().getRefData().getPosition(); + actor.getRefData().getPosition(); Ogre::Vector3 orig = Ogre::Vector3(pos.pos[0], pos.pos[1], pos.pos[2]); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 35652f01d..7e89c1d87 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -71,11 +71,15 @@ namespace MWWorld Ptr getPtrViaHandle (const std::string& handle, Ptr::CellStore& cellStore); + int mActivationDistanceOverride; std::string mFacedHandle; + float mFacedDistance; Ptr mFaced1; Ptr mFaced2; std::string mFaced1Name; std::string mFaced2Name; + float mFaced1Distance; + float mFaced2Distance; int mNumFacing; std::map mFallback; @@ -90,12 +94,23 @@ namespace MWWorld virtual void copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); + void updateWindowManager (); + void performUpdateSceneQueries (); + void processFacedQueryResults (MWRender::OcclusionQuery* query); + void beginFacedQueryProcess (MWRender::OcclusionQuery* query); + void beginSingleFacedQueryProcess (MWRender::OcclusionQuery* query, std::vector < std::pair < float, std::string > > const & results); + void beginDoubleFacedQueryProcess (MWRender::OcclusionQuery* query, std::vector < std::pair < float, std::string > > const & results); + + float getMaxActivationDistance (); + float getNpcActivationDistance (); + float getObjectActivationDistance (); + public: World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame, - ToUTF8::Utf8Encoder* encoder, std::map fallbackMap); + ToUTF8::Utf8Encoder* encoder, std::map fallbackMap, int mActivationDistanceOverride); virtual ~World(); @@ -217,8 +232,8 @@ namespace MWWorld virtual void markCellAsUnchanged(); - virtual std::string getFacedHandle(); - ///< Return handle of the object the player is looking at + virtual MWWorld::Ptr getFacedObject(); + ///< Return pointer to the object the player is looking at, if it is within activation range virtual void deleteObject (const Ptr& ptr); @@ -296,7 +311,7 @@ namespace MWWorld /// @param cursor Y (relative 0-1) /// @return true if the object was placed, or false if it was rejected because the position is too far away - virtual void dropObjectOnGround (const Ptr& object); + virtual void dropObjectOnGround (const Ptr& actor, const Ptr& object); virtual bool canPlaceObject(float cursorX, float cursorY); ///< @return true if it is possible to place on object at specified cursor location diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index b067c5290..9913fb8aa 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -37,28 +37,142 @@ namespace using namespace Ogre; using namespace Bsa; -struct ciLessBoost : std::binary_function +struct PathPatternMatcher { - bool operator() (const std::string & s1, const std::string & s2) const { - //case insensitive version of is_less - return boost::ilexicographical_compare(s1, s2); + PathPatternMatcher (char const * pattern) : pattern (pattern) + { + } + + bool operator () (char const * input) + { + char const * p = pattern; + char const * i = input; + + while (*p && *i) + { + if (*p == '*') + { + ++p; + + while (*i && *i != *p && *i != '/' && *i != '\\') + ++i; + } + else + if (*p == '?') + { + if (*i == '/' || *i == '\\') + break; + + ++i, ++p; + } + if (*p == '/' || *p == '\\') + { + if (*i != '/' && *i != '\\') + break; + + ++i, ++p; + } + else + { + if (*i != *p) + break; + + ++i, ++p; + } + } + + return *p == 0 && *i == 0; } + +private: + char const * pattern; }; -struct pathComparer +struct FileNameGatherer { -private: - std::string find; + StringVectorPtr ptr; -public: - pathComparer(const std::string& toFind) : find(toFind) { } + FileNameGatherer (StringVectorPtr ptr) : ptr (ptr) + { + } - bool operator() (const std::string& other) + void operator () (std::string const & filename) const { - return boost::iequals(find, other); + ptr->push_back (filename); } }; +struct FileInfoGatherer +{ + Archive const * archive; + FileInfoListPtr ptr; + + FileInfoGatherer (Archive const * archive, FileInfoListPtr ptr) : + archive (archive), ptr (ptr) + { + } + + void operator () (std::string filename) const + { + FileInfo fi; + + std::size_t pt = filename.rfind ('/'); + if (pt == std::string::npos) + pt = 0; + + fi.archive = const_cast (archive); + fi.path = filename.substr (0, pt); + fi.filename = filename.substr (pt); + fi.compressedSize = fi.uncompressedSize = 0; + + ptr->push_back(fi); + } +}; + +template +void matchFiles (bool recursive, std::string const & pattern, file_iterator begin, file_iterator end, filename_extractor filenameExtractor, match_handler matchHandler) +{ + if (recursive && pattern == "*") + { + for (file_iterator i = begin; i != end; ++i) + matchHandler (filenameExtractor (*i)); + } + else + { + PathPatternMatcher matcher (pattern.c_str ()); + + if (recursive) + { + for (file_iterator i = begin; i != end; ++i) + { + char const * filename = filenameExtractor (*i); + char const * matchable_part = filename; + + for (char const * j = matchable_part; *j; ++j) + { + if (*j == '/' || *j == '\\') + matchable_part = j + 1; + } + + if (matcher (matchable_part)) + matchHandler (filename); + } + } + else + { + for (file_iterator i = begin; i != end; ++i) + { + char const * filename = filenameExtractor (*i); + + if (matcher (filename)) + matchHandler (filename); + } + } + } +} + + + static bool fsstrict = false; /// An OGRE Archive wrapping a BSAFile archive @@ -94,6 +208,11 @@ class DirArchive: public Ogre::Archive return mIndex.find (normalized); } + static char const * extractFilename (index::value_type const & entry) + { + return entry.first.c_str (); + } + public: DirArchive(const String& name) @@ -143,27 +262,20 @@ public: StringVectorPtr list(bool recursive = true, bool dirs = false) { - StringVectorPtr ptr = StringVectorPtr(new StringVector()); - std::cout << "DirArchive<" << getName () << ">::list" << std::endl; - return ptr; + return find ("*", recursive, dirs); } FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false) { - FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); - std::cout << "DirArchive<" << getName () << ">::listFileInfo" << std::endl; - return ptr; + return findFileInfo ("*", recursive, dirs); } StringVectorPtr find(const String& pattern, bool recursive = true, bool dirs = false) { + std::string normalizedPattern = normalize_path (pattern.begin (), pattern.end ()); StringVectorPtr ptr = StringVectorPtr(new StringVector()); - - if (pattern == "*") - for (index::const_iterator i = mIndex.begin (); i != mIndex.end (); ++i) - ptr->push_back (i->first); - + matchFiles (recursive, normalizedPattern, mIndex.begin (), mIndex.end (), extractFilename, FileNameGatherer (ptr)); return ptr; } @@ -178,21 +290,20 @@ public: bool dirs = false) const { FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); + FileInfoGatherer gatherer (this, ptr); + + std::string normalizedPattern = normalize_path (pattern.begin (), pattern.end ()); - index::const_iterator i = lookup_filename (pattern); + index::const_iterator i = mIndex.find (normalizedPattern); if (i != mIndex.end ()) { - FileInfo fi; - - std::size_t npos = i->first.rfind ('/'); - - fi.archive = this; - fi.filename = npos != -1 ? i->first.substr (npos) : i->first; - fi.path = npos != -1 ? i->first.substr (0, npos) : ""; - fi.compressedSize = fi.uncompressedSize = 0; + gatherer (i->first); + } + else + { - ptr->push_back(fi); + matchFiles (recursive, normalizedPattern, mIndex.begin (), mIndex.end (), extractFilename, gatherer); } return ptr; @@ -203,6 +314,11 @@ class BSAArchive : public Archive { BSAFile arc; + static char const * extractFilename (BSAFile::FileStruct const & entry) + { + return entry.name; + } + public: BSAArchive(const String& name) : Archive(name, "BSA") @@ -230,26 +346,18 @@ public: return arc.exists(filename.c_str()); } - bool cexists(const String& filename) const { - return arc.exists(filename.c_str()); - } - time_t getModifiedTime(const String&) { return 0; } // This is never called as far as I can see. StringVectorPtr list(bool recursive = true, bool dirs = false) { - //std::cout << "list(" << recursive << ", " << dirs << ")\n"; - StringVectorPtr ptr = StringVectorPtr(new StringVector()); - return ptr; + return find ("*", recursive, dirs); } // Also never called. FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false) { - //std::cout << "listFileInfo(" << recursive << ", " << dirs << ")\n"; - FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); - return ptr; + return findFileInfo ("*", recursive, dirs); } // After load() is called, find("*") is called once. It doesn't seem @@ -258,17 +366,9 @@ public: StringVectorPtr find(const String& pattern, bool recursive = true, bool dirs = false) { - //std::cout << "find(" << pattern << ", " << recursive - // << ", " << dirs << ")\n"; - StringVectorPtr ptr = StringVectorPtr(new StringVector()); - - BSAFile::FileList const & files = arc.getList (); - - if (pattern == "*") - for (BSAFile::FileList::const_iterator i = files.begin (); i != files.end (); ++i) - ptr->push_back (i->name); - - return ptr; + StringVectorPtr ptr = StringVectorPtr(new StringVector()); + matchFiles (recursive, pattern, arc.getList ().begin (), arc.getList ().end (), extractFilename, FileNameGatherer (ptr)); + return ptr; } /* Gets called once for each of the ogre formats, *.program, @@ -281,47 +381,9 @@ public: */ FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true, bool dirs = false) const - { - FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); - - // Check if the file exists (only works for single files - wild - // cards and recursive search isn't implemented.) - if(cexists(pattern)) - { - FileInfo fi; - fi.archive = this; - fi.filename = pattern; - // It apparently doesn't matter that we return bogus - // information - fi.path = ""; - fi.compressedSize = fi.uncompressedSize = 0; - - ptr->push_back(fi); - } - - return ptr; - } - - FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true, - bool dirs = false) { FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList()); - - // Check if the file exists (only works for single files - wild - // cards and recursive search isn't implemented.) - if(cexists(pattern)) - { - FileInfo fi; - fi.archive = this; - fi.filename = pattern; - // It apparently doesn't matter that we return bogus - // information - fi.path = ""; - fi.compressedSize = fi.uncompressedSize = 0; - - ptr->push_back(fi); - } - + matchFiles (recursive, pattern, arc.getList ().begin (), arc.getList ().end (), extractFilename, FileInfoGatherer (this, ptr)); return ptr; } }; diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index 52192625b..027f3de71 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -14,6 +14,7 @@ #include "stringparser.hpp" #include "extensions.hpp" #include "context.hpp" +#include namespace Compiler { @@ -199,8 +200,8 @@ namespace Compiler { mMemberOp = false; - std::string name2 = toLower (name); - std::string id = toLower (mExplicit); + std::string name2 = Misc::StringUtils::lowerCase (name); + std::string id = Misc::StringUtils::lowerCase (mExplicit); char type = getContext().getMemberType (name2, id); @@ -285,7 +286,7 @@ namespace Compiler { start(); - std::string name2 = toLower (name); + std::string name2 = Misc::StringUtils::lowerCase (name); char type = mLocals.getType (name2); diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index a4cbc1ffe..210d18dc9 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -8,6 +8,7 @@ #include "locals.hpp" #include "generator.hpp" #include "extensions.hpp" +#include namespace Compiler { @@ -91,13 +92,13 @@ namespace Compiler return false; } - std::string name2 = toLower (name); + std::string name2 = Misc::StringUtils::lowerCase (name); char type = mLocals.getType (name2); if (type!=' ') { - getErrorHandler().error ("can't re-declare local variable", loc); + getErrorHandler().error ("catoLowern't re-declare local variable", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; @@ -112,7 +113,7 @@ namespace Compiler if (mState==SetState) { - std::string name2 = toLower (name); + std::string name2 = Misc::StringUtils::lowerCase (name); mName = name2; // local variable? @@ -138,7 +139,7 @@ namespace Compiler if (mState==SetMemberVarState) { - mMemberName = toLower (name); + mMemberName = Misc::StringUtils::lowerCase (name); char type = getContext().getMemberType (mMemberName, mName); if (type!=' ') @@ -205,13 +206,13 @@ namespace Compiler if (mState==BeginState && getContext().isId (name)) { mState = PotentialExplicitState; - mExplicit = toLower (name); + mExplicit = Misc::StringUtils::lowerCase (name); return true; } if (mState==BeginState && mAllowExpression) { - std::string name2 = toLower (name); + std::string name2 = Misc::StringUtils::lowerCase (name); char type = mLocals.getType (name2); diff --git a/components/compiler/parser.cpp b/components/compiler/parser.cpp index 90368eee0..896458e48 100644 --- a/components/compiler/parser.cpp +++ b/components/compiler/parser.cpp @@ -9,6 +9,8 @@ #include "exception.hpp" #include "scanner.hpp" +#include + namespace Compiler { // Report the error and throw an exception. @@ -57,10 +59,7 @@ namespace Compiler std::string Parser::toLower (const std::string& name) { - std::string lowerCase; - - std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); + std::string lowerCase = Misc::StringUtils::lowerCase(name); return lowerCase; } diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index 962699dfa..7f43c36a5 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -11,6 +11,8 @@ #include "parser.hpp" #include "extensions.hpp" +#include + namespace Compiler { bool Scanner::get (char& c) @@ -268,11 +270,7 @@ namespace Compiler int i = 0; - std::string lowerCase; - lowerCase.reserve (name.size()); - - std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), - (int(*)(int)) std::tolower); + std::string lowerCase = Misc::StringUtils::lowerCase(name); for (; keywords[i]; ++i) if (lowerCase==keywords[i]) diff --git a/components/compiler/stringparser.cpp b/components/compiler/stringparser.cpp index 396a88c78..09c902131 100644 --- a/components/compiler/stringparser.cpp +++ b/components/compiler/stringparser.cpp @@ -6,6 +6,7 @@ #include "scanner.hpp" #include "generator.hpp" +#include namespace Compiler { @@ -22,7 +23,7 @@ namespace Compiler { start(); if (mSmashCase) - Generator::pushString (mCode, mLiterals, toLower (name)); + Generator::pushString (mCode, mLiterals, Misc::StringUtils::lowerCase (name)); else Generator::pushString (mCode, mLiterals, name); diff --git a/components/files/filelibrary.cpp b/components/files/filelibrary.cpp index ce67f0c66..ce2d95f57 100644 --- a/components/files/filelibrary.cpp +++ b/components/files/filelibrary.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include <../components/misc/stringops.hpp> namespace Files { @@ -45,14 +45,14 @@ namespace Files if( !acceptableExtensions.empty() ) { fileExtension = boost::filesystem::path (listIter->extension()).string(); - boost::algorithm::to_lower(fileExtension); + Misc::StringUtils::toLower(fileExtension); if(!containsVectorString(acceptableExtensions, fileExtension)) continue; } type = boost::filesystem::path (listIter->parent_path().leaf()).string(); if (!strict) - boost::algorithm::to_lower(type); + Misc::StringUtils::toLower(type); mMap[type].push_back(*listIter); // std::cout << "Added path: " << listIter->string() << " in section "<< type < #include +#include <../components/misc/stringops.hpp> namespace Files { @@ -87,7 +88,7 @@ bool isFile(const char *name) if (!strict) { - boost::algorithm::to_lower(toFindStr); + Misc::StringUtils::toLower(toFindStr); } for (Files::PathContainer::const_iterator it = list.begin(); it != list.end(); ++it) @@ -99,7 +100,7 @@ bool isFile(const char *name) if (!strict) { - boost::algorithm::to_lower(fullPath); + Misc::StringUtils::toLower(fullPath); } if(endingMatches(fullPath, toFindStr)) { diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 31d873489..489acb108 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -1003,7 +1004,7 @@ public: if(mSkelName.length() > 0 && mName != mSkelName) fullname += "@skel="+mSkelName; - std::transform(fullname.begin(), fullname.end(), fullname.begin(), ::tolower); + Misc::StringUtils::toLower(fullname); Ogre::MeshPtr mesh = meshMgr.getByName(fullname); if(mesh.isNull()) { @@ -1045,8 +1046,8 @@ static MeshPairMap sMeshPairMap; MeshPairList NIFLoader::load(std::string name, std::string skelName, const std::string &group) { - std::transform(name.begin(), name.end(), name.begin(), ::tolower); - std::transform(skelName.begin(), skelName.end(), skelName.begin(), ::tolower); + Misc::StringUtils::toLower(name); + Misc::StringUtils::toLower(skelName); MeshPairMap::const_iterator meshiter = sMeshPairMap.find(name+"@skel="+skelName); if(meshiter != sMeshPairMap.end()) @@ -1159,7 +1160,7 @@ EntityList NIFLoader::createEntities(Ogre::Entity *parent, const std::string &bo Ogre::Entity *ent = sceneMgr->createEntity(meshes[i].first); if(ent->hasSkeleton()) { - std::transform(meshes[i].second.begin(), meshes[i].second.end(), meshes[i].second.begin(), ::tolower); + Misc::StringUtils::toLower(meshes[i].second); if(meshes[i].second.length() < filter.length() || meshes[i].second.compare(0, filter.length(), filter) != 0) diff --git a/components/nifoverrides/nifoverrides.cpp b/components/nifoverrides/nifoverrides.cpp index 1c8fefd24..191b4ac2f 100644 --- a/components/nifoverrides/nifoverrides.cpp +++ b/components/nifoverrides/nifoverrides.cpp @@ -2,7 +2,8 @@ #include -#include +#include <../components/misc/stringops.hpp> + using namespace NifOverrides; @@ -19,7 +20,7 @@ TransparencyResult Overrides::getTransparencyOverride(const std::string& texture result.first = false; std::string tex = texture; - boost::to_lower(tex); + Misc::StringUtils::toLower(tex); Ogre::ConfigFile::SectionIterator seci = mTransparencyOverrides.getSectionIterator(); while (seci.hasMoreElements())