Merge branch 'master' into sdl_input

actorid
Jordan Milne 12 years ago
commit eff26159d9

@ -7,6 +7,8 @@
#include <vector>
#include <algorithm>
#include <sstream>
#include <components/misc/stringops.hpp>
MwIniImporter::MwIniImporter()
: mVerbose(false)
@ -793,7 +795,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
for(std::vector<std::string>::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);

@ -12,6 +12,7 @@
#include <QVariant>
#include "columnbase.hpp"
#include <components/misc/stringops.hpp>
namespace CSMWorld
{
@ -152,10 +153,7 @@ namespace CSMWorld
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::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<std::string, int>::iterator iter = mIndex.find (id);
@ -281,10 +279,7 @@ namespace CSMWorld
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::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<std::string, int>::const_iterator iter = mIndex.find (id2);

@ -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;
}

@ -76,6 +76,7 @@ namespace OMW
std::map<std::string,std::string> 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;
};

@ -149,6 +149,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "")
->multitoken()->composing(), "fallback values")
("activate-dist", bpo::value <int> ()->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<FallbackMap>().mMap);
engine.setScriptConsoleMode (variables["script-console"].as<bool>());
engine.setStartupScript (variables["script-run"].as<std::string>());
engine.setActivationDistanceOverride (variables["activate-dist"].as<int>());
return true;
}

@ -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

@ -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;

@ -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;

@ -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;

@ -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<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
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<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
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<std::string, int>::iterator iter = stats.getFactionRanks().find (toLower (info.mNpcFaction));
std::map<std::string, int>::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<std::string,int>::iterator iter = stats.getFactionRanks().find (toLower (info.mPcFaction));
std::map<std::string,int>::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<ESM::NPC>()->mBase->mFaction)==select.getName();
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mFaction)==select.getName();
case SelectWrapper::Function_Class:
return toLower (mActor.get<ESM::NPC>()->mBase->mClass)==select.getName();
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mClass)==select.getName();
case SelectWrapper::Function_Race:
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)==select.getName();
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->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<ESM::NPC>()->mBase->mRace)!=
toLower (player.get<ESM::NPC>()->mBase->mRace);
return Misc::StringUtils::lowerCase (mActor.get<ESM::NPC>()->mBase->mRace)!=
Misc::StringUtils::lowerCase (player.get<ESM::NPC>()->mBase->mRace);
case SelectWrapper::Function_SameFaction:

@ -8,18 +8,10 @@
#include <sstream>
#include <iterator>
#include <components/misc/stringops.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;
}
template<typename T1, typename T2>
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));
}

@ -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;
}

@ -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);

@ -6,6 +6,7 @@
#include <OgreCompositorChain.h>
#include <OgreMaterial.h>
#include <boost/algorithm/string.hpp>
#include <openengine/ogre/fader.hpp>
@ -16,6 +17,9 @@
#include "../mwbase/windowmanager.hpp"
#include <components/esm/records.hpp>
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

@ -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;

@ -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;

@ -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<ESM::GameSetting>().find("fDispRaceMod")->getFloat();
if (Misc::StringUtils::lowerCase(npc->mBase->mRace) == Misc::StringUtils::lowerCase(player->mBase->mRace)) x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispRaceMod")->getFloat();
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispPersonalityMult")->getFloat()
* (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().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<ESM::Faction::Reaction>::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(toLower(npcFaction))->mReactions.begin();
it != MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(toLower(npcFaction))->mReactions.end(); it++)
for(std::vector<ESM::Faction::Reaction>::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.begin();
it != MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().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<ESM::Faction::Reaction>::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(toLower(npcFaction))->mReactions.begin();
it != MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(toLower(npcFaction))->mReactions.end();it++)
for(std::vector<ESM::Faction::Reaction>::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(Misc::StringUtils::lowerCase(npcFaction))->mReactions.begin();
it != MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().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->mReaction<reaction) reaction = it->mReaction;
}

@ -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
};
}

@ -80,7 +80,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
mHairModel = "meshes\\" + store.get<ESM::BodyPart>().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);

@ -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

@ -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,

@ -383,6 +383,88 @@ namespace MWScript
}
};
template<class R>
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 R>
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 R>
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<ExplicitRef>);
interpreter.installSegment5 (opcodeRemoveSoulGem, new OpRemoveSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeRemoveSoulGemExplicit, new OpRemoveSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeDrop, new OpDrop<ImplicitRef>);
interpreter.installSegment5 (opcodeDropExplicit, new OpDrop<ExplicitRef>);
interpreter.installSegment5 (opcodeDropSoulGem, new OpDropSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeDropSoulGemExplicit, new OpDropSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeGetAttacked, new OpGetAttacked<ImplicitRef>);
interpreter.installSegment5 (opcodeGetAttackedExplicit, new OpGetAttacked<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponDrawn, new OpGetWeaponDrawn<ImplicitRef>);

@ -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<ESM::NPC>()->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<std::string>& 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<std::string>& expelled = MWWorld::Class::get(player).getNpcStats(player).getExpelled ();
boost::algorithm::to_lower(factionID);
Misc::StringUtils::toLower(factionID);
expelled.erase (factionID);
}
}

@ -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<std::vector<int>, bool> slots = MWWorld::Class::get(getTarget()).getEquipmentSlots(getTarget());
@ -32,11 +32,61 @@ namespace MWWorld
}
assert(it != invStore.end());
std::string npcRace = actor.get<ESM::NPC>()->mBase->mRace;
// equip the item in the first free slot
for (std::vector<int>::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<ESM::PartReference> parts;
if(it.getType() == MWWorld::ContainerStore::Type_Clothing)
parts = it->get<ESM::Clothing>()->mBase->mParts.mParts;
else
parts = it->get<ESM::Armor>()->mBase->mParts.mParts;
bool allow = true;
for(std::vector<ESM::PartReference>::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<std::string>());
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<std::string>());
}
else // It's boots
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage14}", std::vector<std::string>());
}
}
break;
}
}
// if all slots are occupied, replace the last slot
if (slot == --slots.first.end())
{

@ -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))
{

@ -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);

@ -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;
}
}

@ -43,7 +43,7 @@ namespace MWWorld
return mEngine;
}
std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
std::pair<float, std::string> 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 <std::string, float> result;
/*auto*/ result = mEngine->rayTest(origin, dest);
result.second *= queryDistance;
return std::make_pair (result.second, result.first);
}
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects ()
std::vector < std::pair <float, std::string> > 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 <float, std::string> > results;
/* auto */ results = mEngine->rayTest2(origin, dest);
std::vector < std::pair <float, std::string> >::iterator i;
for (/* auto */ i = results.begin (); i != results.end (); ++i)
i->first *= queryDistance;
return results;
}
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects (float mouseX, float mouseY)
std::vector < std::pair <float, std::string> > 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 <float, std::string> > results;
/* auto */ results = mEngine->rayTest2(_from,_to);
std::vector < std::pair <float, std::string> >::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;
}

@ -41,14 +41,13 @@ namespace MWWorld
bool toggleCollisionMode();
std::pair<std::string, float> getFacedHandle (MWWorld::World& world);
std::pair<float, std::string> getFacedHandle (MWWorld::World& world, float queryDistance);
std::vector < std::pair <float, std::string> > getFacedHandles (float queryDistance);
std::vector < std::pair <float, std::string> > getFacedHandles (float mouseX, float mouseY, float queryDistance);
btVector3 getRayPoint(float extent);
btVector3 getRayPoint(float extent, float mouseX, float mouseY);
std::vector < std::pair <float, std::string> > getFacedObjects ();
std::vector < std::pair <float, std::string> > getFacedObjects (float mouseX, float mouseY);
// cast ray, return true if it hit something
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to);

@ -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)
{

@ -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<std::string,std::string> fallbackMap)
ToUTF8::Utf8Encoder* encoder, std::map<std::string,std::string> 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<ESM::GameSetting>().find ("iMaxActivateDist")->getInt()*5/4;
}
float World::getObjectActivationDistance ()
{
if (mActivationDistanceOverride >= 0)
return mActivationDistanceOverride;
return getStore().get<ESM::GameSetting>().find ("iMaxActivateDist")->getInt();
}
MWWorld::Ptr World::getFacedObject()
{
std::pair<float, std::string> result;
if (!mRendering->occlusionQuerySupported())
{
std::pair<std::string, float> result = mPhysics->getFacedHandle (*this);
result = mPhysics->getFacedHandle (*this, getMaxActivationDistance ());
else
result = std::make_pair (mFacedDistance, mFacedHandle);
if (result.first.empty() ||
result.second>getStore().get<ESM::GameSetting>().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]);

@ -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<std::string,std::string> 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<std::string,std::string> fallbackMap);
ToUTF8::Utf8Encoder* encoder, std::map<std::string,std::string> 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

@ -37,28 +37,142 @@ namespace
using namespace Ogre;
using namespace Bsa;
struct ciLessBoost : std::binary_function<std::string, std::string, bool>
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 *> (archive);
fi.path = filename.substr (0, pt);
fi.filename = filename.substr (pt);
fi.compressedSize = fi.uncompressedSize = 0;
ptr->push_back(fi);
}
};
template <typename file_iterator, typename filename_extractor, typename match_handler>
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;
}
};

@ -14,6 +14,7 @@
#include "stringparser.hpp"
#include "extensions.hpp"
#include "context.hpp"
#include <components/misc/stringops.hpp>
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);

@ -8,6 +8,7 @@
#include "locals.hpp"
#include "generator.hpp"
#include "extensions.hpp"
#include <components/misc/stringops.hpp>
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);

@ -9,6 +9,8 @@
#include "exception.hpp"
#include "scanner.hpp"
#include <components/misc/stringops.hpp>
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;
}

@ -11,6 +11,8 @@
#include "parser.hpp"
#include "extensions.hpp"
#include <components/misc/stringops.hpp>
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])

@ -6,6 +6,7 @@
#include "scanner.hpp"
#include "generator.hpp"
#include <components/misc/stringops.hpp>
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);

@ -3,7 +3,7 @@
#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#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 <<std::endl;
@ -63,7 +63,7 @@ namespace Files
bool FileLibrary::containsSection(std::string sectionName, bool strict)
{
if (!strict)
boost::algorithm::to_lower(sectionName);
Misc::StringUtils::toLower(sectionName);
StringPathContMap::const_iterator mapIter = mMap.find(sectionName);
if (mapIter == mMap.end())
return false;
@ -75,7 +75,7 @@ namespace Files
const PathContainer* FileLibrary::section(std::string sectionName, bool strict)
{
if (!strict)
boost::algorithm::to_lower(sectionName);
Misc::StringUtils::toLower(sectionName);
StringPathContMap::const_iterator mapIter = mMap.find(sectionName);
if (mapIter == mMap.end())
{

@ -4,6 +4,7 @@
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#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))
{

@ -44,6 +44,7 @@
#include <extern/shiny/Main/Factory.hpp>
#include <components/nif/node.hpp>
#include <components/misc/stringops.hpp>
#include <components/settings/settings.hpp>
#include <components/nifoverrides/nifoverrides.hpp>
@ -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)

@ -2,7 +2,8 @@
#include <OgreStringConverter.h>
#include <boost/algorithm/string.hpp>
#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())

Loading…
Cancel
Save