diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 71d42df55f..88709f58b1 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -307,6 +307,7 @@ int load(Arguments& info) esm.getRecHeader(flags); std::string id = esm.getHNOString("NAME"); + if(!quiet) std::cout << "\nRecord: " << n.toString() << " '" << id << "'\n"; diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index d1aff6d0fe..adbfca129d 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -339,7 +339,7 @@ void OMW::Engine::go() mEnvironment.setWindowManager (new MWGui::WindowManager( mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), - mScriptConsoleMode)); + mCfgMgr.getCachePath ().string(), mScriptConsoleMode)); // Create sound system mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); @@ -369,7 +369,6 @@ void OMW::Engine::go() pos.pos[2] = 0; mEnvironment.getWorld()->renderPlayer(); - mEnvironment.getWorld()->renderGlobalMap(); if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName)) { diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index c5f1847af1..39d7e6e1a4 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -71,6 +71,9 @@ namespace MWBase virtual void setPlayerClass (const ESM::Class& class_) = 0; ///< Set player class to custom class. + + virtual void restoreDynamicStats() = 0; + ///< If the player is sleeping, this should be called every hour. }; } diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 4291631363..8ea9e5cefe 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -226,6 +226,7 @@ namespace MWBase virtual bool getRestEnabled() = 0; virtual bool getPlayerSleeping() = 0; + virtual void wakeUpPlayer() = 0; }; } diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index ee474f3570..521bbb988e 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -282,7 +282,6 @@ namespace MWBase virtual void togglePlayerLooking(bool enable) = 0; virtual void renderPlayer() = 0; - virtual void renderGlobalMap() = 0; virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index efb5ea9477..a05c24e864 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -128,12 +128,10 @@ namespace MWClass info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.icon = ref->base->mIcon; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; - text += "\n" + store.gameSettings.search("sQuality")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mQuality); - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 254095ba6a..7254c37f8a 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -152,13 +152,13 @@ namespace MWClass if (typeGmst.empty()) return -1; - float iWeight = MWBase::Environment::get().getWorld()->getStore().gameSettings.find (typeGmst)->mI; + float iWeight = MWBase::Environment::get().getWorld()->getStore().gameSettings.find (typeGmst)->getInt(); - if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fLightMaxMod")->mF>= + if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fLightMaxMod")->getFloat()>= ref->base->mData.mWeight) return ESM::Skill::LightArmor; - if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMedMaxMod")->mF>= + if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMedMaxMod")->getFloat()>= ref->base->mData.mWeight) return ESM::Skill::MediumArmor; @@ -229,25 +229,23 @@ namespace MWClass std::string text; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - // get armor type string (light/medium/heavy) int armorType = getEquipmentSkill(ptr); std::string typeText; if (armorType == ESM::Skill::LightArmor) - typeText = store.gameSettings.search("sLight")->mStr; + typeText = "#{sLight}"; else if (armorType == ESM::Skill::MediumArmor) - typeText = store.gameSettings.search("sMedium")->mStr; + typeText = "#{sMedium}"; else - typeText = store.gameSettings.search("sHeavy")->mStr; + typeText = "#{sHeavy}"; - text += "\n" + store.gameSettings.search("sArmorRating")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mArmor); + text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->base->mData.mArmor); /// \todo store the current armor health somewhere - text += "\n" + store.gameSettings.search("sCondition")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mHealth); + text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth); - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight) + " (" + typeText + ")"; - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight) + " (" + typeText + ")"; + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index cf94a969ed..4a2ad1dcb9 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -123,12 +123,10 @@ namespace MWClass info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.icon = ref->base->mIcon; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 9ee5dc466d..d746350dfe 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -193,12 +193,10 @@ namespace MWClass info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.icon = ref->base->mIcon; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index c4f34e05bb..28fa723786 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -185,13 +185,11 @@ namespace MWClass MWGui::ToolTipInfo info; info.caption = ref->base->mName; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; if (ref->ref.mLockLevel > 0) - text += "\n" + store.gameSettings.search("sLockLevel")->mStr + ": " + MWGui::ToolTips::toString(ref->ref.mLockLevel); + text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel); if (ref->ref.mTrap != "") - text += "\n" + store.gameSettings.search("sTrapped")->mStr; + text += "\n#{sTrapped}"; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 9c3bbd551c..b94a24ed5c 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -223,14 +223,14 @@ namespace MWClass dest = region->mName; } } - text += "\n" + store.gameSettings.search("sTo")->mStr; + text += "\n#{sTo}"; text += "\n"+dest; } if (ref->ref.mLockLevel > 0) - text += "\n" + store.gameSettings.search("sLockLevel")->mStr + ": " + MWGui::ToolTips::toString(ref->ref.mLockLevel); + text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel); if (ref->ref.mTrap != "") - text += "\n" + store.gameSettings.search("sTrapped")->mStr; + text += "\n#{sTrapped}"; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 8dec3f5378..45779287f4 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -145,12 +145,10 @@ namespace MWClass info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.icon = ref->base->mIcon; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 1ef5339e96..6ae9ed6615 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -173,12 +173,10 @@ namespace MWClass info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.icon = ref->base->mIcon; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index a140f0ff70..a0ec65c988 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -137,16 +137,14 @@ namespace MWClass info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.icon = ref->base->mIcon; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; /// \todo store remaining uses somewhere - text += "\n" + store.gameSettings.search("sUses")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mUses); - text += "\n" + store.gameSettings.search("sQuality")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mQuality); - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); + text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 9a3a27e113..edcfc7daa7 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -101,7 +101,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->mStr) + if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) { return std::string("Item Gold Up"); } @@ -113,7 +113,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->mStr) + if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) { return std::string("Item Gold Down"); } @@ -147,7 +147,7 @@ namespace MWClass int count = ptr.getRefData().getCount(); - bool isGold = (ref->base->mName == store.gameSettings.search("sGold")->mStr); + bool isGold = (ref->base->mName == store.gameSettings.find("sGold")->getString()); if (isGold && count == 1) count = ref->base->mData.mValue; @@ -170,8 +170,8 @@ namespace MWClass if (!isGold) { - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); } if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { @@ -192,7 +192,7 @@ namespace MWClass const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - if (MWWorld::Class::get(ptr).getName(ptr) == store.gameSettings.search("sGold")->mStr) { + if (MWWorld::Class::get(ptr).getName(ptr) == store.gameSettings.find("sGold")->getString()) { int goldAmount = ptr.getRefData().getCount(); std::string base = "Gold_001"; diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index be0d1dd0f5..f641cc7199 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -129,12 +129,10 @@ namespace MWClass info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.icon = ref->base->mIcon; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->base->mEffects); info.isPotion = true; diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index eed848fdef..39472f2ec4 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -136,16 +136,14 @@ namespace MWClass info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.icon = ref->base->mIcon; - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::string text; /// \todo store remaining uses somewhere - text += "\n" + store.gameSettings.search("sUses")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mUses); - text += "\n" + store.gameSettings.search("sQuality")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mQuality); - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); + text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 057569beac..7ccb34913d 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -130,11 +130,10 @@ namespace MWClass /// \todo store remaining uses somewhere - const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - text += "\n" + store.gameSettings.search("sUses")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mUses); - text += "\n" + store.gameSettings.search("sQuality")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mQuality); - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); + text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 250e3ba8ab..fee0dfdf14 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -284,7 +284,7 @@ namespace MWClass // weapon type & damage. arrows / bolts don't have his info. if (ref->base->mData.mType < 12) { - text += "\n" + store.gameSettings.search("sType")->mStr + " "; + text += "\n#{sType} "; std::map > mapping; mapping[ESM::Weapon::ShortBladeOneHand] = std::make_pair("sSkillShortblade", "sOneHanded"); @@ -303,29 +303,29 @@ namespace MWClass std::string type = mapping[ref->base->mData.mType].first; std::string oneOrTwoHanded = mapping[ref->base->mData.mType].second; - text += store.gameSettings.search(type)->mStr + - ((oneOrTwoHanded != "") ? ", " + store.gameSettings.search(oneOrTwoHanded)->mStr : ""); + text += store.gameSettings.find(type)->getString() + + ((oneOrTwoHanded != "") ? ", " + store.gameSettings.find(oneOrTwoHanded)->getString() : ""); // weapon damage if (ref->base->mData.mType >= 9) { // marksman - text += "\n" + store.gameSettings.search("sAttack")->mStr + ": " + text += "\n#{sAttack}: " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mChop[0])) + " - " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mChop[1])); } else { // Chop - text += "\n" + store.gameSettings.search("sChop")->mStr + ": " + text += "\n#{sChop}: " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mChop[0])) + " - " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mChop[1])); // Slash - text += "\n" + store.gameSettings.search("sSlash")->mStr + ": " + text += "\n#{sSlash}: " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mSlash[0])) + " - " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mSlash[1])); // Thrust - text += "\n" + store.gameSettings.search("sThrust")->mStr + ": " + text += "\n#{sThrust}: " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mThrust[0])) + " - " + MWGui::ToolTips::toString(static_cast(ref->base->mData.mThrust[1])); } @@ -333,10 +333,10 @@ namespace MWClass /// \todo store the current weapon health somewhere if (ref->base->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity - text += "\n" + store.gameSettings.search("sCondition")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mHealth); + text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth); - text += "\n" + store.gameSettings.search("sWeight")->mStr + ": " + MWGui::ToolTips::toString(ref->base->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, store.gameSettings.search("sValue")->mStr); + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); + text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); info.enchant = ref->base->mEnchant; diff --git a/apps/openmw/mwdialogue/journalimp.cpp b/apps/openmw/mwdialogue/journalimp.cpp index aed2086e0a..ac4b7a6ded 100644 --- a/apps/openmw/mwdialogue/journalimp.cpp +++ b/apps/openmw/mwdialogue/journalimp.cpp @@ -40,7 +40,7 @@ namespace MWDialogue quest.addEntry (entry); // we are doing slicing on purpose here std::vector empty; - std::string notification = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sJournalEntry")->mStr; + std::string notification = "#{sJournalEntry}"; MWBase::Environment::get().getWindowManager()->messageBox (notification, empty); } diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index d2c6f3d060..5c202941f5 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -110,7 +110,7 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) } else { - std::string message = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTake")->mStr; + std::string message = "#{sTake}"; CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); dialog->open(MWWorld::Class::get(object).getName(object), message, count); dialog->eventOkClicked.clear(); @@ -129,19 +129,18 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) { // the player is trying to sell an item, check if the merchant accepts it // also, don't allow selling gold (let's be better than Morrowind at this, can we?) - if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object) - || MWWorld::Class::get(object).getName(object) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->mStr) + if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object) || + MWWorld::Class::get(object).getName(object) == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) { // user notification "i don't buy this item" MWBase::Environment::get().getWindowManager()-> - messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog4")->mStr, std::vector()); + messageBox("#{sBarterDialog4}", std::vector()); return; } } bool buying = isTradeWindow(); // buying or selling? - std::string message = buying ? MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage02")->mStr - : MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage01")->mStr; + std::string message = buying ? "#{sQuanityMenuMessage02}" : "#{sQuanityMenuMessage01}"; if (std::find(mBoughtItems.begin(), mBoughtItems.end(), object) != mBoughtItems.end()) { @@ -279,7 +278,8 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) { // user notification MWBase::Environment::get().getWindowManager()-> - messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage2")->mStr, std::vector()); + messageBox("#{sContentsMessage2}", std::vector()); + return; } } @@ -302,7 +302,8 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) object.getRefData().setCount(origCount); // user notification MWBase::Environment::get().getWindowManager()-> - messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage3")->mStr, std::vector()); + messageBox("#{sContentsMessage3}", std::vector()); + return; } else @@ -363,7 +364,7 @@ void ContainerBase::drawItems() int maxHeight = mItemView->getSize().height - 58; bool onlyMagic = false; - int categories; + int categories = 0; if (mFilter == Filter_All) categories = MWWorld::ContainerStore::Type_All; else if (mFilter == Filter_Weapon) diff --git a/apps/openmw/mwgui/countdialog.cpp b/apps/openmw/mwgui/countdialog.cpp index baf14e3fb0..61c3c358a2 100644 --- a/apps/openmw/mwgui/countdialog.cpp +++ b/apps/openmw/mwgui/countdialog.cpp @@ -27,7 +27,7 @@ namespace MWGui { setVisible(true); - mLabelText->setCaption(message); + mLabelText->setCaptionWithReplacing(message); MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 177e04f427..245487a049 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -123,13 +123,13 @@ void DialogueWindow::onSelectTopic(std::string topic) { if (!mEnabled) return; - if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->mStr) + if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sBarter")->getString()) { /// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)? mWindowManager.pushGuiMode(GM_Barter); mWindowManager.getTradeWindow()->startTrade(mPtr); } - else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSpells")->mStr) + else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpells")->getString()) { mWindowManager.pushGuiMode(GM_SpellBuying); mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); @@ -158,10 +158,10 @@ void DialogueWindow::setKeywords(std::list keyWords) bool anyService = mShowTrade||mShowSpells; if (mShowTrade) - mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->mStr); + mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sBarter")->getString()); if (mShowSpells) - mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSpells")->mStr); + mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpells")->getString()); if (anyService) mTopicsList->addSeparator(); @@ -266,7 +266,7 @@ void DialogueWindow::updateOptions() void DialogueWindow::goodbye() { - mHistory->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGoodbye")->mStr); + mHistory->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGoodbye")->getString()); mTopicsList->setEnabled(false); mEnabled = false; } diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index e41f2eec97..170fc3bc5f 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -126,7 +126,7 @@ namespace MWGui // always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before // (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow) - MWBase::Environment::get().getInputManager()->update(0, true); + //MWBase::Environment::get().getInputManager()->update(0, true); Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0)); diff --git a/apps/openmw/mwgui/map_window.cpp b/apps/openmw/mwgui/map_window.cpp index ea7b442593..1913ed8dd6 100644 --- a/apps/openmw/mwgui/map_window.cpp +++ b/apps/openmw/mwgui/map_window.cpp @@ -11,6 +11,8 @@ #include "../mwbase/environment.hpp" #include "../mwworld/player.hpp" +#include "../mwrender/globalmap.hpp" + using namespace MWGui; LocalMapBase::LocalMapBase() @@ -222,6 +224,9 @@ void LocalMapBase::setPlayerPos(const float x, const float y) { if (x == mLastPositionX && y == mLastPositionY) return; + + notifyPlayerUpdate (); + MyGUI::IntSize size = mLocalMap->getCanvasSize(); MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); MyGUI::IntCoord viewsize = mLocalMap->getCoord(); @@ -237,6 +242,9 @@ void LocalMapBase::setPlayerDir(const float x, const float y) { if (x == mLastDirectionX && y == mLastDirectionY) return; + + notifyPlayerUpdate (); + MyGUI::ISubWidget* main = mCompass->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); @@ -249,18 +257,23 @@ void LocalMapBase::setPlayerDir(const float x, const float y) // ------------------------------------------------------------------------------------------ -MapWindow::MapWindow(MWBase::WindowManager& parWindowManager) : - MWGui::WindowPinnableBase("openmw_map_window.layout", parWindowManager), - mGlobal(false) +MapWindow::MapWindow(MWBase::WindowManager& parWindowManager, const std::string& cacheDir) + : MWGui::WindowPinnableBase("openmw_map_window.layout", parWindowManager) + , mGlobal(false) { setCoord(500,0,320,300); + mGlobalMapRender = new MWRender::GlobalMap(cacheDir); + mGlobalMapRender->render(); + getWidget(mLocalMap, "LocalMap"); getWidget(mGlobalMap, "GlobalMap"); getWidget(mGlobalMapImage, "GlobalMapImage"); getWidget(mPlayerArrowLocal, "CompassLocal"); getWidget(mPlayerArrowGlobal, "CompassGlobal"); + mGlobalMapImage->setImageTexture("GlobalMap.png"); + mGlobalMap->setVisible (false); getWidget(mButton, "WorldButton"); @@ -277,6 +290,11 @@ MapWindow::MapWindow(MWBase::WindowManager& parWindowManager) : LocalMapBase::init(mLocalMap, mPlayerArrowLocal, this); } +MapWindow::~MapWindow() +{ + delete mGlobalMapRender; +} + void MapWindow::setCellName(const std::string& cellName) { setTitle(cellName); @@ -284,13 +302,12 @@ void MapWindow::setCellName(const std::string& cellName) void MapWindow::addVisitedLocation(const std::string& name, int x, int y) { - const int cellSize = 24; - - int size = 24 * 61; + float worldX, worldY; + mGlobalMapRender->cellTopLeftCornerToImageSpace (x, y, worldX, worldY); MyGUI::IntCoord widgetCoord( - (x+30)*cellSize+6, - (size-1) - (y+30)*cellSize+6, + worldX * mGlobalMapRender->getWidth()+6, + worldY * mGlobalMapRender->getHeight()+6, 12, 12); @@ -340,6 +357,9 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" : "#{sWorld}"); + + if (mGlobal) + globalMapUpdatePlayer (); } void MapWindow::onPinToggled() @@ -349,12 +369,8 @@ void MapWindow::onPinToggled() void MapWindow::open() { - mGlobalMapImage->setImageTexture("GlobalMap.png"); - - int size = 24 * 61; - - mGlobalMap->setCanvasSize (size, size); - mGlobalMapImage->setSize(size, size); + mGlobalMap->setCanvasSize (mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight()); + mGlobalMapImage->setSize(mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight()); for (unsigned int i=0; igetChildCount (); ++i) { @@ -362,25 +378,43 @@ void MapWindow::open() mGlobalMapImage->getChildAt (i)->castType()->setImageResource("DoorMarker"); } + globalMapUpdatePlayer(); + + mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds"); +} + +void MapWindow::globalMapUpdatePlayer () +{ Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition (); Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation (); Ogre::Vector2 dir (orient.yAxis ().x, -orient.yAxis().z); - float worldX = ((pos.x / 8192.f-0.5) / 30.f+1)/2.f; - float worldY = ((pos.z / 8192.f+1.5) / 30.f+1)/2.f; + float worldX, worldY; + mGlobalMapRender->worldPosToImageSpace (pos.x, pos.z, worldX, worldY); + worldX *= mGlobalMapRender->getWidth(); + worldY *= mGlobalMapRender->getHeight(); + // for interiors, we have no choice other than using the last position & direction. /// \todo save this last position in the savegame? if (MWBase::Environment::get().getWorld ()->isCellExterior ()) { - mPlayerArrowGlobal->setPosition(MyGUI::IntPoint(size * worldX - 16, size * worldY - 16)); + mPlayerArrowGlobal->setPosition(MyGUI::IntPoint(worldX - 16, worldY - 16)); MyGUI::ISubWidget* main = mPlayerArrowGlobal->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); float angle = std::atan2(dir.x, dir.y); rotatingSubskin->setAngle(angle); - } - mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds"); + // set the view offset so that player is in the center + MyGUI::IntSize viewsize = mGlobalMap->getSize(); + MyGUI::IntPoint viewoffs(0.5*viewsize.width - worldX, 0.5*viewsize.height - worldY); + mGlobalMap->setViewOffset(viewoffs); + } +} + +void MapWindow::notifyPlayerUpdate () +{ + globalMapUpdatePlayer (); } diff --git a/apps/openmw/mwgui/map_window.hpp b/apps/openmw/mwgui/map_window.hpp index a8b5b9cb90..73eaad1cd7 100644 --- a/apps/openmw/mwgui/map_window.hpp +++ b/apps/openmw/mwgui/map_window.hpp @@ -3,6 +3,11 @@ #include "window_pinnable_base.hpp" +namespace MWRender +{ + class GlobalMap; +} + namespace MWGui { class LocalMapBase @@ -44,6 +49,8 @@ namespace MWGui void onMarkerFocused(MyGUI::Widget* w1, MyGUI::Widget* w2); void onMarkerUnfocused(MyGUI::Widget* w1, MyGUI::Widget* w2); + virtual void notifyPlayerUpdate() {} + OEngine::GUI::Layout* mLayout; bool mMapDragAndDrop; @@ -57,8 +64,8 @@ namespace MWGui class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase { public: - MapWindow(MWBase::WindowManager& parWindowManager); - virtual ~MapWindow(){} + MapWindow(MWBase::WindowManager& parWindowManager, const std::string& cacheDir); + virtual ~MapWindow(); void setCellName(const std::string& cellName); @@ -71,6 +78,8 @@ namespace MWGui void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onWorldButtonClicked(MyGUI::Widget* _sender); + void globalMapUpdatePlayer(); + MyGUI::ScrollView* mGlobalMap; MyGUI::ImageBox* mGlobalMapImage; MyGUI::ImageBox* mPlayerArrowLocal; @@ -82,8 +91,12 @@ namespace MWGui MyGUI::Button* mEventBoxGlobal; MyGUI::Button* mEventBoxLocal; + MWRender::GlobalMap* mGlobalMapRender; + protected: virtual void onPinToggled(); + + virtual void notifyPlayerUpdate(); }; } #endif diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 40e5811a94..019a59cf4c 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -33,11 +33,6 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) setText("AppearanceT", mWindowManager.getGameSettingString("sRaceMenu1", "Appearance")); getWidget(mPreviewImage, "PreviewImage"); - MWBase::Environment::get().getWorld ()->setupExternalRendering (mPreview); - mPreview.update (0); - - mPreviewImage->setImageTexture ("CharacterHeadPreview"); - getWidget(mHeadRotate, "HeadRotate"); mHeadRotate->setScrollRange(50); mHeadRotate->setScrollPosition(25); @@ -107,6 +102,12 @@ void RaceDialog::open() updateRaces(); updateSkills(); updateSpellPowers(); + + mPreview = new MWRender::RaceSelectionPreview(); + MWBase::Environment::get().getWorld ()->setupExternalRendering (*mPreview); + mPreview->update (0); + + mPreviewImage->setImageTexture ("CharacterHeadPreview"); } @@ -138,6 +139,12 @@ int wrap(int index, int max) return index; } +void RaceDialog::close() +{ + delete mPreview; + mPreview = 0; +} + // widget controls void RaceDialog::onOkClicked(MyGUI::Widget* _sender) @@ -154,7 +161,7 @@ void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position) { float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2; float diff = angle - mCurrentAngle; - mPreview.update (diff); + mPreview->update (diff); mCurrentAngle += diff; } diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index 0505e58e13..c4734eae8c 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -46,6 +46,7 @@ namespace MWGui void setNextButtonShow(bool shown); virtual void open(); + virtual void close(); // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; @@ -94,7 +95,7 @@ namespace MWGui float mCurrentAngle; - MWRender::RaceSelectionPreview mPreview; + MWRender::RaceSelectionPreview* mPreview; }; } #endif diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index fb9f03e25b..f8d5649b97 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -51,7 +51,7 @@ namespace MWGui void SpellBuyingWindow::addSpell(const std::string& spellId) { const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); - int price = spell->mData.mCost*MWBase::Environment::get().getWorld()->getStore().gameSettings.search("fSpellValueMult")->mF; + int price = spell->mData.mCost*MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fSpellValueMult")->getFloat(); MyGUI::Button* toAdd = mSpellsView->createWidget( @@ -67,11 +67,7 @@ namespace MWGui /// \todo price adjustment depending on merchantile skill toAdd->setUserData(price); - - std::string sgp = - MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sgp")->mStr; - toAdd->setCaption(spell->mName+" - "+boost::lexical_cast(price)+ sgp); - + toAdd->setCaptionWithReplacing(spell->mName+" - "+boost::lexical_cast(price)+"#{sgp}"); toAdd->setSize(toAdd->getTextSize().width,sLineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &SpellBuyingWindow::onMouseWheel); toAdd->setUserString("ToolTipType", "Spell"); @@ -142,8 +138,7 @@ namespace MWGui void SpellBuyingWindow::updateLabels() { - mPlayerGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->mStr - + ": " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); + mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); mPlayerGold->setCoord(8, mPlayerGold->getTop(), mPlayerGold->getTextSize().width, diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 6cc6eb94bf..5a670968e0 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -57,7 +57,7 @@ StatsWindow::StatsWindow (MWBase::WindowManager& parWindowManager) const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); for (int i=0; names[i][0]; ++i) { - setText (names[i][0], store.gameSettings.find (names[i][1])->mStr); + setText (names[i][0], store.gameSettings.find (names[i][1])->getString()); } getWidget(mSkillView, "SkillView"); @@ -475,8 +475,6 @@ void StatsWindow::updateSkillArea() text += "\n#BF9959"; for (int i=0; i<6; ++i) { - const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().skills.search(faction->mData.mSkillID[i]); - assert(skill); text += "#{"+ESM::Skill::sSkillNameIds[faction->mData.mSkillID[i]]+"}"; if (i<5) text += ", "; diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 55acde4b47..cc48438415 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -368,19 +368,19 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) if (text.size() > 0 && text[0] == '\n') text.erase(0, 1); - const ESM::Enchantment* enchant; + const ESM::Enchantment* enchant = 0; const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); if (info.enchant != "") { enchant = store.enchants.search(info.enchant); if (enchant->mData.mType == ESM::Enchantment::CastOnce) - text += "\n" + store.gameSettings.search("sItemCastOnce")->mStr; + text += "\n#{sItemCastOnce}"; else if (enchant->mData.mType == ESM::Enchantment::WhenStrikes) - text += "\n" + store.gameSettings.search("sItemCastWhenStrikes")->mStr; + text += "\n#{sItemCastWhenStrikes}"; else if (enchant->mData.mType == ESM::Enchantment::WhenUsed) - text += "\n" + store.gameSettings.search("sItemCastWhenUsed")->mStr; + text += "\n#{sItemCastWhenUsed}"; else if (enchant->mData.mType == ESM::Enchantment::ConstantEffect) - text += "\n" + store.gameSettings.search("sItemCastConstant")->mStr; + text += "\n#{sItemCastConstant}"; } // this the maximum width of the tooltip before it starts word-wrapping @@ -405,7 +405,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) textWidget->setProperty("Static", "true"); textWidget->setProperty("MultiLine", "true"); textWidget->setProperty("WordWrap", "true"); - textWidget->setCaption(text); + textWidget->setCaptionWithReplacing(text); textWidget->setTextAlign(Align::HCenter | Align::Top); IntSize textSize = textWidget->getTextSize(); @@ -440,6 +440,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) if (info.enchant != "") { + assert(enchant); Widget* enchantArea = mDynamicToolTipBox->createWidget("", IntCoord(0, totalSize.height, 300, 300-totalSize.height), Align::Stretch, "ToolTipEnchantArea"); @@ -466,7 +467,8 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) const int chargeWidth = 204; TextBox* chargeText = enchantArea->createWidget("SandText", IntCoord(0, 0, 10, 18), Align::Default, "ToolTipEnchantChargeText"); - chargeText->setCaption(store.gameSettings.search("sCharges")->mStr); + chargeText->setCaptionWithReplacing("#{sCharges}"); + const int chargeTextWidth = chargeText->getTextSize().width + 5; const int chargeAndTextWidth = chargeWidth + chargeTextWidth; diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 72ce86cedb..64710c2794 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -110,7 +110,7 @@ namespace MWGui for (MWWorld::ContainerStoreIterator it = playerStore.begin(); it != playerStore.end(); ++it) { - if (MWWorld::Class::get(*it).getName(*it) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->mStr) + if (MWWorld::Class::get(*it).getName(*it) == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) { goldFound = true; gold = *it; @@ -138,7 +138,7 @@ namespace MWGui { // user notification MWBase::Environment::get().getWindowManager()-> - messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog11")->mStr, std::vector()); + messageBox("#{sBarterDialog11}", std::vector()); return; } @@ -147,7 +147,7 @@ namespace MWGui { // user notification MWBase::Environment::get().getWindowManager()-> - messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog1")->mStr, std::vector()); + messageBox("#{sBarterDialog1}", std::vector()); return; } @@ -170,7 +170,7 @@ namespace MWGui { // user notification MWBase::Environment::get().getWindowManager()-> - messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog2")->mStr, std::vector()); + messageBox("#{sBarterDialog2}", std::vector()); return; } @@ -200,17 +200,16 @@ namespace MWGui void TradeWindow::updateLabels() { - mPlayerGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sYourGold")->mStr - + " " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); + mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast(mWindowManager.getInventoryWindow()->getPlayerGold())); if (mCurrentBalance > 0) { - mTotalBalanceLabel->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTotalSold")->mStr); + mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalSold}"); mTotalBalance->setCaption(boost::lexical_cast(mCurrentBalance)); } else { - mTotalBalanceLabel->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTotalCost")->mStr); + mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalCost}"); mTotalBalance->setCaption(boost::lexical_cast(-mCurrentBalance)); } @@ -229,8 +228,7 @@ namespace MWGui merchantgold = ref->base->mData.mGold; } - mMerchantGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSellerGold")->mStr - + " " + boost::lexical_cast(merchantgold)); + mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast(merchantgold)); } std::vector TradeWindow::getEquippedItems() diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index cc9019f2be..380fb8dd50 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -7,6 +7,7 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/timestamp.hpp" #include "../mwworld/player.hpp" @@ -186,7 +187,11 @@ namespace MWGui mProgressBar.setProgress (mCurHour, mHours); if (mCurHour <= mHours) + { MWBase::Environment::get().getWorld ()->advanceTime (1); + if (mSleeping) + MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats (); + } } if (mCurHour > mHours) @@ -197,7 +202,7 @@ namespace MWGui { MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.2); mProgressBar.setVisible (false); - mWindowManager.popGuiMode (); + mWindowManager.removeGuiMode (GM_Rest); mWaiting = false; MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); @@ -210,4 +215,11 @@ namespace MWGui } } + void WaitDialog::wakeUp () + { + mSleeping = false; + mWaiting = false; + stopWaiting(); + } + } diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index 4a401c0c6d..6af565c6ed 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -32,6 +32,7 @@ namespace MWGui void bedActivated() { setCanRest(true); } bool getSleeping() { return mWaiting && mSleeping; } + void wakeUp(); protected: MyGUI::TextBox* mDateTimeText; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index a08a84b291..87a2bc4401 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -50,7 +50,8 @@ using namespace MWGui; WindowManager::WindowManager( - const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, bool consoleOnlyScripts) + const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, + const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts) : mGuiManager(NULL) , mHud(NULL) , mMap(NULL) @@ -132,7 +133,7 @@ WindowManager::WindowManager( mDragAndDrop->mDragAndDropWidget = dragAndDropWidget; mMenu = new MainMenu(w,h); - mMap = new MapWindow(*this); + mMap = new MapWindow(*this, cacheDir); mStatsWindow = new StatsWindow(*this); mConsole = new Console(w,h, consoleOnlyScripts); mJournal = new JournalWindow(*this); @@ -521,9 +522,9 @@ int WindowManager::readPressedButton () const std::string &WindowManager::getGameSettingString(const std::string &id, const std::string &default_) { - const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.search(id); + const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.find(id); if (setting && setting->mType == ESM::VT_String) - return setting->mStr; + return setting->getString(); return default_; } @@ -679,9 +680,9 @@ void WindowManager::setDragDrop(bool dragDrop) void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result) { - const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.search(_tag); + const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.find(_tag); if (setting && setting->mType == ESM::VT_String) - _result = setting->mStr; + _result = setting->getString(); else _result = _tag; } @@ -955,6 +956,11 @@ bool WindowManager::getPlayerSleeping () return mWaitDialog->getSleeping(); } +void WindowManager::wakeUpPlayer() +{ + mWaitDialog->wakeUp(); +} + void WindowManager::addVisitedLocation(const std::string& name, int x, int y) { mMap->addVisitedLocation (name, x, y); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 47461f877a..e30e110d35 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -71,7 +71,9 @@ namespace MWGui typedef std::pair Faction; typedef std::vector FactionList; - WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, bool consoleOnlyScripts); + WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, + OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, + const std::string& cacheDir, bool consoleOnlyScripts); virtual ~WindowManager(); /** @@ -207,6 +209,7 @@ namespace MWGui virtual bool getRestEnabled() { return mRestAllowed; } virtual bool getPlayerSleeping(); + virtual void wakeUpPlayer(); private: OEngine::GUI::MyGUIManager *mGuiManager; diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index b4cc40fec2..87a0583948 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -7,9 +7,15 @@ #include +#include + #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + #include "creaturestats.hpp" namespace MWMechanics @@ -20,7 +26,7 @@ namespace MWMechanics adjustMagicEffects (ptr); calculateCreatureStatModifiers (ptr); calculateDynamicStats (ptr); - + // AI CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); creatureStats.getAiSequence().execute (ptr); @@ -76,6 +82,48 @@ namespace MWMechanics creatureStats.getFatigue().setBase(strength+willpower+agility+endurance); } + void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration) + { + CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); + + if (duration == 3600) + { + // stunted magicka + bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(136)).mMagnitude > 0; + + int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); + stats.getHealth().setCurrent(stats.getHealth ().getCurrent () + + 0.1 * endurance); + + const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + float fFatigueReturnBase = store.gameSettings.find("fFatigueReturnBase")->getFloat (); + float fFatigueReturnMult = store.gameSettings.find("fFatigueReturnMult")->getFloat (); + float fEndFatigueMult = store.gameSettings.find("fEndFatigueMult")->getFloat (); + + float capacity = MWWorld::Class::get(ptr).getCapacity(ptr); + float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr); + float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity); + if (normalizedEncumbrance > 1) + normalizedEncumbrance = 1; + + float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); + x *= fEndFatigueMult * endurance; + stats.getFatigue ().setCurrent (stats.getFatigue ().getCurrent () + 3600 * x); + + if (!stunted) + { + float fRestMagicMult = store.gameSettings.find("fRestMagicMult")->getFloat (); + stats.getMagicka().setCurrent (stats.getMagicka ().getCurrent () + + fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified ()); + } + } + + + + } + + void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr) { CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); @@ -159,4 +207,12 @@ namespace MWMechanics movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector)); } } + + void Actors::restoreDynamicStats() + { + for (std::set::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter) + { + calculateRestoration (*iter, 3600); + } + } } diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index d5dcef487c..7e5a0ac861 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -31,6 +31,9 @@ namespace MWMechanics void calculateCreatureStatModifiers (const MWWorld::Ptr& ptr); + void calculateRestoration (const MWWorld::Ptr& ptr, float duration); + + public: Actors(); @@ -54,6 +57,8 @@ namespace MWMechanics ///< This function is normally called automatically during the update process, but it can /// also be called explicitly at any time to force an update. + void restoreDynamicStats(); + ///< If the player is sleeping, this should be called every hour. }; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index cd4f439cf1..364e653217 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -282,6 +282,11 @@ namespace MWMechanics mActors.update (movement, duration, paused); } + void MechanicsManager::restoreDynamicStats() + { + mActors.restoreDynamicStats (); + } + void MechanicsManager::setPlayerName (const std::string& name) { MWBase::Environment::get().getWorld()->getPlayer().setName (name); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index d5fd3b6f2f..3a41e8fa60 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -73,6 +73,9 @@ namespace MWMechanics virtual void setPlayerClass (const ESM::Class& class_); ///< Set player class to custom class. + + virtual void restoreDynamicStats(); + ///< If the player is sleeping, this should be called every hour. }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 5ffc99579a..bbd42c1471 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -97,13 +97,13 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla } float typeFactor = - MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMiscSkillBonus")->mF; + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMiscSkillBonus")->getFloat(); for (int i=0; i<5; ++i) if (class_.mData.mSkills[i][0]==skillIndex) { typeFactor = - MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMinorSkillBonus")->mF; + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMinorSkillBonus")->getFloat(); break; } @@ -112,7 +112,7 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla if (class_.mData.mSkills[i][1]==skillIndex) { typeFactor = - MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMajorSkillBonus")->mF; + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMajorSkillBonus")->getFloat(); break; } @@ -125,7 +125,7 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla if (skill->mData.mSpecialization==class_.mData.mSpecialization) { specialisationFactor = - MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fSpecialSkillBonus")->mF; + MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fSpecialSkillBonus")->getFloat(); if (specialisationFactor<=0) throw std::runtime_error ("invalid skill specialisation factor"); @@ -227,3 +227,13 @@ int MWMechanics::NpcStats::getLevelupAttributeMultiplier(int attribute) const else return 5; } + +void MWMechanics::NpcStats::flagAsUsed (const std::string& id) +{ + mUsedIds.insert (id); +} + +bool MWMechanics::NpcStats::hasBeenUsed (const std::string& id) const +{ + return mUsedIds.find (id)!=mUsedIds.end(); +} diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 7c3055783d..48e63d7b6e 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -50,6 +50,8 @@ namespace MWMechanics std::vector mSkillIncreases; // number of skill increases for each attribute + std::set mUsedIds; + public: NpcStats(); @@ -86,6 +88,10 @@ namespace MWMechanics int getLevelupAttributeMultiplier(int attribute) const; void levelUp(); + + void flagAsUsed (const std::string& id); + + bool hasBeenUsed (const std::string& id) const; }; } diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 3d7629e5b5..ef92497e55 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -49,44 +49,27 @@ bool Animation::findGroupTimes(const std::string &groupname, Animation::GroupTim std::string::const_iterator strpos = iter->second.begin(); std::string::const_iterator strend = iter->second.end(); + size_t strlen = strend-strpos; - while(strpos != strend) + if(start.size() <= strlen && std::mismatch(strpos, strend, start.begin(), checklow()).first == strend) { - size_t strlen = strend-strpos; - std::string::const_iterator striter; - - if(start.size() <= strlen && - ((striter=std::mismatch(strpos, strend, start.begin(), checklow()).first) == strend || - *striter == '\r' || *striter == '\n')) - { - times->mStart = iter->first; - times->mLoopStart = iter->first; - } - else if(startloop.size() <= strlen && - ((striter=std::mismatch(strpos, strend, startloop.begin(), checklow()).first) == strend || - *striter == '\r' || *striter == '\n')) - { - times->mLoopStart = iter->first; - } - else if(stoploop.size() <= strlen && - ((striter=std::mismatch(strpos, strend, stoploop.begin(), checklow()).first) == strend || - *striter == '\r' || *striter == '\n')) - { + times->mStart = iter->first; + times->mLoopStart = iter->first; + } + else if(startloop.size() <= strlen && std::mismatch(strpos, strend, startloop.begin(), checklow()).first == strend) + { + times->mLoopStart = iter->first; + } + else if(stoploop.size() <= strlen && std::mismatch(strpos, strend, stoploop.begin(), checklow()).first == strend) + { + times->mLoopStop = iter->first; + } + else if(stop.size() <= strlen && std::mismatch(strpos, strend, stop.begin(), checklow()).first == strend) + { + times->mStop = iter->first; + if(times->mLoopStop < 0.0f) times->mLoopStop = iter->first; - } - else if(stop.size() <= strlen && - ((striter=std::mismatch(strpos, strend, stop.begin(), checklow()).first) == strend || - *striter == '\r' || *striter == '\n')) - { - times->mStop = iter->first; - if(times->mLoopStop < 0.0f) - times->mLoopStop = iter->first; - break; - } - - strpos = std::find(strpos+1, strend, '\n'); - while(strpos != strend && *strpos == '\n') - strpos++; + break; } } @@ -104,17 +87,9 @@ void Animation::playGroup(std::string groupname, int mode, int loops) times.mStart = times.mLoopStart = 0.0f; times.mLoopStop = times.mStop = 0.0f; - if(mEntityList.mSkelBase) - { - Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates(); - Ogre::AnimationStateIterator as = aset->getAnimationStateIterator(); - while(as.hasMoreElements()) - { - Ogre::AnimationState *state = as.getNext(); - times.mLoopStop = times.mStop = state->getLength(); - break; - } - } + NifOgre::TextKeyMap::const_reverse_iterator iter = mTextKeys.rbegin(); + if(iter != mTextKeys.rend()) + times.mLoopStop = times.mStop = iter->first; } else if(!findGroupTimes(groupname, ×)) throw std::runtime_error("Failed to find animation group "+groupname); diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index c8852bff52..f755f34ef2 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -25,6 +25,7 @@ namespace MWRender , mPosition(position) , mLookAt(lookAt) , mCharacter(character) + , mAnimation(NULL) { } @@ -53,10 +54,13 @@ namespace MWRender mCamera->setNearClipDistance (0.01); mCamera->setFarClipDistance (1000); - mTexture = Ogre::TextureManager::getSingleton().createManual(mName, - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mSizeX, mSizeY, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET); + mTexture = Ogre::TextureManager::getSingleton().getByName (mName); + if (mTexture.isNull ()) + mTexture = Ogre::TextureManager::getSingleton().createManual(mName, + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mSizeX, mSizeY, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET); mRenderTarget = mTexture->getBuffer()->getRenderTarget(); + mRenderTarget->removeAllViewports (); mViewport = mRenderTarget->addViewport(mCamera); mViewport->setOverlaysEnabled(false); mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0)); @@ -71,7 +75,7 @@ namespace MWRender CharacterPreview::~CharacterPreview () { - Ogre::TextureManager::getSingleton().remove(mName); + //Ogre::TextureManager::getSingleton().remove(mName); mSceneMgr->destroyCamera (mName); delete mAnimation; } diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index a237d9ab7c..4f71507545 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -19,6 +19,7 @@ #include "../mwworld/ptr.hpp" #include "player.hpp" +#include "renderconst.hpp" using namespace Ogre; @@ -86,6 +87,8 @@ ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid) } result->end(); + result->setVisibilityFlags (RV_Debug); + return result; } @@ -140,6 +143,8 @@ ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid) result->end(); + result->setVisibilityFlags (RV_Debug); + return result; } diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index a0bfdd8e8f..c23fdc1a3b 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -19,6 +19,8 @@ namespace MWRender GlobalMap::GlobalMap(const std::string &cacheDir) : mCacheDir(cacheDir) + , mMinX(0), mMaxX(0) + , mMinY(0), mMaxY(0) { } @@ -27,21 +29,35 @@ namespace MWRender { Ogre::TexturePtr tex; - if (!boost::filesystem::exists(mCacheDir + "/GlobalMap.png")) + // get the size of the world + const ESMS::CellList::ExtCells& extCells = MWBase::Environment::get().getWorld ()->getStore ().cells.extCells; + for (ESMS::CellList::ExtCells::const_iterator it = extCells.begin(); it != extCells.end(); ++it) { + if (it->first.first < mMinX) + mMinX = it->first.first; + if (it->first.first > mMaxX) + mMaxX = it->first.first; + if (it->first.second < mMinY) + mMinY = it->first.second; + if (it->first.second > mMaxY) + mMaxY = it->first.second; + } - int cellSize = 24; + int cellSize = 24; + mWidth = cellSize*(mMaxX-mMinX+1); + mHeight = cellSize*(mMaxY-mMinY+1); + + //if (!boost::filesystem::exists(mCacheDir + "/GlobalMap.png")) + if (1) + { Ogre::Image image; - int width = cellSize*61; - int height = cellSize*61; + Ogre::uchar data[mWidth * mHeight * 3]; - Ogre::uchar data[width * height * 3]; - - for (int x = -30; x <= 30; ++x) + for (int x = mMinX; x <= mMaxX; ++x) { - for (int y = -30; y <= 30; ++y) + for (int y = mMinY; y <= mMaxY; ++y) { ESM::Land* land = MWBase::Environment::get().getWorld ()->getStore ().lands.search (x,y); @@ -61,8 +77,8 @@ namespace MWRender int vertexY = float(cellY)/float(cellSize) * ESM::Land::LAND_SIZE; - int texelX = (x+30) * cellSize + cellX; - int texelY = (height-1) - ((y+30) * cellSize + cellY); + int texelX = (x-mMinX) * cellSize + cellX; + int texelY = (mHeight-1) - ((y-mMinY) * cellSize + cellY); Ogre::ColourValue waterShallowColour(0.15, 0.2, 0.19); Ogre::ColourValue waterDeepColour(0.1, 0.14, 0.13); @@ -123,20 +139,23 @@ namespace MWRender b = waterDeepColour.b * 255; } - data[texelY * height * 3 + texelX * 3] = r; - data[texelY * height * 3 + texelX * 3+1] = g; - data[texelY * height * 3 + texelX * 3+2] = b; + // uncomment this line to outline cell borders + //if (cellX == 0 || cellX == cellSize-1 || cellY == 0|| cellY == cellSize-1) r = 255; + + data[texelY * mWidth * 3 + texelX * 3] = r; + data[texelY * mWidth * 3 + texelX * 3+1] = g; + data[texelY * mWidth * 3 + texelX * 3+2] = b; } } } } - image.loadDynamicImage (data, width, height, Ogre::PF_B8G8R8); + image.loadDynamicImage (data, mWidth, mHeight, Ogre::PF_B8G8R8); - image.save (mCacheDir + "/GlobalMap.png"); + //image.save (mCacheDir + "/GlobalMap.png"); tex = Ogre::TextureManager::getSingleton ().createManual ("GlobalMap.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::TEX_TYPE_2D, width, height, 0, Ogre::PF_B8G8R8, Ogre::TU_DEFAULT); + Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, Ogre::PF_B8G8R8, Ogre::TU_DEFAULT); tex->loadImage(image); } else @@ -145,4 +164,20 @@ namespace MWRender tex->load(); } + void GlobalMap::worldPosToImageSpace(float x, float z, float& imageX, float& imageY) + { + imageX = float(x / 8192.f - mMinX) / (mMaxX - mMinX + 1); + + imageY = 1.f-float(-z / 8192.f - mMinY) / (mMaxY - mMinY + 1); + } + + void GlobalMap::cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY) + { + imageX = float(x - mMinX) / (mMaxX - mMinX + 1); + + // NB y + 1, because we want the top left corner, not bottom left where the origin of the cell is + imageY = 1.f-float(y - mMinY + 1) / (mMaxY - mMinY + 1); + } + + } diff --git a/apps/openmw/mwrender/globalmap.hpp b/apps/openmw/mwrender/globalmap.hpp index b7c199dcf0..01f5fdb9e8 100644 --- a/apps/openmw/mwrender/globalmap.hpp +++ b/apps/openmw/mwrender/globalmap.hpp @@ -13,8 +13,22 @@ namespace MWRender void render(); + int getWidth() { return mWidth; } + int getHeight() { return mHeight; } + + void worldPosToImageSpace(float x, float z, float& imageX, float& imageY); + ///< @param x x ogre coords + /// @param z z ogre coords + + void cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY); + private: std::string mCacheDir; + + int mWidth; + int mHeight; + + int mMinX, mMaxX, mMinY, mMaxY; }; } diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 297cb8d7a3..8c8bbb86f7 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -323,6 +323,7 @@ namespace MWRender bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera) { float xch; + mCamera->getParentSceneNode ()->needUpdate(true); camera = mCamera->getRealPosition(); xch = camera.z, camera.z = camera.y, camera.y = -xch; player = mPlayerNode->getPosition(); diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index e6ecb51504..75e243ec79 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -56,9 +56,9 @@ enum VisibilityFlags RV_PlayerPreview = 512, - RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water + RV_Debug = 1024, - /// \todo markers (normally hidden) + RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 99b82bd0c2..c937c9894f 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -101,7 +101,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const MaterialManager::getSingleton().setDefaultTextureFiltering(tfo); MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 ); - ResourceGroupManager::getSingleton ().declareResource ("GlobalMap.png", "Texture", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + //ResourceGroupManager::getSingleton ().declareResource ("GlobalMap.png", "Texture", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); @@ -164,8 +164,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mDebugging = new Debugging(mMwRoot, engine); mLocalMap = new MWRender::LocalMap(&mRendering, this); - mGlobalMap = new GlobalMap(cacheDir.string()); - setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); } @@ -182,7 +180,6 @@ RenderingManager::~RenderingManager () delete mOcclusionQuery; delete mCompositors; delete mWater; - delete mGlobalMap; } MWRender::SkyManager* RenderingManager::getSkyManager() @@ -901,9 +898,4 @@ void RenderingManager::setupExternalRendering (MWRender::ExternalRendering& rend rendering.setup (mRendering.getScene()); } -void RenderingManager::renderGlobalMap () -{ - mGlobalMap->render (); -} - } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 24ec8b15b4..359809b71d 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -195,8 +195,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void setupExternalRendering (MWRender::ExternalRendering& rendering); - void renderGlobalMap(); - protected: virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw); diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index a4a9e99fd8..584a299267 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -205,5 +205,6 @@ op 0x200019e: PlaceAtMe Explicit op 0x200019f: GetPcSleep op 0x20001a0: ShowMap op 0x20001a1: FillMap -opcodes 0x20001a2-0x3ffffff unused +op 0x20001a2: WakeUpPc +opcodes 0x20001a3-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a869f882b1..674548cd68 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -31,6 +31,16 @@ namespace MWScript } }; + class OpWakeUpPc : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWBase::Environment::get().getWindowManager ()->wakeUpPlayer(); + } + }; + class OpXBox : public Interpreter::Opcode0 { public: @@ -261,6 +271,7 @@ namespace MWScript const int opcodeDontSaveObject = 0x2000153; const int opcodeToggleVanityMode = 0x2000174; const int opcodeGetPcSleep = 0x200019f; + const int opcodeWakeUpPc = 0x20001a2; void registerExtensions (Compiler::Extensions& extensions) { @@ -286,6 +297,7 @@ namespace MWScript extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode); extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode); extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep); + extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -307,6 +319,7 @@ namespace MWScript interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject); interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode); interpreter.installSegment5 (opcodeGetPcSleep, new OpGetPcSleep); + interpreter.installSegment5 (opcodeWakeUpPc, new OpWakeUpPc); } } } diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 38e827ea61..6e70f588e0 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -442,7 +442,7 @@ namespace MWScript ESM::Position ipos = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getRefData().getPosition(); Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]); - Ogre::Quaternion rot(Ogre::Radian(ipos.rot[2]), Ogre::Vector3::UNIT_Z); + Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z); if(direction == 0) pos = pos + distance*rot.yAxis(); else if(direction == 1) pos = pos - distance*rot.yAxis(); else if(direction == 2) pos = pos - distance*rot.xAxis(); @@ -485,7 +485,7 @@ namespace MWScript ESM::Position ipos = me.getRefData().getPosition(); Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]); - Ogre::Quaternion rot(Ogre::Radian(ipos.rot[2]), Ogre::Vector3::UNIT_Z); + Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z); if(direction == 0) pos = pos + distance*rot.yAxis(); else if(direction == 1) pos = pos - distance*rot.yAxis(); else if(direction == 2) pos = pos - distance*rot.xAxis(); diff --git a/apps/openmw/mwworld/actionread.cpp b/apps/openmw/mwworld/actionread.cpp index 361da19f42..4ac613df7f 100644 --- a/apps/openmw/mwworld/actionread.cpp +++ b/apps/openmw/mwworld/actionread.cpp @@ -35,22 +35,21 @@ namespace MWWorld MWBase::Environment::get().getWindowManager()->getBookWindow()->open(getTarget()); } - /* + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); + // Skill gain from books - if (ref->base->data.skillID >= 0 && ref->base->data.skillID < ESM::Skill::Length) + if (ref->base->mData.mSkillID >= 0 && ref->base->mData.mSkillID < ESM::Skill::Length + && !npcStats.hasBeenUsed (ref->base->mId)) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); - MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); MWWorld::LiveCellRef *playerRef = player.get(); const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( - playerRef->base->cls); + playerRef->base->mClass); - npcStats.increaseSkill (ref->base->data.skillID, *class_, true); + npcStats.increaseSkill (ref->base->mData.mSkillID, *class_, true); - /// \todo Remove skill from the book. Right now you can read as many times as you want - /// and the skill will still increase. + npcStats.flagAsUsed (ref->base->mId); } - */ } } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 098da50235..3bc06b5813 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -76,7 +76,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr) // gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001 // this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold) - if (MWWorld::Class::get(ptr).getName(ptr) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->mStr) + if (MWWorld::Class::get(ptr).getName(ptr) == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) { MWWorld::LiveCellRef *gold = ptr.get(); diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 8b918e2023..391b34a840 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -41,7 +41,8 @@ const float WeatherGlobals::mThunderSoundDelay = 0.25; WeatherManager::WeatherManager(MWRender::RenderingManager* rendering) : mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), - mRemainingTransitionTime(0), mMonth(0), mDay(0) + mRemainingTransitionTime(0), mMonth(0), mDay(0), + mTimePassed(0) { mRendering = rendering; @@ -487,7 +488,10 @@ WeatherResult WeatherManager::transition(float factor) void WeatherManager::update(float duration) { - mWeatherUpdateTime -= duration * MWBase::Environment::get().getWorld()->getTimeScaleFactor(); + float timePassed = mTimePassed; + mTimePassed = 0; + + mWeatherUpdateTime -= timePassed; bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); @@ -558,7 +562,7 @@ void WeatherManager::update(float duration) if (mNextWeather != "") { - mRemainingTransitionTime -= duration * MWBase::Environment::get().getWorld()->getTimeScaleFactor(); + mRemainingTransitionTime -= timePassed; if (mRemainingTransitionTime < 0) { mCurrentWeather = mNextWeather; diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 5e0388751f..589dff3ebf 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -231,6 +231,11 @@ namespace MWWorld void setDate(const int day, const int month); + void advanceTime(double hours) + { + mTimePassed += hours*3600; + } + unsigned int getWeatherID() const; private: @@ -261,6 +266,8 @@ namespace MWWorld float mThunderChanceNeeded; float mThunderSoundDelay; + double mTimePassed; // time passed since last update + WeatherResult transition(const float factor); WeatherResult getResult(const Ogre::String& weather); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 1bb29e9a67..6fc228f0b5 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -366,6 +366,8 @@ namespace MWWorld void World::advanceTime (double hours) { + mWeatherManager->advanceTime (hours); + hours += mGlobalVariables->getFloat ("gamehour"); setHour (hours); @@ -526,7 +528,7 @@ namespace MWWorld std::pair result = mPhysics->getFacedHandle (*this); if (result.first.empty() || - result.second>getStore().gameSettings.find ("iMaxActivateDist")->mI) + result.second>getStore().gameSettings.find ("iMaxActivateDist")->getInt()) return ""; return result.first; @@ -1253,11 +1255,6 @@ namespace MWWorld mRendering->renderPlayer(mPlayer->getPlayer()); } - void World::renderGlobalMap () - { - mRendering->renderGlobalMap (); - } - void World::setupExternalRendering (MWRender::ExternalRendering& rendering) { mRendering->setupExternalRendering (rendering); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 5c57279051..90cd2151b6 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -313,7 +313,6 @@ namespace MWWorld } virtual void renderPlayer(); - virtual void renderGlobalMap(); virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); diff --git a/components/esm/loadbook.hpp b/components/esm/loadbook.hpp index dc7067e1f2..9f937ee4be 100644 --- a/components/esm/loadbook.hpp +++ b/components/esm/loadbook.hpp @@ -19,9 +19,10 @@ struct Book BKDTstruct mData; std::string mName, mModel, mIcon, mScript, mEnchant, mText; + std::string mId; void load(ESMReader &esm); void save(ESMWriter &esm); - }; +}; } #endif diff --git a/components/esm/loadgmst.cpp b/components/esm/loadgmst.cpp index aca880b4dc..dcc5001254 100644 --- a/components/esm/loadgmst.cpp +++ b/components/esm/loadgmst.cpp @@ -197,7 +197,7 @@ int GameSetting::getInt() const } } -int GameSetting::getFloat() const +float GameSetting::getFloat() const { switch (mType) { diff --git a/components/esm/loadgmst.hpp b/components/esm/loadgmst.hpp index acfc49814b..8435899f5e 100644 --- a/components/esm/loadgmst.hpp +++ b/components/esm/loadgmst.hpp @@ -87,7 +87,7 @@ struct GameSetting int getInt() const; ///< Throws an exception if GMST is not of type int or float. - int getFloat() const; + float getFloat() const; ///< Throws an exception if GMST is not of type int or float. std::string getString() const; diff --git a/components/esm_store/store.hpp b/components/esm_store/store.hpp index 991925bd47..7329386d4a 100644 --- a/components/esm_store/store.hpp +++ b/components/esm_store/store.hpp @@ -34,7 +34,7 @@ namespace ESMS RecListT appas; RecListT armors; RecListT bodyParts; - RecListT books; + RecListWithIDT books; RecListT birthSigns; RecListT classes; RecListT clothes; diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index a70eb7629d..6449ad246c 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -193,7 +193,8 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, // affecting the entire subtree of this node Nif::NiStringExtraData *sd = (Nif::NiStringExtraData*)e; - if (sd->string == "NCO") + // not sure what the difference between NCO and NCC is, or if there even is one + if (sd->string == "NCO" || sd->string == "NCC") { // No collision. Use an internal flag setting to mark this. flags |= 0x800; diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 5127af966a..ad51d50b95 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -152,6 +152,28 @@ static void fail(const std::string &msg) } +static void insertTextKeys(const Nif::NiTextKeyExtraData *tk, TextKeyMap *textkeys) +{ + for(size_t i = 0;i < tk->list.size();i++) + { + const std::string &str = tk->list[i].text; + std::string::size_type pos = 0; + while(pos < str.length()) + { + while(pos < str.length() && ::isspace(str[pos])) + pos++; + if(pos >= str.length()) + break; + + std::string::size_type nextpos = std::min(str.find('\r', pos), str.find('\n', pos)); + textkeys->insert(std::make_pair(tk->list[i].time, str.substr(pos, nextpos-pos))); + + pos = nextpos; + } + } +} + + void buildBones(Ogre::Skeleton *skel, const Nif::Node *node, std::vector &ctrls, Ogre::Bone *parent=NULL) { Ogre::Bone *bone; @@ -274,23 +296,18 @@ void loadResource(Ogre::Resource *resource) if(scaleiter != scalekeys.mKeys.end()) lastscale = curscale = Ogre::Vector3(scaleiter->mValue) / startscale; bool didlast = false; - + while(!didlast) { float curtime = kfc->timeStop; - //Get latest time - if(quatiter != quatkeys.mKeys.end()){ + if(quatiter != quatkeys.mKeys.end()) curtime = std::min(curtime, quatiter->mTime); - } - if(traniter != trankeys.mKeys.end()){ + if(traniter != trankeys.mKeys.end()) curtime = std::min(curtime, traniter->mTime); - - } - if(scaleiter != scalekeys.mKeys.end()){ + if(scaleiter != scalekeys.mKeys.end()) curtime = std::min(curtime, scaleiter->mTime); - } curtime = std::max(curtime, kfc->timeStart); if(curtime >= kfc->timeStop) @@ -299,15 +316,33 @@ void loadResource(Ogre::Resource *resource) curtime = kfc->timeStop; } - bool rinterpolate = quatiter != quatkeys.mKeys.end() && quatiter != quatkeys.mKeys.begin() && curtime != quatiter->mTime; - bool tinterpolate = traniter != trankeys.mKeys.end() && traniter != trankeys.mKeys.begin() && curtime != traniter->mTime; - bool sinterpolate = scaleiter != scalekeys.mKeys.end() && scaleiter != scalekeys.mKeys.begin() && curtime != scaleiter->mTime; + // Get the latest quaternions, translations, and scales for the + // current time + while(quatiter != quatkeys.mKeys.end() && curtime >= quatiter->mTime) + { + lastquat = curquat; + quatiter++; + if(quatiter != quatkeys.mKeys.end()) + curquat = startquat.Inverse() * quatiter->mValue ; + } + while(traniter != trankeys.mKeys.end() && curtime >= traniter->mTime) + { + lasttrans = curtrans; + traniter++; + if(traniter != trankeys.mKeys.end()) + curtrans = traniter->mValue - starttrans; + } + while(scaleiter != scalekeys.mKeys.end() && curtime >= scaleiter->mTime) + { + lastscale = curscale; + scaleiter++; + if(scaleiter != scalekeys.mKeys.end()) + curscale = Ogre::Vector3(scaleiter->mValue) / startscale; + } - - Ogre::TransformKeyFrame *kframe; kframe = nodetrack->createNodeKeyFrame(curtime); - if(!rinterpolate) + if(quatiter == quatkeys.mKeys.end() || quatiter == quatkeys.mKeys.begin()) kframe->setRotation(curquat); else { @@ -315,7 +350,7 @@ void loadResource(Ogre::Resource *resource) float diff = (curtime-last->mTime) / (quatiter->mTime-last->mTime); kframe->setRotation(Ogre::Quaternion::nlerp(diff, lastquat, curquat)); } - if(!tinterpolate) + if(traniter == trankeys.mKeys.end() || traniter == trankeys.mKeys.begin()) kframe->setTranslate(curtrans); else { @@ -323,7 +358,7 @@ void loadResource(Ogre::Resource *resource) float diff = (curtime-last->mTime) / (traniter->mTime-last->mTime); kframe->setTranslate(lasttrans + ((curtrans-lasttrans)*diff)); } - if(!sinterpolate) + if(scaleiter == scalekeys.mKeys.end() || scaleiter == scalekeys.mKeys.begin()) kframe->setScale(curscale); else { @@ -331,31 +366,6 @@ void loadResource(Ogre::Resource *resource) float diff = (curtime-last->mTime) / (scaleiter->mTime-last->mTime); kframe->setScale(lastscale + ((curscale-lastscale)*diff)); } - - // Get the latest quaternion, translation, and scale for the - // current time - while(quatiter != quatkeys.mKeys.end() && curtime >= quatiter->mTime) - { - quatiter++; - lastquat = curquat; - if(quatiter != quatkeys.mKeys.end()) - curquat = startquat.Inverse() * quatiter->mValue ; - } - while(traniter != trankeys.mKeys.end() && curtime >= traniter->mTime) - { - traniter++; - lasttrans = curtrans; - if(traniter != trankeys.mKeys.end()) - curtrans = traniter->mValue - starttrans; - } - while(scaleiter != scalekeys.mKeys.end() && curtime >= scaleiter->mTime) - { - scaleiter++; - lastscale = curscale; - if(scaleiter != scalekeys.mKeys.end()) - curscale = Ogre::Vector3(scaleiter->mValue) / startscale; - } - } } anim->optimise(); @@ -371,8 +381,7 @@ bool createSkeleton(const std::string &name, const std::string &group, TextKeyMa if(e->recType == Nif::RC_NiTextKeyExtraData) { const Nif::NiTextKeyExtraData *tk = static_cast(e.getPtr()); - for(size_t i = 0;i < tk->list.size();i++) - (*textkeys)[tk->list[i].time] = tk->list[i].text; + insertTextKeys(tk, textkeys); } e = e->extra; } diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index b6610d8a7a..a203112b50 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -59,7 +59,7 @@ namespace NifOgre { // FIXME: These should not be in NifOgre, it works agnostic of what model format is used -typedef std::map TextKeyMap; +typedef std::multimap TextKeyMap; struct EntityList { std::vector mEntities; Ogre::Entity *mSkelBase; diff --git a/files/materials/water.shader b/files/materials/water.shader index 8f46aed344..947dc72f5e 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -123,9 +123,9 @@ #define REFR_BUMP 0.06 // refraction distortion amount #define SCATTER_AMOUNT 3.0 // amount of sunlight scattering - #define SCATTER_COLOUR float3(0.0,1.0,0.95) // colour of sunlight scattering + #define SCATTER_COLOUR gammaCorrectRead(float3(0.0,1.0,0.95)) // colour of sunlight scattering - #define SUN_EXT float3(0.45, 0.55, 0.68) //sunlight extinction + #define SUN_EXT gammaCorrectRead(float3(0.45, 0.55, 0.68)) //sunlight extinction #define SPEC_HARDNESS 256 // specular highlights hardness @@ -177,6 +177,7 @@ shUniform(float4, sunPosition) @shAutoConstant(sunPosition, light_position, 0) shUniform(float4, sunSpecular) @shAutoConstant(sunSpecular, light_specular_colour, 0) + shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) shUniform(float, renderTargetFlipping) @shAutoConstant(renderTargetFlipping, render_target_flipping) @@ -242,7 +243,7 @@ float s = shSaturate(dot(lR, vVec)*2.0-1.2); float lightScatter = shSaturate(dot(-lVec,lNormal)*0.7+0.3) * s * SCATTER_AMOUNT * waterSunFade_sunHeight.x * shSaturate(1.0-exp(-waterSunFade_sunHeight.y)); - float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*float3(1.0,0.4,0.0), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); + float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*gammaCorrectRead(float3(1.0,0.4,0.0)), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); // fresnel float ior = (cameraPos.y>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air @@ -251,7 +252,7 @@ fresnel = shSaturate(fresnel); // reflection - float3 reflection = shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb; + float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb); // refraction float3 R = reflect(vVec, normal); @@ -262,8 +263,7 @@ float refractDepth = shSample(depthMap, screenCoords-(shoreFade * normal.xz*REFR_BUMP)).x * far - depthPassthrough; float doRefraction = (refractDepth < 0) ? 0.f : 1.f; - float3 refraction = float3(0,0,0); - refraction.rgb = shSample(refractionMap, (screenCoords-(shoreFade * normal.xz*REFR_BUMP * doRefraction))*1.0).rgb; + float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(shoreFade * normal.xz*REFR_BUMP * doRefraction))*1.0).rgb); // brighten up the refraction underwater refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction; @@ -281,12 +281,12 @@ { float waterSunGradient = dot(-vVec, -lVec); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; + float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85))*waterSunGradient * 0.5; float waterGradient = dot(-vVec, float3(0.0,-1.0,0.0)); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; - float3 waterext = float3(0.6, 0.9, 1.0);//water extinction + float3 watercolour = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; + float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); float darkness = VISIBILITY*2.0; @@ -299,9 +299,11 @@ else { float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColor), fogValue); } + shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); + shOutputColour(0).w = 1; } diff --git a/files/openmw.cfg b/files/openmw.cfg index c79369d054..b37e5a22bd 100644 --- a/files/openmw.cfg +++ b/files/openmw.cfg @@ -1,4 +1,4 @@ -data="?global?"data" +data="?global?data" data="?mw?Data Files" data-local="?local?data" resources=${MORROWIND_RESOURCE_FILES} diff --git a/libs/openengine/bullet/BtOgreExtras.h b/libs/openengine/bullet/BtOgreExtras.h index f3e1aa87ab..423924eda8 100644 --- a/libs/openengine/bullet/BtOgreExtras.h +++ b/libs/openengine/bullet/BtOgreExtras.h @@ -206,6 +206,8 @@ public: } mLineDrawer->setMaterial("BtOgre/DebugLines"); + + mLineDrawer->setVisibilityFlags (1024); } ~DebugDrawer() diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 74352b358b..b42ffb84c1 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -303,16 +303,11 @@ namespace Physic + boost::lexical_cast(y); // find the minimum and maximum heights (needed for bullet) - float minh; - float maxh; + float minh = heights[0]; + float maxh = heights[0]; for (int i=0; imaxh) maxh = h; if (hps->velocity[2] = 0; // don't build up falling damage, but allow sideways acceleration - pm->ps.velocity.z = 0; + pm->ps.velocity = Ogre::Vector3(0,0,0); return true; } diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 03ed4ffb14..9f53985745 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -13,8 +13,8 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) //Traceobj was a Aedra Object { - static float lastyaw = 0.0f; - static float lastpitch = 0.0f; + //static float lastyaw = 0.0f; + //static float lastpitch = 0.0f; //if (!traceobj) // return; diff --git a/libs/openengine/ogre/fader.cpp b/libs/openengine/ogre/fader.cpp index ba532b5273..6965ffc78b 100644 --- a/libs/openengine/ogre/fader.cpp +++ b/libs/openengine/ogre/fader.cpp @@ -24,7 +24,8 @@ Fader::Fader(Ogre::SceneManager* sceneMgr) MaterialPtr material = MaterialManager::getSingleton().create("FadeInOutMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); Pass* pass = material->getTechnique(0)->getPass(0); pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); - mFadeTextureUnit = pass->createTextureUnitState(); + pass->setDepthWriteEnabled (false); + mFadeTextureUnit = pass->createTextureUnitState("black.png"); mFadeTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(0.f, 0.f, 0.f)); // always black colour mRectangle = new Ogre::Rectangle2D(true);