Add OpenMW commits up to 6 June 2019

# Conflicts:
#	apps/openmw/mwgui/hud.cpp
#	apps/openmw/mwgui/jailscreen.cpp
#	apps/openmw/mwgui/waitdialog.cpp
#	apps/openmw/mwinput/inputmanagerimp.cpp
#	apps/openmw/mwworld/worldimp.hpp
pull/541/head
David Cernat 5 years ago
commit b57c0bcafe

@ -73,10 +73,10 @@ Programmers
Finbar Crago(finbar-crago)
Florian Weber (Florianjw)
Gašper Sedej
Gijsbert ter Horst (Ghostbird)
Gohan1989
gugus/gus
guidoj
Hallfaer Tuilinn
Haoda Wang (h313)
hristoast
Internecine

@ -1,6 +1,7 @@
0.46.0
------
Bug #1515: Opening console masks dialogue, inventory menu
Bug #2969: Scripted items can stack
Bug #2987: Editor: some chance and AI data fields can overflow
Bug #3006: 'else if' operator breaks script compilation
@ -12,7 +13,9 @@
Bug #3765: DisableTeleporting makes Mark/Recall/Intervention effects undetectable
Bug #3778: [Mod] Improved Thrown Weapon Projectiles - weapons have wrong transformation during throw animation
Bug #3812: Wrong multiline tooltips width when word-wrapping is enabled
Bug #4240: Ash storm origin coordinates and hand shielding animation behavior are incorrect
Bug #4329: Removed birthsign abilities are restored after reloading the save
Bug #4341: Error message about missing GDB is too vague
Bug #4383: Bow model obscures crosshair when arrow is drawn
Bug #4384: Resist Normal Weapons only checks ammunition for ranged weapons
Bug #4411: Reloading a saved game while falling prevents damage in some cases
@ -35,6 +38,7 @@
Bug #4768: Fallback numerical value recovery chokes on invalid arguments
Bug #4775: Slowfall effect resets player jumping flag
Bug #4778: Interiors of Illusion puzzle in Sotha Sil Expanded mod is broken
Bug #4787: Sneaking makes 1st person walking/bobbing animation super-slow
Bug #4797: Player sneaking and running stances are not accounted for when in air
Bug #4800: Standing collisions are not updated immediately when an object is teleported without a cell change
Bug #4803: Stray special characters before begin statement break script compilation
@ -50,14 +54,17 @@
Bug #4828: Potion looping effects VFX are not shown for NPCs
Bug #4837: CTD when a mesh with NiLODNode root node with particles is loaded
Bug #4841: Russian localization ignores implicit keywords
Bug #4844: Data race in savegame loading / GlobalMap render
Bug #4847: Idle animation reset oddities
Bug #4851: No shadows since switch to OSG
Bug #4860: Actors outside of processing range visible for one frame after spawning
Bug #4867: Arbitrary text after local variable declarations breaks script compilation
Bug #4876: AI ratings handling inconsistencies
Bug #4877: Startup script executes only on a new game start
Bug #4879: SayDone returns 0 on the frame Say is called
Bug #4888: Global variable stray explicit reference calls break script compilation
Bug #4896: Title screen music doesn't loop
Bug #4902: Using scrollbars in settings causes resolution to change
Bug #4911: Editor: QOpenGLContext::swapBuffers() warning with Qt5
Bug #4916: Specular power (shininess) material parameter is ignored when shaders are used.
Bug #4918: Abilities don't play looping VFX when they're initially applied
@ -71,6 +78,7 @@
Bug #4945: Poor random magic magnitude distribution
Bug #4947: Player character doesn't use lip animation
Bug #4948: Footstep sounds while levitating on ground level
Bug #4961: Flying creature combat engagement takes z-axis into account
Bug #4963: Enchant skill progress is incorrect
Bug #4964: Multiple effect spell projectile sounds play louder than vanilla
Bug #4965: Global light attenuation settings setup is lacking
@ -82,7 +90,15 @@
Bug #4984: "Friendly hits" feature should be used only for player's followers
Bug #4989: Object dimension-dependent VFX scaling behavior is inconsistent
Bug #4990: Dead bodies prevent you from hitting
Bug #4999: Drop instruction behaves differently from vanilla
Bug #5001: Possible data race in the Animation::setAlpha()
Bug #5004: Werewolves shield their eyes during storm
Bug #5018: Spell tooltips don't support purely negative magnitudes
Bug #5025: Data race in the ICO::setMaximumNumOfObjectsToCompilePerFrame()
Bug #5028: Offered price caps are not trading-specific
Bug #5038: Enchanting success chance calculations are blatantly wrong
Bug #5047: # in cell names sets color
Bug #5050: Invalid spell effects are not handled gracefully
Feature #1774: Handle AvoidNode
Feature #2229: Improve pathfinding AI
Feature #3025: Analogue gamepad movement controls
@ -90,12 +106,16 @@
Feature #3610: Option to invert X axis
Feature #3893: Implicit target for "set" function in console
Feature #3980: In-game option to disable controller
Feature #3999: Shift + Double Click should maximize/restore menu size
Feature #4001: Toggle sneak controller shortcut
Feature #4209: Editor: Faction rank sub-table
Feature #4255: Handle broken RepairedOnMe script function
Feature #4316: Implement RaiseRank/LowerRank functions properly
Feature #4360: Improve default controller bindings
Feature #4673: Weapon sheathing
Feature #4675: Support for NiRollController
Feature #4730: Native animated containers support
Feature #4784: Launcher: Duplicate Content Lists
Feature #4812: Support NiSwitchNode
Feature #4836: Daytime node switch
Feature #4859: Make water reflections more configurable
@ -106,6 +126,12 @@
Feature #4968: Scalable UI widget skins
Feature #4994: Persistent pinnable windows hiding
Feature #5000: Compressed BSA format support
Feature #5010: Native graphics herbalism support
Feature #5031: Make GetWeaponType function return different values for tools
Feature #5033: Magic armor mitigation for creatures
Feature #5034: Make enchanting window stay open after a failed attempt
Feature #5036: Allow scripted faction leaving
Feature #5051: Provide a separate textures for scrollbars
Task #4686: Upgrade media decoder to a more current FFmpeg API
Task #4695: Optimize Distant Terrain memory consumption
Task #4721: Add NMake support to the Windows prebuild script

@ -12,7 +12,7 @@
#include <components/esm/loadspel.hpp>
#include <components/esm/loadweap.hpp>
#include <boost/format.hpp>
#include <components/misc/stringops.hpp>
std::string bodyPartLabel(int idx)
{
@ -659,7 +659,7 @@ std::string bodyPartFlags(int flags)
(ESM::BodyPart::BPF_Female|
ESM::BodyPart::BPF_NotPlayable));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -680,7 +680,7 @@ std::string cellFlags(int flags)
ESM::Cell::QuasiEx|
0x00000040));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -696,7 +696,7 @@ std::string containerFlags(int flags)
ESM::Container::Organic|
ESM::Container::Respawn));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -722,7 +722,7 @@ std::string creatureFlags(int flags)
ESM::Creature::Weapon|
ESM::Creature::Essential));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%02X)") % flags);
properties += Misc::StringUtils::format("(0x%02X)", flags);
return properties;
}
@ -737,7 +737,7 @@ std::string landFlags(int flags)
if (flags & 0x00000004) properties += "Unknown3 ";
if (flags & 0x00000002) properties += "Unknown2 ";
if (flags & 0xFFFFFFF8) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -751,7 +751,7 @@ std::string itemListFlags(int flags)
(ESM::ItemLevList::AllLevels|
ESM::ItemLevList::Each));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -762,7 +762,7 @@ std::string creatureListFlags(int flags)
if (flags & ESM::CreatureLevList::AllLevels) properties += "AllLevels ";
int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels);
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -790,7 +790,7 @@ std::string lightFlags(int flags)
ESM::Light::Negative|
ESM::Light::OffDefault));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -816,7 +816,7 @@ std::string magicEffectFlags(int flags)
if (flags & ESM::MagicEffect::NegativeLight) properties += "NegativeLight ";
if (flags & 0xFFFC0000) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -838,7 +838,7 @@ std::string npcFlags(int flags)
ESM::NPC::Respawn|
ESM::NPC::Essential));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%02X)") % flags);
properties += Misc::StringUtils::format("(0x%02X)", flags);
return properties;
}
@ -853,7 +853,7 @@ std::string raceFlags(int flags)
(ESM::Race::Playable|
ESM::Race::Beast));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -869,7 +869,7 @@ std::string spellFlags(int flags)
ESM::Spell::F_PCStart|
ESM::Spell::F_Always));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
@ -886,6 +886,6 @@ std::string weaponFlags(int flags)
(ESM::Weapon::Magical|
ESM::Weapon::Silver));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}

@ -4,7 +4,7 @@
#include <iostream>
#include <sstream>
#include <boost/format.hpp>
#include <components/misc/stringops.hpp>
namespace
{
@ -12,7 +12,7 @@ namespace
void printAIPackage(ESM::AIPackage p)
{
std::cout << " AI Type: " << aiTypeLabel(p.mType)
<< " (" << boost::format("0x%08X") % p.mType << ")" << std::endl;
<< " (" << Misc::StringUtils::format("0x%08X", p.mType) << ")" << std::endl;
if (p.mType == ESM::AI_Wander)
{
std::cout << " Distance: " << p.mWander.mDistance << std::endl;
@ -46,7 +46,7 @@ void printAIPackage(ESM::AIPackage p)
std::cout << " Activate Unknown: " << p.mActivate.mUnk << std::endl;
}
else {
std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl;
std::cout << " BadPackage: " << Misc::StringUtils::format("0x%08X", p.mType) << std::endl;
}
if (!p.mCellName.empty())
@ -64,7 +64,7 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
char indicator = rule[2];
std::string type_str = "INVALID";
std::string func_str = str(boost::format("INVALID=%s") % rule.substr(1,3));
std::string func_str = Misc::StringUtils::format("INVALID=%s", rule.substr(1,3));
int func;
std::istringstream iss(rule.substr(2,2));
iss >> func;
@ -104,7 +104,7 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
// for all types not qual to one. If this wasn't true, go back to
// the error message.
if (type != '1' && rule[3] != 'X')
func_str = str(boost::format("INVALID=%s") % rule.substr(1,3));
func_str = Misc::StringUtils::format("INVALID=%s", rule.substr(1,3));
char oper = rule[4];
std::string oper_str = "??";
@ -122,8 +122,7 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
std::ostringstream stream;
stream << ss.mValue;
std::string result = str(boost::format("%-12s %-32s %2s %s")
% type_str % func_str % oper_str % stream.str());
std::string result = Misc::StringUtils::format("%-12s %-32s %2s %s", type_str, func_str, oper_str, stream.str());
return result;
}
@ -156,13 +155,13 @@ void printTransport(const std::vector<ESM::Transport::Dest>& transport)
for (const ESM::Transport::Dest& dest : transport)
{
std::cout << " Destination Position: "
<< boost::format("%12.3f") % dest.mPos.pos[0] << ","
<< boost::format("%12.3f") % dest.mPos.pos[1] << ","
<< boost::format("%12.3f") % dest.mPos.pos[2] << ")" << std::endl;
<< Misc::StringUtils::format("%12.3f", dest.mPos.pos[0]) << ","
<< Misc::StringUtils::format("%12.3f", dest.mPos.pos[1]) << ","
<< Misc::StringUtils::format("%12.3f", dest.mPos.pos[2]) << ")" << std::endl;
std::cout << " Destination Rotation: "
<< boost::format("%9.6f") % dest.mPos.rot[0] << ","
<< boost::format("%9.6f") % dest.mPos.rot[1] << ","
<< boost::format("%9.6f") % dest.mPos.rot[2] << ")" << std::endl;
<< Misc::StringUtils::format("%9.6f", dest.mPos.rot[0]) << ","
<< Misc::StringUtils::format("%9.6f", dest.mPos.rot[1]) << ","
<< Misc::StringUtils::format("%9.6f", dest.mPos.rot[2]) << ")" << std::endl;
if (!dest.mCellName.empty())
std::cout << " Destination Cell: " << dest.mCellName << std::endl;
}
@ -542,7 +541,7 @@ void Record<ESM::Cell>::print()
std::cout << " Water Level: " << mData.mWater << std::endl;
}
else
std::cout << " Map Color: " << boost::format("0x%08X") % mData.mMapColor << std::endl;
std::cout << " Map Color: " << Misc::StringUtils::format("0x%08X", mData.mMapColor) << std::endl;
std::cout << " Water Level Int: " << mData.mWaterInt << std::endl;
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl;
@ -607,7 +606,7 @@ void Record<ESM::Container>::print()
std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl;
std::cout << " Weight: " << mData.mWeight << std::endl;
for (const ESM::ContItem &item : mData.mInventory.mList)
std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount)
<< " Item: " << item.mItem.toString() << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl;
}
@ -653,7 +652,7 @@ void Record<ESM::Creature>::print()
std::cout << " Gold: " << mData.mData.mGold << std::endl;
for (const ESM::ContItem &item : mData.mInventory.mList)
std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount)
<< " Item: " << item.mItem.toString() << std::endl;
for (const std::string &spell : mData.mSpells.mList)
@ -669,7 +668,7 @@ void Record<ESM::Creature>::print()
std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl;
std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl;
std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl;
std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl;
std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl;
for (const ESM::AIPackage &package : mData.mAiPackage.mList)
printAIPackage(package);
@ -1073,7 +1072,7 @@ void Record<ESM::NPC>::print()
}
for (const ESM::ContItem &item : mData.mInventory.mList)
std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount)
<< " Item: " << item.mItem.toString() << std::endl;
for (const std::string &spell : mData.mSpells.mList)
@ -1089,7 +1088,7 @@ void Record<ESM::NPC>::print()
std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl;
std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl;
std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl;
std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl;
std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl;
for (const ESM::AIPackage &package : mData.mAiPackage.mList)
printAIPackage(package);
@ -1212,7 +1211,7 @@ void Record<ESM::Script>::print()
std::cout << " ByteCode: ";
for (const unsigned char &byte : mData.mScriptData)
std::cout << boost::format("%02X") % (int)(byte);
std::cout << Misc::StringUtils::format("%02X", (int)(byte));
std::cout << std::endl;
if (mPrintPlain)

@ -39,10 +39,13 @@ Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config:
const QString encoding = mGameSettings.value("encoding", "win1252");
mSelector->setEncoding(encoding);
mProfileDialog = new TextInputDialog(tr("New Content List"), tr("Content List name:"), this);
mNewProfileDialog = new TextInputDialog(tr("New Content List"), tr("Content List name:"), this);
mCloneProfileDialog = new TextInputDialog(tr("Clone Content List"), tr("Content List name:"), this);
connect(mProfileDialog->lineEdit(), SIGNAL(textChanged(QString)),
this, SLOT(updateOkButton(QString)));
connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)),
this, SLOT(updateNewProfileOkButton(QString)));
connect(mCloneProfileDialog->lineEdit(), SIGNAL(textChanged(QString)),
this, SLOT(updateCloneProfileOkButton(QString)));
buildView();
loadSettings();
@ -61,6 +64,7 @@ void Launcher::DataFilesPage::buildView()
//tool buttons
ui.newProfileButton->setToolTip ("Create a new Content List");
ui.cloneProfileButton->setToolTip ("Clone the current Content List");
ui.deleteProfileButton->setToolTip ("Delete an existing Content List");
//combo box
@ -70,6 +74,7 @@ void Launcher::DataFilesPage::buildView()
// Add the actions to the toolbuttons
ui.newProfileButton->setDefaultAction (ui.newProfileAction);
ui.cloneProfileButton->setDefaultAction (ui.cloneProfileAction);
ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction);
//establish connections
@ -246,10 +251,10 @@ void Launcher::DataFilesPage::slotProfileChanged(int index)
void Launcher::DataFilesPage::on_newProfileAction_triggered()
{
if (mProfileDialog->exec() != QDialog::Accepted)
if (mNewProfileDialog->exec() != QDialog::Accepted)
return;
QString profile = mProfileDialog->lineEdit()->text();
QString profile = mNewProfileDialog->lineEdit()->text();
if (profile.isEmpty())
return;
@ -273,6 +278,20 @@ void Launcher::DataFilesPage::addProfile (const QString &profile, bool setAsCurr
setProfile (ui.profilesComboBox->findText (profile), false);
}
void Launcher::DataFilesPage::on_cloneProfileAction_triggered()
{
if (mCloneProfileDialog->exec() != QDialog::Accepted)
return;
QString profile = mCloneProfileDialog->lineEdit()->text();
if (profile.isEmpty())
return;
mLauncherSettings.setContentList(profile, selectedFilePaths());
addProfile(profile, true);
}
void Launcher::DataFilesPage::on_deleteProfileAction_triggered()
{
QString profile = ui.profilesComboBox->currentText();
@ -295,17 +314,16 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered()
checkForDefaultProfile();
}
void Launcher::DataFilesPage::updateOkButton(const QString &text)
void Launcher::DataFilesPage::updateNewProfileOkButton(const QString &text)
{
// We do this here because we need the profiles combobox text
if (text.isEmpty()) {
mProfileDialog->setOkButtonEnabled(false);
return;
}
mNewProfileDialog->setOkButtonEnabled(!text.isEmpty() && ui.profilesComboBox->findText(text) == -1);
}
(ui.profilesComboBox->findText(text) == -1)
? mProfileDialog->setOkButtonEnabled(true)
: mProfileDialog->setOkButtonEnabled(false);
void Launcher::DataFilesPage::updateCloneProfileOkButton(const QString &text)
{
// We do this here because we need the profiles combobox text
mCloneProfileDialog->setOkButtonEnabled(!text.isEmpty() && ui.profilesComboBox->findText(text) == -1);
}
void Launcher::DataFilesPage::checkForDefaultProfile()

@ -62,9 +62,11 @@ namespace Launcher
void slotProfileDeleted(const QString &item);
void slotAddonDataChanged ();
void updateOkButton(const QString &text);
void updateNewProfileOkButton(const QString &text);
void updateCloneProfileOkButton(const QString &text);
void on_newProfileAction_triggered();
void on_cloneProfileAction_triggered();
void on_deleteProfileAction_triggered();
public:
@ -73,7 +75,8 @@ namespace Launcher
private:
TextInputDialog *mProfileDialog;
TextInputDialog *mNewProfileDialog;
TextInputDialog *mCloneProfileDialog;
Files::ConfigurationManager &mCfgMgr;

@ -53,7 +53,7 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message
// If object have creature soul trapped, check if that creature reference is valid
if (!cellRef.mSoul.empty())
if (mObjects.searchId(cellRef.mSoul) == -1)
messages.add(id, "Trapped soul object '" + cellRef.mOwner + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Trapped soul object '" + cellRef.mSoul + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (cellRef.mFaction.empty())
{

@ -62,7 +62,7 @@ add_openmw_dir (mwsound
add_openmw_dir (mwworld
refdata worldimp scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellvisitors failedaction
cells localscripts customdata inventorystore ptr actionopen actionread
cells localscripts customdata inventorystore ptr actionopen actionread actionharvest
actionequip timestamp actionalchemy cellstore actionapply actioneat
store esmstore recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
contentloader esmloader actiontrap cellreflist cellref physicssystem weather projectilemanager

@ -368,10 +368,10 @@ OMW::Engine::~Engine()
mWorkQueue = nullptr;
mResourceSystem.reset();
mViewer = nullptr;
mResourceSystem.reset();
delete mEncoder;
mEncoder = nullptr;
@ -404,7 +404,8 @@ void OMW::Engine::enableFSStrict(bool fsStrict)
void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs)
{
mDataDirs = dataDirs;
mFileCollections = Files::Collections (dataDirs, !mFSStrict);
mDataDirs.insert(mDataDirs.begin(), (mResDir / "vfs"));
mFileCollections = Files::Collections (mDataDirs, !mFSStrict);
}
// Add BSA archive

@ -273,6 +273,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
cfgMgr.processPaths(dataDirs);
engine.setResourceDir(variables["resources"].as<Files::EscapeHashString>().toStdString());
engine.setDataDirs(dataDirs);
// fallback archives
@ -282,8 +283,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.addArchive(*it);
}
engine.setResourceDir(variables["resources"].as<Files::EscapeHashString>().toStdString());
StringsVector content = variables["content"].as<Files::EscapeStringVector>().toStdStringVector();
if (content.empty())
{

@ -375,9 +375,6 @@ namespace MWBase
virtual const Translation::Storage& getTranslationDataStorage() const = 0;
/// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this.
virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0;
virtual void loadUserFonts() = 0;
virtual Loading::Listener* getLoadingScreen() = 0;
@ -408,6 +405,7 @@ namespace MWBase
virtual void removeCurrentModal(MWGui::WindowModal* input) = 0;
virtual void pinWindow (MWGui::GuiWindow window) = 0;
virtual void toggleMaximized(MWGui::Layout *layout) = 0;
/// Fade the screen in, over \a time seconds
virtual void fadeScreenIn(const float time, bool clearQueue=true, float delay=0.f) = 0;
@ -421,6 +419,7 @@ namespace MWBase
virtual void activateHitOverlay(bool interrupt=true) = 0;
virtual void setWerewolfOverlay(bool set) = 0;
virtual void toggleConsole() = 0;
virtual void toggleDebugWindow() = 0;
/// Cycle to next or previous spell
@ -436,6 +435,7 @@ namespace MWBase
virtual std::string correctTexturePath(const std::string& path) = 0;
virtual bool textureExists(const std::string& path) = 0;
virtual void addCell(MWWorld::CellStore* cell) = 0;
virtual void removeCell(MWWorld::CellStore* cell) = 0;
virtual void writeFog(MWWorld::CellStore* cell) = 0;

@ -187,7 +187,7 @@ namespace MWBase
///< Return a pointer to a liveCellRef with the given name.
/// \param activeOnly do non search inactive cells.
virtual MWWorld::Ptr searchPtr (const std::string& name, bool activeOnly) = 0;
virtual MWWorld::Ptr searchPtr (const std::string& name, bool activeOnly, bool searchInContainers = true) = 0;
///< Return a pointer to a liveCellRef with the given name.
/// \param activeOnly do non search inactive cells.
@ -750,6 +750,7 @@ namespace MWBase
/// Return the distance between actor's weapon and target's collision box.
virtual float getHitDistance(const MWWorld::ConstPtr& actor, const MWWorld::ConstPtr& target) = 0;
virtual void addContainerScripts(const MWWorld::Ptr& reference, MWWorld::CellStore* cell) = 0;
virtual void removeContainerScripts(const MWWorld::Ptr& reference) = 0;
virtual bool isPlayerInJail() const = 0;

@ -27,6 +27,7 @@
#include "../mwworld/customdata.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/actionharvest.hpp"
#include "../mwworld/actionopen.hpp"
#include "../mwworld/actiontrap.hpp"
#include "../mwphysics/physicssystem.hpp"
@ -34,6 +35,7 @@
#include "../mwgui/tooltips.hpp"
#include "../mwrender/animation.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
@ -52,6 +54,10 @@ namespace MWClass
{
return *this;
}
virtual const ContainerCustomData& asContainerCustomData() const
{
return *this;
}
};
MWWorld::CustomData *ContainerCustomData::clone() const
@ -75,15 +81,30 @@ namespace MWClass
// store
ptr.getRefData().setCustomData (data.release());
MWBase::Environment::get().getWorld()->addContainerScripts(ptr, ptr.getCell());
}
}
bool canBeHarvested(const MWWorld::ConstPtr& ptr)
{
const MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if (animation == nullptr)
return false;
return animation->canBeHarvested();
}
void Container::respawn(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
if (ref->mBase->mFlags & ESM::Container::Respawn)
{
// Container was not touched, there is no need to modify its content.
if (ptr.getRefData().getCustomData() == nullptr)
return;
MWBase::Environment::get().getWorld()->removeContainerScripts(ptr);
ptr.getRefData().setCustomData(nullptr);
}
@ -239,6 +260,12 @@ namespace MWClass
{
if(!isTrapped)
{
if (canBeHarvested(ptr))
{
std::shared_ptr<MWWorld::Action> action (new MWWorld::ActionHarvest(ptr));
return action;
}
std::shared_ptr<MWWorld::Action> action (new MWWorld::ActionOpen(ptr));
return action;
}
@ -289,9 +316,18 @@ namespace MWClass
bool Container::hasToolTip (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
if (getName(ptr).empty())
return false;
if (const MWWorld::CustomData* data = ptr.getRefData().getCustomData())
return !canBeHarvested(ptr) || data->asContainerCustomData().mContainerStore.hasVisibleItems();
return (ref->mBase->mName != "");
return true;
}
bool Container::canBeActivated(const MWWorld::Ptr& ptr) const
{
return hasToolTip(ptr);
}
MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const

@ -73,6 +73,8 @@ namespace MWClass
const;
///< Write additional state from \a ptr into \a state.
virtual bool canBeActivated(const MWWorld::Ptr& ptr) const;
static void registerSelf();
virtual void respawn (const MWWorld::Ptr& ptr) const;

@ -519,10 +519,10 @@ namespace MWClass
*/
}
damage = std::max(1.f, damage);
if(ishealth)
{
damage *= damage / (damage + getArmorRating(ptr));
damage = std::max(1.f, damage);
if (!attacker.isEmpty())
{
damage = scaleDamage(damage, attacker, ptr);
@ -747,7 +747,7 @@ namespace MWClass
float Creature::getArmorRating (const MWWorld::Ptr& ptr) const
{
// Note this is currently unused. Creatures do not use armor mitigation.
// Equipment armor rating is deliberately ignored.
return getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).getMagnitude();
}

@ -409,7 +409,7 @@ namespace MWClass
store.get<ESM::Region>().find(cell->mRegion);
//name as is, not a token
return region->mName;
return MyGUI::TextIterator::toTagsString(region->mName);
}
}

@ -189,6 +189,7 @@ namespace MWClass
info.effects = list;
info.text = text;
info.isIngredient = true;
return info;
}

@ -1601,6 +1601,19 @@ namespace MWClass
int Npc::getPrimaryFactionRank (const MWWorld::ConstPtr& ptr) const
{
std::string factionID = ptr.getClass().getPrimaryFaction(ptr);
if(factionID.empty())
return -1;
// Search in the NPC data first
if (const MWWorld::CustomData* data = ptr.getRefData().getCustomData())
{
int rank = data->asNpcCustomData().mNpcStats.getFactionRank(factionID);
if (rank >= 0)
return rank;
}
// Use base NPC record as a fallback
const MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
return ref->mBase->getFactionRank();
}

@ -4,6 +4,8 @@
#include <MyGUI_Button.h>
#include <MyGUI_EditBox.h>
#include <MyGUI_ControllerManager.h>
#include <MyGUI_ControllerRepeatClick.h>
#include <MyGUI_InputManager.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -26,9 +28,6 @@
namespace MWGui
{
const float AlchemyWindow::sCountChangeInitialPause = 0.5f;
const float AlchemyWindow::sCountChangeInterval = 0.1f;
AlchemyWindow::AlchemyWindow()
: WindowBase("openmw_alchemy_window.layout")
, mSortModel(nullptr)
@ -170,7 +169,7 @@ namespace MWGui
update();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mNameEdit);
}
void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender)
@ -249,6 +248,7 @@ namespace MWGui
params.mAttribute = effectKey.mArg;
params.mIsConstant = true;
params.mNoTarget = true;
params.mNoMagnitude = true;
params.mKnown = mAlchemy->knownEffect(effectIndex, MWBase::Environment::get().getWorld()->getPlayerPtr());
@ -281,10 +281,9 @@ namespace MWGui
void AlchemyWindow::addRepeatController(MyGUI::Widget *widget)
{
MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(Controllers::ControllerRepeatEvent::getClassTypeName());
Controllers::ControllerRepeatEvent* controller = item->castType<Controllers::ControllerRepeatEvent>();
controller->eventRepeatClick += MyGUI::newDelegate(this, &AlchemyWindow::onRepeatClick);
controller->setRepeat(sCountChangeInitialPause, sCountChangeInterval);
MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(MyGUI::ControllerRepeatClick::getClassTypeName());
MyGUI::ControllerRepeatClick* controller = static_cast<MyGUI::ControllerRepeatClick*>(item);
controller->eventRepeatClick += newDelegate(this, &AlchemyWindow::onRepeatClick);
MyGUI::ControllerManager::getInstance().addItem(widget, controller);
}

@ -4,9 +4,10 @@
#include <memory>
#include <vector>
#include <MyGUI_ControllerItem.h>
#include <components/widgets/numericeditbox.hpp>
#include "controllers.hpp"
#include "windowbase.hpp"
namespace MWMechanics

@ -4,6 +4,7 @@
#include <MyGUI_ImageBox.h>
#include <MyGUI_Gui.h>
#include <MyGUI_ScrollView.h>
#include <MyGUI_InputManager.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -71,7 +72,7 @@ namespace MWGui
WindowModal::onOpen();
updateBirths();
updateSpells();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mBirthList);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mBirthList);
// Show the current birthsign by default
const std::string &signId =

@ -101,7 +101,7 @@ namespace MWGui
setTakeButtonShow(showTakeButton);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton);
}
void BookWindow::setTakeButtonShow(bool show)
@ -161,9 +161,9 @@ namespace MWGui
mPrevPageButton->setVisible(prevPageVisible);
if (focus == mNextPageButton && !nextPageVisible && prevPageVisible)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mPrevPageButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mPrevPageButton);
else if (focus == mPrevPageButton && !prevPageVisible && nextPageVisible)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNextPageButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mNextPageButton);
if (mPages.empty())
return;

@ -3,6 +3,7 @@
#include <MyGUI_ImageBox.h>
#include <MyGUI_ListBox.h>
#include <MyGUI_Gui.h>
#include <MyGUI_InputManager.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -135,7 +136,7 @@ namespace MWGui
WindowModal::onOpen ();
updateClasses();
updateStats();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mClassList);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mClassList);
// Show the current class by default
MWWorld::Ptr player = MWMechanics::getPlayer();
@ -436,7 +437,7 @@ namespace MWGui
getWidget(mEditName, "EditName");
// Make sure the edit box has focus
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mEditName);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName);
MyGUI::Button* descriptionButton;
getWidget(descriptionButton, "DescriptionButton");
@ -902,7 +903,7 @@ namespace MWGui
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", ""));
// Make sure the edit box has focus
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
DescriptionDialog::~DescriptionDialog()

@ -2,6 +2,7 @@
#include <MyGUI_Button.h>
#include <MyGUI_EditBox.h>
#include <MyGUI_InputManager.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
@ -33,7 +34,7 @@ namespace MWGui
mMessage->setSize(mMessage->getWidth(), mMessage->getTextSize().height + 24);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mOkButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mOkButton);
center();
}

@ -1,6 +1,8 @@
#include "console.hpp"
#include <MyGUI_EditBox.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_LayerManager.h>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@ -150,8 +152,9 @@ namespace MWGui
void Console::onOpen()
{
// Give keyboard focus to the combo box whenever the console is
// turned on
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCommandLine);
// turned on and place it over other widgets
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCommandLine);
MyGUI::LayerManager::getInstance().upLayerItem(mMainWidget);
}
void Console::print(const std::string &msg, const std::string& color)
@ -471,7 +474,7 @@ namespace MWGui
mPtr = object;
}
// User clicked on an object. Restore focus to the console command line.
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCommandLine);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCommandLine);
}
else
{

@ -254,7 +254,7 @@ namespace MWGui
mItemView->setModel (mSortModel);
mItemView->resetScrollBars();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton);
setTitle(container.getClass().getName(container));
}
@ -284,7 +284,8 @@ namespace MWGui
if (mModel)
mModel->onClose();
MWBase::Environment::get().getMechanicsManager()->onClose(mPtr);
if (!mPtr.isEmpty())
MWBase::Environment::get().getMechanicsManager()->onClose(mPtr);
}
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
@ -297,7 +298,7 @@ namespace MWGui
if(mDragAndDrop != nullptr && mDragAndDrop->mIsOnDragAndDrop)
return;
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton);
/*
Start of tes3mp addition
@ -377,7 +378,7 @@ namespace MWGui
{
if(mDragAndDrop == nullptr || !mDragAndDrop->mIsOnDragAndDrop)
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton);
onTakeAllButtonClicked(mTakeButton);

@ -7,54 +7,6 @@ namespace MWGui
{
namespace Controllers
{
ControllerRepeatEvent::ControllerRepeatEvent() :
mInit(0.5f),
mStep(0.1f),
mEnabled(true),
mTimeLeft(0)
{
}
ControllerRepeatEvent::~ControllerRepeatEvent()
{
}
bool ControllerRepeatEvent::addTime(MyGUI::Widget* _widget, float _time)
{
if(mTimeLeft == 0)
mTimeLeft = mInit;
mTimeLeft -= _time;
while (mTimeLeft <= 0)
{
mTimeLeft += mStep;
eventRepeatClick(_widget, this);
}
return true;
}
void ControllerRepeatEvent::setRepeat(float init, float step)
{
mInit = init;
mStep = step;
}
void ControllerRepeatEvent::setEnabled(bool enable)
{
mEnabled = enable;
}
void ControllerRepeatEvent::setProperty(const std::string& _key, const std::string& _value)
{
}
void ControllerRepeatEvent::prepareItem(MyGUI::Widget* _widget)
{
}
// -------------------------------------------------------------
void ControllerFollowMouse::prepareItem(MyGUI::Widget *_widget)
{
}

@ -13,39 +13,6 @@ namespace MWGui
{
namespace Controllers
{
// Should be removed when upgrading to MyGUI 3.2.2 (current git), it has ControllerRepeatClick
class ControllerRepeatEvent :
public MyGUI::ControllerItem
{
MYGUI_RTTI_DERIVED( ControllerRepeatEvent )
public:
ControllerRepeatEvent();
virtual ~ControllerRepeatEvent();
void setRepeat(float init, float step);
void setEnabled(bool enable);
virtual void setProperty(const std::string& _key, const std::string& _value);
// Events
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, MyGUI::ControllerItem*> EventHandle_RepeatClickVoid;
/** Event : Repeat Click.\n
signature : void method(MyGUI::Widget* _sender, MyGUI::ControllerItem *_controller)\n
*/
EventHandle_RepeatClickVoid eventRepeatClick;
private:
bool addTime(MyGUI::Widget* _widget, float _time);
void prepareItem(MyGUI::Widget* _widget);
private:
float mInit;
float mStep;
bool mEnabled;
float mTimeLeft;
};
/// Automatically positions a widget below the mouse cursor.
class ControllerFollowMouse :
public MyGUI::ControllerItem

@ -3,6 +3,7 @@
#include <MyGUI_Button.h>
#include <MyGUI_ScrollBar.h>
#include <MyGUI_RenderManager.h>
#include <MyGUI_InputManager.h>
#include <components/widgets/numericeditbox.hpp>
@ -47,7 +48,7 @@ namespace MWGui
mMainWidget->getHeight());
// by default, the text edit field has the focus of the keyboard
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit);
mSlider->setScrollPosition(maxCount-1);

@ -5,6 +5,7 @@
#include <MyGUI_ProgressBar.h>
#include <MyGUI_ScrollBar.h>
#include <MyGUI_Button.h>
#include <MyGUI_InputManager.h>
#include <components/debug/debuglog.hpp>
#include <components/widgets/list.hpp>
@ -380,7 +381,7 @@ namespace MWGui
{
onTopicActivated(topic);
if (mGoodbyeButton->getEnabled())
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mGoodbyeButton);
}
else if (topic == sPersuasion)
mPersuasionDialog.setVisible(true);
@ -443,7 +444,7 @@ namespace MWGui
return;
}
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mGoodbyeButton);
setTitle(mPtr.getClass().getName(mPtr));
@ -622,7 +623,7 @@ namespace MWGui
bool goodbyeWasEnabled = mGoodbyeButton->getEnabled();
mGoodbyeButton->setEnabled(goodbyeEnabled);
if (goodbyeEnabled && !goodbyeWasEnabled)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mGoodbyeButton);
bool topicsEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye;
mTopicsList->setEnabled(topicsEnabled);

@ -5,6 +5,7 @@
#include <MyGUI_Button.h>
#include <MyGUI_ScrollView.h>
#include <MyGUI_EditBox.h>
#include <MyGUI_InputManager.h>
#include <components/widgets/list.hpp>
#include <components/settings/settings.hpp>
@ -67,7 +68,7 @@ namespace MWGui
void EnchantingDialog::onOpen()
{
center();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mName);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mName);
}
void EnchantingDialog::setSoulGem(const MWWorld::Ptr &gem)
@ -107,20 +108,11 @@ namespace MWGui
void EnchantingDialog::updateLabels()
{
std::stringstream enchantCost;
enchantCost << std::setprecision(1) << std::fixed << mEnchanting.getEnchantPoints();
mEnchantmentPoints->setCaption(enchantCost.str() + " / " + MyGUI::utility::toString(mEnchanting.getMaxEnchantValue()));
mCharge->setCaption(MyGUI::utility::toString(mEnchanting.getGemCharge()));
int successChance = int(mEnchanting.getEnchantChance());
mSuccessChance->setCaption(MyGUI::utility::toString(std::max(0, successChance)));
std::stringstream castCost;
castCost << mEnchanting.getEffectiveCastCost();
mCastCost->setCaption(castCost.str());
mPrice->setCaption(MyGUI::utility::toString(mEnchanting.getEnchantPrice()));
mEnchantmentPoints->setCaption(std::to_string(static_cast<int>(mEnchanting.getEnchantPoints(false))) + " / " + std::to_string(mEnchanting.getMaxEnchantValue()));
mCharge->setCaption(std::to_string(mEnchanting.getGemCharge()));
mSuccessChance->setCaption(std::to_string(std::max(0, std::min(100, mEnchanting.getEnchantChance()))));
mCastCost->setCaption(std::to_string(mEnchanting.getEffectiveCastCost()));
mPrice->setCaption(std::to_string(mEnchanting.getEnchantPrice()));
switch(mEnchanting.getCastStyle())
{
@ -322,7 +314,7 @@ namespace MWGui
return;
}
if (mEnchanting.getEnchantPoints() > mEnchanting.getMaxEnchantValue())
if (static_cast<int>(mEnchanting.getEnchantPoints(false)) > mEnchanting.getMaxEnchantValue())
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage29}");
return;
@ -348,7 +340,7 @@ namespace MWGui
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(), mPtr))
{
std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->mValue.getString();
Misc::StringUtils::replace(msg, "%s", item.getClass().getName(item).c_str(), 2);
msg = Misc::StringUtils::format(msg, item.getClass().getName(item));
MWBase::Environment::get().getWindowManager()->messageBox(msg);
MWBase::Environment::get().getMechanicsManager()->confiscateStolenItemToOwner(player, item, mPtr, 1);
@ -366,13 +358,19 @@ namespace MWGui
{
MWBase::Environment::get().getWindowManager()->playSound("enchant success");
MWBase::Environment::get().getWindowManager()->messageBox ("#{sEnchantmentMenu12}");
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
}
else
{
MWBase::Environment::get().getWindowManager()->playSound("enchant fail");
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage34}");
if (!mEnchanting.getGem().isEmpty() && !mEnchanting.getGem().getRefData().getCount())
{
setSoulGem(MWWorld::Ptr());
mEnchanting.nextCastStyle();
updateLabels();
updateEffectsView();
}
}
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
}
}

@ -2,12 +2,12 @@
namespace MWGui
{
MyGUI::VectorWidgetPtr ExposedWindow::getSkinWidgetsByName (const std::string &name)
MyGUI::VectorWidgetPtr Window::getSkinWidgetsByName (const std::string &name)
{
return MyGUI::Widget::getSkinWidgetsByName (name);
}
MyGUI::Widget* ExposedWindow::getSkinWidget(const std::string & _name, bool _throw)
MyGUI::Widget* Window::getSkinWidget(const std::string & _name, bool _throw)
{
MyGUI::VectorWidgetPtr widgets = getSkinWidgetsByName (_name);

@ -9,9 +9,9 @@ namespace MWGui
/**
* @brief subclass to provide access to some Widget internals.
*/
class ExposedWindow : public MyGUI::Window
class Window : public MyGUI::Window
{
MYGUI_RTTI_DERIVED(ExposedWindow)
MYGUI_RTTI_DERIVED(Window)
public:
MyGUI::VectorWidgetPtr getSkinWidgetsByName (const std::string &name);

@ -274,6 +274,7 @@ namespace MWGui
if (!MWBase::Environment::get().getWindowManager ()->isGuiMode ())
return;
MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager();
if (mDragAndDrop->mIsOnDragAndDrop)
{
// drop item into the gameworld
@ -288,19 +289,19 @@ namespace MWGui
WorldItemModel drop (mouseX, mouseY);
mDragAndDrop->drop(&drop, nullptr);
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
winMgr->changePointer("arrow");
}
else
{
GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode();
GuiMode mode = winMgr->getMode();
if ( (mode != GM_Console) && (mode != GM_Container) && (mode != GM_Inventory) )
if (!winMgr->isConsoleMode() && (mode != GM_Container) && (mode != GM_Inventory))
return;
MWWorld::Ptr object = MWBase::Environment::get().getWorld()->getFacedObject();
if (mode == GM_Console)
MWBase::Environment::get().getWindowManager()->setConsoleSelectedObject(object);
if (winMgr->isConsoleMode())
winMgr->setConsoleSelectedObject(object);
else //if ((mode == GM_Container) || (mode == GM_Inventory))
{
// pick up object
@ -314,7 +315,7 @@ namespace MWGui
an item here, and expect the server's reply to our packet to cause the actual
picking up of items
*/
//MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object);
//winMgr->getInventoryWindow()->pickUpObject(object);
{
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset();

@ -176,28 +176,39 @@ namespace MWGui
mItemView->setModel(nullptr);
}
void InventoryWindow::toggleMaximized()
{
std::string setting = getModeSetting();
bool maximized = !Settings::Manager::getBool(setting + " maximized", "Windows");
if (maximized)
setting += " maximized";
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
float x = Settings::Manager::getFloat(setting + " x", "Windows") * float(viewSize.width);
float y = Settings::Manager::getFloat(setting + " y", "Windows") * float(viewSize.height);
float w = Settings::Manager::getFloat(setting + " w", "Windows") * float(viewSize.width);
float h = Settings::Manager::getFloat(setting + " h", "Windows") * float(viewSize.height);
MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>();
window->setCoord(x, y, w, h);
if (maximized)
Settings::Manager::setBool(setting, "Windows", maximized);
else
Settings::Manager::setBool(setting + " maximized", "Windows", maximized);
adjustPanes();
updatePreviewSize();
}
void InventoryWindow::setGuiMode(GuiMode mode)
{
std::string setting = "inventory";
mGuiMode = mode;
switch(mode) {
case GM_Container:
setPinButtonVisible(false);
setting += " container";
break;
case GM_Companion:
setPinButtonVisible(false);
setting += " companion";
break;
case GM_Barter:
setPinButtonVisible(false);
setting += " barter";
break;
case GM_Inventory:
default:
setPinButtonVisible(true);
break;
}
std::string setting = getModeSetting();
setPinButtonVisible(mode == GM_Inventory);
if (Settings::Manager::getBool(setting + " maximized", "Windows"))
setting += " maximized";
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntPoint pos(static_cast<int>(Settings::Manager::getFloat(setting + " x", "Windows") * viewSize.width),
@ -400,11 +411,11 @@ namespace MWGui
adjustPanes();
}
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
std::string InventoryWindow::getModeSetting() const
{
adjustPanes();
std::string setting = "inventory";
switch(mGuiMode) {
switch(mGuiMode)
{
case GM_Container:
setting += " container";
break;
@ -418,6 +429,14 @@ namespace MWGui
break;
}
return setting;
}
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
{
adjustPanes();
std::string setting = getModeSetting();
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
float x = _sender->getPosition().left / float(viewSize.width);
float y = _sender->getPosition().top / float(viewSize.height);
@ -427,6 +446,9 @@ namespace MWGui
Settings::Manager::setFloat(setting + " y", "Windows", y);
Settings::Manager::setFloat(setting + " w", "Windows", w);
Settings::Manager::setFloat(setting + " h", "Windows", h);
bool maximized = Settings::Manager::getBool(setting + " maximized", "Windows");
if (maximized)
Settings::Manager::setBool(setting + " maximized", "Windows", false);
if (mMainWidget->getSize().width != mLastXSize || mMainWidget->getSize().height != mLastYSize)
{
@ -490,7 +512,9 @@ namespace MWGui
void InventoryWindow::onTitleDoubleClicked()
{
if (!mPinned)
if (MyGUI::InputManager::getInstance().isShiftPressed())
toggleMaximized();
else if (!mPinned)
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Inventory);
}

@ -65,6 +65,9 @@ namespace MWGui
/// Cycle to previous/next weapon
void cycle(bool next);
protected:
virtual void onTitleDoubleClicked();
private:
DragAndDrop* mDragAndDrop;
@ -104,11 +107,15 @@ namespace MWGui
float mScaleFactor;
float mUpdateTimer;
void toggleMaximized();
void onItemSelected(int index);
void onItemSelectedFromSourceModel(int index);
void onBackgroundSelected();
std::string getModeSetting() const;
void sellItem(MyGUI::Widget* sender, int count);
void dragItem(MyGUI::Widget* sender, int count);
@ -116,7 +123,6 @@ namespace MWGui
void onFilterChanged(MyGUI::Widget* _sender);
void onAvatarClicked(MyGUI::Widget* _sender);
void onPinToggled();
void onTitleDoubleClicked();
void updateEncumbranceBar();
void notifyContentChanged();

@ -177,7 +177,7 @@ namespace MWGui
End of tes3mp addition
*/
Misc::StringUtils::replace(message, "%d", std::to_string(mDays).c_str(), 2);
message = Misc::StringUtils::format(message, mDays);
for (const int& skill : skills)
{
@ -197,8 +197,7 @@ namespace MWGui
*/
skillMsg = gmst.find("sNotifyMessage39")->mValue.getString();
Misc::StringUtils::replace(skillMsg, "%s", skillName.c_str(), 2);
Misc::StringUtils::replace(skillMsg, "%d", std::to_string(skillValue).c_str(), 2);
skillMsg = Misc::StringUtils::format(skillMsg, skillName, skillValue);
message += "\n" + skillMsg;
}

@ -254,7 +254,7 @@ namespace
}
updateShowingPages();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(getWidget<MyGUI::Widget>(CloseBTN));
MyGUI::InputManager::getInstance().setKeyFocusWidget(getWidget<MyGUI::Widget>(CloseBTN));
}
void onClose()
@ -377,9 +377,9 @@ namespace
prevPageBtn->setVisible(prevPageVisible);
if (focus == nextPageBtn && !nextPageVisible && prevPageVisible)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(prevPageBtn);
MyGUI::InputManager::getInstance().setKeyFocusWidget(prevPageBtn);
else if (focus == prevPageBtn && !prevPageVisible && nextPageVisible)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nextPageBtn);
MyGUI::InputManager::getInstance().setKeyFocusWidget(nextPageBtn);
setVisible (PageOneNum, relPages > 0);
setVisible (PageTwoNum, relPages > 1);

@ -83,7 +83,7 @@ void KeyboardNavigation::restoreFocus(int mode)
{
MyGUI::Widget* w = found->second;
if (w && w->getVisible() && w->getEnabled())
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(found->second);
MyGUI::InputManager::getInstance().setKeyFocusWidget(found->second);
}
}
@ -130,7 +130,7 @@ void KeyboardNavigation::onFrame()
// workaround incorrect key focus resets (fix in MyGUI TBD)
if (!shouldAcceptKeyFocus(focus) && shouldAcceptKeyFocus(mCurrentFocus) && (!mModalWindow || isRootParent(mCurrentFocus, mModalWindow)))
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCurrentFocus);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCurrentFocus);
focus = mCurrentFocus;
}
@ -154,12 +154,12 @@ void KeyboardNavigation::setDefaultFocus(MyGUI::Widget *window, MyGUI::Widget *d
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
if (!focus || !shouldAcceptKeyFocus(focus))
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus);
MyGUI::InputManager::getInstance().setKeyFocusWidget(defaultFocus);
}
else
{
if (!isRootParent(focus, window))
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus);
MyGUI::InputManager::getInstance().setKeyFocusWidget(defaultFocus);
}
}
@ -276,7 +276,7 @@ bool KeyboardNavigation::switchFocus(int direction, bool wrap)
else if (direction == D_Up && (vertdiff >= 0 || !isVertical))
return false;
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[index]);
MyGUI::InputManager::getInstance().setKeyFocusWidget(keyFocusList[index]);
return true;
}
@ -291,7 +291,7 @@ bool KeyboardNavigation::selectFirstWidget()
if (!keyFocusList.empty())
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[0]);
MyGUI::InputManager::getInstance().setKeyFocusWidget(keyFocusList[0]);
return true;
}
return false;

@ -165,11 +165,6 @@ namespace MWGui
if (mMainWidget->getVisible())
return;
if (mViewer->getIncrementalCompileOperation())
{
mViewer->getIncrementalCompileOperation()->setMaximumNumOfObjectsToCompilePerFrame(100);
}
// Assign dummy bounding sphere callback to avoid the bounding sphere of the entire scene being recomputed after each frame of loading
// We are already using node masks to avoid the scene from being updated/rendered, but node masks don't work for computeBound()
mViewer->getSceneData()->setComputeBoundingSphereCallback(new DontComputeBoundCallback);

@ -3,6 +3,7 @@
#include <MyGUI_TextBox.h>
#include <MyGUI_Gui.h>
#include <MyGUI_RenderManager.h>
#include <MyGUI_InputManager.h>
#include <components/widgets/imagebutton.hpp>
#include <components/settings/settings.hpp>
@ -67,12 +68,12 @@ namespace MWGui
if (isMainMenu)
{
if (mButtons["loadgame"]->getVisible())
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["loadgame"]);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mButtons["loadgame"]);
else
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["newgame"]);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mButtons["newgame"]);
}
else
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["return"]);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mButtons["return"]);
}
Layout::setVisible (visible);

@ -268,9 +268,6 @@ namespace MWGui
{
for (int my=0; my<mNumCells; ++my)
{
int x = mCurX + (mx - mCellDistance);
int y = mCurY + (-1*(my - mCellDistance));
MapEntry& entry = mMaps[my + mNumCells*mx];
MyGUI::ImageBox* fog = entry.mFogWidget;
@ -280,19 +277,6 @@ namespace MWGui
entry.mFogTexture.reset();
continue;
}
osg::ref_ptr<osg::Texture2D> tex = mLocalMapRender->getFogOfWarTexture(x, y);
if (tex)
{
entry.mFogTexture.reset(new osgMyGUI::OSGTexture(tex));
fog->setRenderItemTexture(entry.mFogTexture.get());
fog->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f));
}
else
{
fog->setImageTexture("black");
entry.mFogTexture.reset();
}
}
}
@ -425,31 +409,18 @@ namespace MWGui
mInterior = interior;
mChanged = false;
applyFogOfWar();
// Update the map textures
for (int mx=0; mx<mNumCells; ++mx)
{
for (int my=0; my<mNumCells; ++my)
{
int mapX = x + (mx - mCellDistance);
int mapY = y + (-1*(my - mCellDistance));
MapEntry& entry = mMaps[my + mNumCells*mx];
MyGUI::ImageBox* box = entry.mMapWidget;
entry.mMapWidget->setRenderItemTexture(nullptr);
entry.mFogWidget->setRenderItemTexture(nullptr);
entry.mMapTexture.reset();
entry.mFogTexture.reset();
osg::ref_ptr<osg::Texture2D> texture = mLocalMapRender->getMapTexture(mapX, mapY);
if (texture)
{
entry.mMapTexture.reset(new osgMyGUI::OSGTexture(texture));
box->setRenderItemTexture(entry.mMapTexture.get());
box->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f));
}
else
{
box->setRenderItemTexture(nullptr);
entry.mMapTexture.reset();
}
entry.mCellX = x + (mx - mCellDistance);
entry.mCellY = y - (my - mCellDistance);
}
}
@ -463,22 +434,7 @@ namespace MWGui
void LocalMapBase::requestMapRender(const MWWorld::CellStore *cell)
{
std::set<const MWWorld::CellStore*> cells;
if (!cell->isExterior())
cells.insert(cell);
else
{
for (int dX=-mCellDistance; dX<=mCellDistance; ++dX)
{
for (int dY=-mCellDistance; dY<=mCellDistance; ++dY)
{
const MWWorld::CellStore* gridCell = MWBase::Environment::get().getWorld()->getExterior (cell->getCell()->getGridX()+dX, cell->getCell()->getGridY()+dY);
cells.insert(gridCell);
}
}
}
mLocalMapRender->requestMap(cells);
mLocalMapRender->requestMap(cell);
}
void LocalMapBase::redraw()
@ -581,6 +537,68 @@ namespace MWGui
mMarkerUpdateTimer = 0;
updateMagicMarkers();
}
updateRequiredMaps();
}
bool widgetCropped(MyGUI::Widget* widget, MyGUI::Widget* cropTo)
{
MyGUI::IntRect coord = widget->getAbsoluteRect();
MyGUI::IntRect croppedCoord = cropTo->getAbsoluteRect();
if (coord.left < croppedCoord.left && coord.right < croppedCoord.left)
return true;
if (coord.left > croppedCoord.right && coord.right > croppedCoord.right)
return true;
if (coord.top < croppedCoord.top && coord.bottom < croppedCoord.top)
return true;
if (coord.top > croppedCoord.bottom && coord.bottom > croppedCoord.bottom)
return true;
return false;
}
void LocalMapBase::updateRequiredMaps()
{
bool needRedraw = false;
for (MapEntry& entry : mMaps)
{
if (widgetCropped(entry.mMapWidget, mLocalMap))
continue;
if (!entry.mMapTexture)
{
if (!mInterior)
requestMapRender(MWBase::Environment::get().getWorld()->getExterior (entry.mCellX, entry.mCellY));
osg::ref_ptr<osg::Texture2D> texture = mLocalMapRender->getMapTexture(entry.mCellX, entry.mCellY);
if (texture)
{
entry.mMapTexture.reset(new osgMyGUI::OSGTexture(texture));
entry.mMapWidget->setRenderItemTexture(entry.mMapTexture.get());
entry.mMapWidget->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f));
needRedraw = true;
}
else
entry.mMapTexture.reset(new osgMyGUI::OSGTexture("", nullptr));
}
if (!entry.mFogTexture && mFogOfWarToggled && mFogOfWarEnabled)
{
osg::ref_ptr<osg::Texture2D> tex = mLocalMapRender->getFogOfWarTexture(entry.mCellX, entry.mCellY);
if (tex)
{
entry.mFogTexture.reset(new osgMyGUI::OSGTexture(tex));
entry.mFogWidget->setRenderItemTexture(entry.mFogTexture.get());
entry.mFogWidget->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f));
}
else
{
entry.mFogWidget->setImageTexture("black");
entry.mFogTexture.reset(new osgMyGUI::OSGTexture("", nullptr));
}
needRedraw = true;
}
}
if (needRedraw)
redraw();
}
void LocalMapBase::updateDoorMarkers()
@ -1004,7 +1022,9 @@ namespace MWGui
void MapWindow::onTitleDoubleClicked()
{
if (!mPinned)
if (MyGUI::InputManager::getInstance().isShiftPressed())
MWBase::Environment::get().getWindowManager()->toggleMaximized(this);
else if (!mPinned)
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Map);
}
@ -1176,7 +1196,7 @@ namespace MWGui
{
WindowModal::onOpen();
center();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
void EditNoteDialog::onCancelButtonClicked(MyGUI::Widget *sender)

@ -151,12 +151,14 @@ namespace MWGui
struct MapEntry
{
MapEntry(MyGUI::ImageBox* mapWidget, MyGUI::ImageBox* fogWidget)
: mMapWidget(mapWidget), mFogWidget(fogWidget) {}
: mMapWidget(mapWidget), mFogWidget(fogWidget), mCellX(0), mCellY(0) {}
MyGUI::ImageBox* mMapWidget;
MyGUI::ImageBox* mFogWidget;
std::shared_ptr<MyGUI::ITexture> mMapTexture;
std::shared_ptr<MyGUI::ITexture> mFogTexture;
int mCellX;
int mCellY;
};
std::vector<MapEntry> mMaps;
@ -197,6 +199,8 @@ namespace MWGui
virtual void customMarkerCreated(MyGUI::Widget* marker) {}
virtual void doorMarkerCreated(MyGUI::Widget* marker) {}
void updateRequiredMaps();
void updateMagicMarkers();
void addDetectionMarkers(int type);

@ -12,7 +12,6 @@ namespace MWGui
GM_Companion,
GM_MainMenu, // Main menu mode
GM_Console, // Console mode
GM_Journal, // Journal mode
GM_Scroll, // Read scroll

@ -3,6 +3,7 @@
#include <MyGUI_ListBox.h>
#include <MyGUI_ImageBox.h>
#include <MyGUI_Gui.h>
#include <MyGUI_InputManager.h>
#include <osg/Texture2D>
@ -176,7 +177,7 @@ namespace MWGui
mHeadRotate->setScrollPosition(initialPos);
onHeadRotate(mHeadRotate, initialPos);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mRaceList);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mRaceList);
}
void RaceDialog::setRaceId(const std::string &raceId)

@ -207,7 +207,7 @@ void Recharge::onItemClicked(MyGUI::Widget *sender, const MWWorld::Ptr& item)
if (gem.getRefData().getCount() == 0)
{
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage51")->mValue.getString();
Misc::StringUtils::replace(message, "%s", gem.getClass().getName(gem).c_str(), 2);
message = Misc::StringUtils::format(message, gem.getClass().getName(gem));
MWBase::Environment::get().getWindowManager()->messageBox(message);

@ -94,7 +94,7 @@ namespace MWGui
MWBase::Environment::get().getStateManager()->deleteGame (mCurrentCharacter, mCurrentSlot);
mSaveList->removeItemAt(mSaveList->getIndexSelected());
onSlotSelected(mSaveList, mSaveList->getIndexSelected());
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList);
if (mSaveList->getItemCount() == 0)
{
@ -114,7 +114,7 @@ namespace MWGui
void SaveGameDialog::onDeleteSlotCancel()
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList);
}
void SaveGameDialog::onSaveNameChanged(MyGUI::EditBox *sender)
@ -138,9 +138,9 @@ namespace MWGui
mSaveNameEdit->setCaption ("");
if (mSaving)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveNameEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveNameEdit);
else
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList);
center();
@ -244,14 +244,11 @@ namespace MWGui
void SaveGameDialog::onConfirmationCancel()
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList);
}
void SaveGameDialog::accept(bool reallySure)
{
// Remove for MyGUI 3.2.2
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nullptr);
if (mSaving)
{
// If overwriting an existing slot, ask for confirmation first
@ -334,7 +331,7 @@ namespace MWGui
void SaveGameDialog::onCharacterAccept(MyGUI::ComboBox* sender, size_t pos)
{
// Give key focus to save list so we can confirm the selection with Enter
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList);
}
void SaveGameDialog::fillSaveList()

@ -1,6 +1,7 @@
#include "scrollwindow.hpp"
#include <MyGUI_ScrollView.h>
#include <MyGUI_InputManager.h>
#include <components/esm/loadbook.hpp>
#include <components/widgets/imagebutton.hpp>
@ -66,7 +67,7 @@ namespace MWGui
setTakeButtonShow(showTakeButton);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton);
}
void ScrollWindow::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character)

@ -6,14 +6,18 @@
#include <MyGUI_ScrollView.h>
#include <MyGUI_Gui.h>
#include <MyGUI_TabControl.h>
#include <MyGUI_InputManager.h>
#include <boost/algorithm/string.hpp>
#include <SDL_video.h>
#include <iomanip>
#include <components/debug/debuglog.hpp>
#include <components/misc/stringops.hpp>
#include <components/misc/gcd.hpp>
#include <components/misc/constants.hpp>
#include <components/widgets/sharedstatebutton.hpp>
#include <components/settings/settings.hpp>
@ -142,13 +146,22 @@ namespace MWGui
MyGUI::ScrollBar* scroll = current->castType<MyGUI::ScrollBar>();
std::string valueStr;
std::string valueType = getSettingValueType(current);
if (valueType == "Float" || valueType == "Integer")
if (valueType == "Float" || valueType == "Integer" || valueType == "Cell")
{
// TODO: ScrollBar isn't meant for this. should probably use a dedicated FloatSlider widget
float min,max;
getSettingMinMax(scroll, min, max);
float value = Settings::Manager::getFloat(getSettingName(current), getSettingCategory(current));
valueStr = MyGUI::utility::toString((int)value);
if (valueType == "Cell")
{
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << value/Constants::CellSizeInUnits;
valueStr = ss.str();
}
else
valueStr = MyGUI::utility::toString(int(value));
value = std::max(min, std::min(value, max));
value = (value-min)/(max-min);
@ -161,7 +174,8 @@ namespace MWGui
scroll->setScrollPosition(value);
}
scroll->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
updateSliderLabel(scroll, valueStr);
if (scroll->getVisible())
updateSliderLabel(scroll, valueStr);
}
configureWidgets(current);
@ -176,7 +190,7 @@ namespace MWGui
MyGUI::TextBox* textBox;
getWidget(textBox, labelWidgetName);
std::string labelCaption = scroller->getUserString("SettingLabelCaption");
Misc::StringUtils::replaceAll(labelCaption, "%s", value.c_str(), 2);
labelCaption = Misc::StringUtils::format(labelCaption, value);
textBox->setCaptionWithReplacing(labelCaption);
}
}
@ -185,6 +199,12 @@ namespace MWGui
WindowBase("openmw_settings_window.layout"),
mKeyboardMode(true)
{
bool terrain = Settings::Manager::getBool("distant terrain", "Terrain");
const std::string widgetName = terrain ? "RenderingDistanceSlider" : "LargeRenderingDistanceSlider";
MyGUI::Widget* unusedSlider;
getWidget(unusedSlider, widgetName);
unusedSlider->setVisible(false);
configureWidgets(mMainWidget);
setTitle("#{sOptions}");
@ -440,7 +460,7 @@ namespace MWGui
{
std::string valueStr;
std::string valueType = getSettingValueType(scroller);
if (valueType == "Float" || valueType == "Integer")
if (valueType == "Float" || valueType == "Integer" || valueType == "Cell")
{
float value = pos / float(scroller->getScrollRange()-1);
@ -451,7 +471,15 @@ namespace MWGui
Settings::Manager::setFloat(getSettingName(scroller), getSettingCategory(scroller), value);
else
Settings::Manager::setInt(getSettingName(scroller), getSettingCategory(scroller), (int)value);
valueStr = MyGUI::utility::toString(int(value));
if (valueType == "Cell")
{
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << value/Constants::CellSizeInUnits;
valueStr = ss.str();
}
else
valueStr = MyGUI::utility::toString(int(value));
}
else
{
@ -466,12 +494,13 @@ namespace MWGui
void SettingsWindow::apply()
{
const Settings::CategorySettingVector changed = Settings::Manager::apply();
const Settings::CategorySettingVector changed = Settings::Manager::getPendingChanges();
MWBase::Environment::get().getWorld()->processChangedSettings(changed);
MWBase::Environment::get().getSoundManager()->processChangedSettings(changed);
MWBase::Environment::get().getWindowManager()->processChangedSettings(changed);
MWBase::Environment::get().getInputManager()->processChangedSettings(changed);
MWBase::Environment::get().getMechanicsManager()->processChangedSettings(changed);
Settings::Manager::resetPendingChanges();
}
void SettingsWindow::onKeyboardSwitchClicked(MyGUI::Widget* _sender)
@ -599,9 +628,10 @@ namespace MWGui
void SettingsWindow::onOpen()
{
highlightCurrentResolution();
updateControlsBox();
resetScrollbars();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mOkButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mOkButton);
}
void SettingsWindow::onWindowResize(MyGUI::Window *_sender)

@ -2,6 +2,7 @@
#include <MyGUI_ImageBox.h>
#include <MyGUI_Gui.h>
#include <MyGUI_InputManager.h>
#include <components/esm/records.hpp>
#include <components/widgets/list.hpp>
@ -457,7 +458,7 @@ namespace MWGui
void SpellCreationDialog::onOpen()
{
center();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mNameEdit);
}
void SpellCreationDialog::onReferenceUnavailable ()

@ -148,6 +148,19 @@ namespace MWGui
return mSpells.size();
}
SpellModel::ModelIndex SpellModel::getSelectedIndex() const
{
ModelIndex selected = -1;
for (SpellModel::ModelIndex i = 0; i<int(getItemCount()); ++i)
{
if (getItem(i).mSelected) {
selected = i;
break;
}
}
return selected;
}
Spell SpellModel::getItem(ModelIndex index) const
{
if (index < 0 || index >= int(mSpells.size()))

@ -48,6 +48,8 @@ namespace MWGui
///< throws for invalid index
size_t getItemCount() const;
ModelIndex getSelectedIndex() const;
///< returns -1 if nothing is selected
private:
MWWorld::Ptr mActor;

@ -1,7 +1,9 @@
#include "spellwindow.hpp"
#include <MyGUI_Button.h>
#include <MyGUI_EditBox.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_Window.h>
#include <components/misc/stringops.hpp>
#include <components/settings/settings.hpp>
@ -47,6 +49,9 @@ namespace MWGui
{
mSpellIcons = new SpellIcons();
MyGUI::Widget* deleteButton;
getWidget(deleteButton, "DeleteSpellButton");
getWidget(mSpellView, "SpellView");
getWidget(mEffectBox, "EffectsBox");
getWidget(mFilterEdit, "FilterEdit");
@ -55,8 +60,13 @@ namespace MWGui
mSpellView->eventSpellClicked += MyGUI::newDelegate(this, &SpellWindow::onModelIndexSelected);
mFilterEdit->eventEditTextChange += MyGUI::newDelegate(this, &SpellWindow::onFilterChanged);
deleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onDeleteClicked);
setCoord(498, 300, 302, 300);
// Adjust the spell filtering widget size because of MyGUI limitations.
int filterWidth = mSpellView->getSize().width - deleteButton->getSize().width - 3;
mFilterEdit->setSize(filterWidth, mFilterEdit->getSize().height);
}
SpellWindow::~SpellWindow()
@ -73,7 +83,9 @@ namespace MWGui
void SpellWindow::onTitleDoubleClicked()
{
if (!mPinned)
if (MyGUI::InputManager::getInstance().isShiftPressed())
MWBase::Environment::get().getWindowManager()->toggleMaximized(this);
else if (!mPinned)
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Magic);
}
@ -82,7 +94,7 @@ namespace MWGui
// Reset the filter focus when opening the window
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
if (focus == mFilterEdit)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nullptr);
MyGUI::InputManager::getInstance().resetKeyFocusWidget();
updateSpells();
}
@ -151,13 +163,17 @@ namespace MWGui
MWWorld::Ptr player = MWMechanics::getPlayer();
std::string raceId = player.get<ESM::NPC>()->mBase->mRace;
const std::string& signId =
MWBase::Environment::get().getWorld()->getPlayer().getBirthSign();
const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(raceId);
const ESM::BirthSign* birthsign = MWBase::Environment::get().getWorld()->getStore().get<ESM::BirthSign>().find(signId);
// can't delete racial spells, birthsign spells or powers
bool isInherent = race->mPowers.exists(spell->mId) || spell->mData.mType == ESM::Spell::ST_Power;
const std::string& signId = MWBase::Environment::get().getWorld()->getPlayer().getBirthSign();
if (!isInherent && !signId.empty())
{
const ESM::BirthSign* sign = MWBase::Environment::get().getWorld()->getStore().get<ESM::BirthSign>().find(signId);
isInherent = sign->mPowers.exists(spell->mId);
}
// can't delete racial spells, birthsign spells or powers
if (race->mPowers.exists(spell->mId) || birthsign->mPowers.exists(spell->mId) || spell->mData.mType == ESM::Spell::ST_Power)
if (isInherent)
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sDeleteSpellError}");
}
@ -167,7 +183,7 @@ namespace MWGui
mSpellToDelete = spellId;
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
std::string question = MWBase::Environment::get().getWindowManager()->getGameSettingString("sQuestionDeleteSpell", "Delete %s?");
Misc::StringUtils::replace(question, "%s", spell->mName.c_str(), 2);
question = Misc::StringUtils::format(question, spell->mName);
dialog->askForConfirmation(question);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &SpellWindow::onDeleteSpellAccept);
@ -196,6 +212,17 @@ namespace MWGui
mSpellView->setModel(new SpellModel(MWMechanics::getPlayer(), sender->getCaption()));
}
void SpellWindow::onDeleteClicked(MyGUI::Widget *widget)
{
SpellModel::ModelIndex selected = mSpellView->getModel()->getSelectedIndex();
if (selected < 0)
return;
const Spell& spell = mSpellView->getModel()->getItem(selected);
if (spell.mType != Spell::Type_EnchantedItem)
askDeleteSpell(spell.mId);
}
void SpellWindow::onSpellSelected(const std::string& spellId)
{
MWWorld::Ptr player = MWMechanics::getPlayer();
@ -253,12 +280,9 @@ namespace MWGui
mSpellView->setModel(new SpellModel(MWMechanics::getPlayer(), ""));
SpellModel::ModelIndex selected = 0;
for (SpellModel::ModelIndex i = 0; i<int(mSpellView->getModel()->getItemCount()); ++i)
{
if (mSpellView->getModel()->getItem(i).mSelected)
selected = i;
}
SpellModel::ModelIndex selected = mSpellView->getModel()->getSelectedIndex();
if (selected < 0)
selected = 0;
selected += next ? 1 : -1;
int itemcount = mSpellView->getModel()->getItemCount();

@ -33,6 +33,7 @@ namespace MWGui
void onSpellSelected(const std::string& spellId);
void onModelIndexSelected(SpellModel::ModelIndex index);
void onFilterChanged(MyGUI::EditBox *sender);
void onDeleteClicked(MyGUI::Widget *widget);
void onDeleteSpellAccept();
void askDeleteSpell(const std::string& spellId);

@ -4,6 +4,7 @@
#include <MyGUI_ScrollView.h>
#include <MyGUI_ProgressBar.h>
#include <MyGUI_ImageBox.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_Gui.h>
#include <components/settings/settings.hpp>
@ -652,7 +653,13 @@ namespace MWGui
void StatsWindow::onTitleDoubleClicked()
{
if (!mPinned)
if (MyGUI::InputManager::getInstance().isShiftPressed())
{
MWBase::Environment::get().getWindowManager()->toggleMaximized(this);
MyGUI::Window* t = mMainWidget->castType<MyGUI::Window>();
onWindowResize(t);
}
else if (!mPinned)
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Stats);
}
}

@ -5,6 +5,7 @@
#include <MyGUI_EditBox.h>
#include <MyGUI_Button.h>
#include <MyGUI_InputManager.h>
namespace MWGui
{
@ -23,7 +24,7 @@ namespace MWGui
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked);
// Make sure the edit box has focus
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
void TextInputDialog::setNextButtonShow(bool shown)
@ -46,7 +47,7 @@ namespace MWGui
{
WindowModal::onOpen();
// Make sure the edit box has focus
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
// widget controls
@ -56,7 +57,7 @@ namespace MWGui
if (mTextEdit->getCaption() == "")
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget (mTextEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
else
eventDone(this);

@ -94,17 +94,19 @@ namespace MWGui
return;
}
bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode();
MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager();
bool guiMode = winMgr->isGuiMode();
if (guiMode)
{
if (!MWBase::Environment::get().getWindowManager()->getCursorVisible())
if (!winMgr->getCursorVisible())
return;
const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition();
if (MWBase::Environment::get().getWindowManager()->getWorldMouseOver() && ((MWBase::Environment::get().getWindowManager()->getMode() == GM_Console)
|| (MWBase::Environment::get().getWindowManager()->getMode() == GM_Container)
|| (MWBase::Environment::get().getWindowManager()->getMode() == GM_Inventory)))
if (winMgr->getWorldMouseOver() &&
(winMgr->isConsoleMode() ||
(winMgr->getMode() == GM_Container) ||
(winMgr->getMode() == GM_Inventory)))
{
if (mFocusObject.isEmpty ())
return;
@ -112,7 +114,7 @@ namespace MWGui
const MWWorld::Class& objectclass = mFocusObject.getClass();
MyGUI::IntSize tooltipSize;
if ((!objectclass.hasToolTip(mFocusObject))&&(MWBase::Environment::get().getWindowManager()->getMode() == GM_Console))
if (!objectclass.hasToolTip(mFocusObject) && winMgr->isConsoleMode())
{
setCoord(0, 0, 300, 300);
mDynamicToolTipBox->setVisible(true);
@ -212,7 +214,7 @@ namespace MWGui
{
MyGUI::IntCoord avatarPos = focus->getAbsoluteCoord();
MyGUI::IntPoint relMousePos = MyGUI::InputManager::getInstance ().getMousePosition () - MyGUI::IntPoint(avatarPos.left, avatarPos.top);
MWWorld::Ptr item = MWBase::Environment::get().getWindowManager()->getInventoryWindow ()->getAvatarSelectedItem (relMousePos.left, relMousePos.top);
MWWorld::Ptr item = winMgr->getInventoryWindow ()->getAvatarSelectedItem (relMousePos.left, relMousePos.top);
mFocusObject = item;
if (!mFocusObject.isEmpty ())
@ -486,7 +488,9 @@ namespace MWGui
effectsWidget->setEffectList(info.effects);
std::vector<MyGUI::Widget*> effectItems;
effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, info.isPotion ? Widgets::MWEffectList::EF_NoTarget : 0);
int flag = info.isPotion ? Widgets::MWEffectList::EF_NoTarget : 0;
flag |= info.isIngredient ? Widgets::MWEffectList::EF_NoMagnitude : 0;
effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, flag);
totalSize.height += coord.top-6;
totalSize.width = std::max(totalSize.width, coord.width);
}

@ -22,6 +22,7 @@ namespace MWGui
: imageSize(32)
, remainingEnchantCharge(-1)
, isPotion(false)
, isIngredient(false)
, wordWrap(true)
{}
@ -41,6 +42,7 @@ namespace MWGui
std::vector<std::string> notes;
bool isPotion; // potions do not show target in the tooltip
bool isIngredient; // ingredients have no effect magnitude
bool wordWrap;
};

@ -3,6 +3,7 @@
#include <MyGUI_Button.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_ControllerManager.h>
#include <MyGUI_ControllerRepeatClick.h>
#include <components/widgets/numericeditbox.hpp>
@ -44,9 +45,6 @@ namespace
namespace MWGui
{
const float TradeWindow::sBalanceChangeInitialPause = 0.5f;
const float TradeWindow::sBalanceChangeInterval = 0.1f;
TradeWindow::TradeWindow()
: WindowBase("openmw_trade_window.layout")
, mSortModel(nullptr)
@ -138,7 +136,7 @@ namespace MWGui
onFilterChanged(mFilterAll);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTotalBalance);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTotalBalance);
}
void TradeWindow::onFrame(float dt)
@ -311,7 +309,7 @@ namespace MWGui
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(itemStack.mBase.getCellRef().getRefId(), mPtr))
{
std::string msg = gmst.find("sNotifyMessage49")->mValue.getString();
Misc::StringUtils::replace(msg, "%s", itemStack.mBase.getClass().getName(itemStack.mBase).c_str(), 2);
msg = Misc::StringUtils::format(msg, itemStack.mBase.getClass().getName(itemStack.mBase));
MWBase::Environment::get().getWindowManager()->messageBox(msg);
MWBase::Environment::get().getMechanicsManager()->confiscateStolenItemToOwner(player, itemStack.mBase, mPtr, itemStack.mCount);
@ -382,10 +380,9 @@ namespace MWGui
void TradeWindow::addRepeatController(MyGUI::Widget *widget)
{
MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(Controllers::ControllerRepeatEvent::getClassTypeName());
Controllers::ControllerRepeatEvent* controller = item->castType<Controllers::ControllerRepeatEvent>();
controller->eventRepeatClick += MyGUI::newDelegate(this, &TradeWindow::onRepeatClick);
controller->setRepeat(sBalanceChangeInitialPause, sBalanceChangeInterval);
MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(MyGUI::ControllerRepeatClick::getClassTypeName());
MyGUI::ControllerRepeatClick* controller = static_cast<MyGUI::ControllerRepeatClick*>(item);
controller->eventRepeatClick += newDelegate(this, &TradeWindow::onRepeatClick);
MyGUI::ControllerManager::getInstance().addItem(widget, controller);
}
@ -468,16 +465,26 @@ namespace MWGui
int merchantOffer = 0;
// The offered price must be capped at 75% of the base price to avoid exploits
// connected to buying and selling the same item.
// This value has been determined by researching the limitations of the vanilla formula
// and may not be sufficient if getBarterOffer behavior has been changed.
std::vector<ItemStack> playerBorrowed = playerTradeModel->getItemsBorrowedToUs();
for (const ItemStack& itemStack : playerBorrowed)
{
merchantOffer -= MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(itemStack.mBase, itemStack.mCount), true);
const int basePrice = getEffectiveValue(itemStack.mBase, itemStack.mCount);
const int cap = static_cast<int>(std::max(1.f, 0.75f * basePrice)); // Minimum buying price -- 75% of the base
const int buyingPrice = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, basePrice, true);
merchantOffer -= std::max(cap, buyingPrice);
}
std::vector<ItemStack> merchantBorrowed = mTradeModel->getItemsBorrowedToUs();
for (const ItemStack& itemStack : merchantBorrowed)
{
merchantOffer += MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(itemStack.mBase, itemStack.mCount), false);
const int basePrice = getEffectiveValue(itemStack.mBase, itemStack.mCount);
const int cap = static_cast<int>(std::max(1.f, 0.75f * basePrice)); // Maximum selling price -- 75% of the base
const int sellingPrice = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, basePrice, false);
merchantOffer += mPtr.getClass().isNpc() ? std::min(cap, sellingPrice) : sellingPrice;
}
int diff = merchantOffer - mCurrentMerchantOffer;

@ -91,22 +91,22 @@ namespace MWGui
mTimeAdvancer.eventInterrupted += MyGUI::newDelegate(this, &WaitDialog::onWaitingInterrupted);
mTimeAdvancer.eventFinished += MyGUI::newDelegate(this, &WaitDialog::onWaitingFinished);
}
void WaitDialog::onReferenceUnavailable ()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Rest);
resetReference();
}
void WaitDialog::setPtr(const MWWorld::Ptr &ptr)
{
mPtr = ptr;
setCanRest(!mPtr.isEmpty() || MWBase::Environment::get().getWorld ()->canRest () == MWBase::World::Rest_Allowed);
setCanRest(!ptr.isEmpty() || MWBase::Environment::get().getWorld ()->canRest () == MWBase::World::Rest_Allowed);
if (ptr.isEmpty() && MWBase::Environment::get().getWorld ()->canRest() == MWBase::World::Rest_PlayerIsInAir)
{
// Resting in air is not allowed unless you're using a bed
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage1}");
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Rest);
}
if (mUntilHealedButton->getVisible())
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mUntilHealedButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mUntilHealedButton);
else
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mWaitButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mWaitButton);
}
bool WaitDialog::exit()
@ -118,7 +118,6 @@ namespace MWGui
{
mSleeping = false;
mTimeAdvancer.stop();
resetReference();
}
void WaitDialog::onOpen()
@ -152,12 +151,6 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage1}");
MWBase::Environment::get().getWindowManager()->popGuiMode ();
}
else if (mPtr.isEmpty() && canRest == MWBase::World::Rest_PlayerIsInAir)
{
// Resting in air is not allowed either, unless you're using a bed
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage1}");
MWBase::Environment::get().getWindowManager()->popGuiMode ();
}
/*
Start of tes3mp addition
@ -268,7 +261,7 @@ namespace MWGui
{
mHourText->setCaptionWithReplacing (MyGUI::utility::toString(position+1) + " #{sRestMenu2}");
mManualHours = position+1;
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mWaitButton);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mWaitButton);
}
void WaitDialog::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character)
@ -351,8 +344,6 @@ namespace MWGui
void WaitDialog::onFrame(float dt)
{
checkReferenceAvailable();
mTimeAdvancer.onFrame(dt);
if (mFadeTimeRemaining <= 0)

@ -4,7 +4,6 @@
#include "timeadvancer.hpp"
#include "windowbase.hpp"
#include "referenceinterface.hpp"
namespace MWGui
{
@ -23,7 +22,7 @@ namespace MWGui
MyGUI::TextBox* mProgressText;
};
class WaitDialog : public WindowBase, public ReferenceInterface
class WaitDialog : public WindowBase
{
public:
WaitDialog();
@ -64,8 +63,6 @@ namespace MWGui
WaitDialogProgressBar mProgressBar;
virtual void onReferenceUnavailable();
void onUntilHealedButtonClicked(MyGUI::Widget* sender);
void onWaitButtonClicked(MyGUI::Widget* sender);
void onCancelButtonClicked(MyGUI::Widget* sender);

@ -235,6 +235,7 @@ namespace MWGui
params.mRange = effectInfo.mRange;
params.mIsConstant = (flags & MWEffectList::EF_Constant) != 0;
params.mNoTarget = (flags & MWEffectList::EF_NoTarget);
params.mNoMagnitude = (flags & MWEffectList::EF_NoMagnitude);
effect->setSpellEffect(params);
effects.push_back(effect);
coord.top += effect->getHeight();
@ -293,6 +294,7 @@ namespace MWGui
effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default);
effectInfo.mIsConstant = (flags & EF_Constant) || effectInfo.mIsConstant;
effectInfo.mNoTarget = (flags & EF_NoTarget) || effectInfo.mNoTarget;
effectInfo.mNoMagnitude = (flags & EF_NoMagnitude) || effectInfo.mNoMagnitude;
effect->setSpellEffect(effectInfo);
effects.push_back(effect);
if (effect->getRequestedWidth() > maxwidth)
@ -408,7 +410,7 @@ namespace MWGui
spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], "");
}
if (mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) {
if (mEffectParams.mMagnMin || mEffectParams.mMagnMax) {
ESM::MagicEffect::MagnitudeDisplayType displayType = magicEffect->getMagnitudeDisplayType();
if ( displayType == ESM::MagicEffect::MDT_TimesInt ) {
std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", "");
@ -421,7 +423,7 @@ namespace MWGui
spellLine += formatter.str();
}
else if ( displayType != ESM::MagicEffect::MDT_None ) {
else if ( displayType != ESM::MagicEffect::MDT_None && !mEffectParams.mNoMagnitude) {
spellLine += " " + MyGUI::utility::toString(mEffectParams.mMagnMin);
if (mEffectParams.mMagnMin != mEffectParams.mMagnMax)
spellLine += to + MyGUI::utility::toString(mEffectParams.mMagnMax);
@ -431,9 +433,9 @@ namespace MWGui
else if ( displayType == ESM::MagicEffect::MDT_Feet )
spellLine += " " + ft;
else if ( displayType == ESM::MagicEffect::MDT_Level )
spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? lvl : lvls );
spellLine += " " + ((mEffectParams.mMagnMin == mEffectParams.mMagnMax && std::abs(mEffectParams.mMagnMin) == 1) ? lvl : lvls );
else // ESM::MagicEffect::MDT_Points
spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts );
spellLine += " " + ((mEffectParams.mMagnMin == mEffectParams.mMagnMax && std::abs(mEffectParams.mMagnMin) == 1) ? pt : pts );
}
}
@ -528,99 +530,5 @@ namespace MWGui
assignWidget(mBarWidget, "Bar");
assignWidget(mBarTextWidget, "BarText");
}
MWScrollBar::MWScrollBar()
: mEnableRepeat(true)
, mRepeatTriggerTime(0.5f)
, mRepeatStepTime(0.1f)
, mIsIncreasing(true)
{
ScrollBar::setRepeatEnabled(false);
}
MWScrollBar::~MWScrollBar()
{
}
void MWScrollBar::initialiseOverride()
{
ScrollBar::initialiseOverride();
if(mWidgetStart)
{
mWidgetStart->eventMouseButtonPressed += MyGUI::newDelegate(this, &MWScrollBar::onDecreaseButtonPressed);
mWidgetStart->eventMouseButtonReleased += MyGUI::newDelegate(this, &MWScrollBar::onDecreaseButtonReleased);
}
if(mWidgetEnd)
{
mWidgetEnd->eventMouseButtonPressed += MyGUI::newDelegate(this, &MWScrollBar::onIncreaseButtonPressed);
mWidgetEnd->eventMouseButtonReleased += MyGUI::newDelegate(this, &MWScrollBar::onIncreaseButtonReleased);
}
}
void MWScrollBar::setRepeat(float trigger, float step)
{
mRepeatTriggerTime = trigger;
mRepeatStepTime = step;
}
void MWScrollBar::repeatClick(MyGUI::Widget* _widget, MyGUI::ControllerItem* _controller)
{
int stepSize = mScrollPage;
if(mIsIncreasing && mScrollPosition < mScrollRange-1)
{
if(mScrollPosition + stepSize > mScrollRange-1)
mScrollPosition = mScrollRange-1;
else
mScrollPosition += stepSize;
eventScrollChangePosition(this, mScrollPosition);
updateTrack();
}
else if(!mIsIncreasing && mScrollPosition > 0)
{
int newPos = mScrollPosition - stepSize;
if(newPos < 0)
mScrollPosition = 0;
else
mScrollPosition -= stepSize;
eventScrollChangePosition(this, mScrollPosition);
updateTrack();
}
}
void MWScrollBar::onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
mIsIncreasing = false;
MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(MWGui::Controllers::ControllerRepeatEvent::getClassTypeName());
MWGui::Controllers::ControllerRepeatEvent* controller = item->castType<MWGui::Controllers::ControllerRepeatEvent>();
controller->eventRepeatClick += newDelegate(this, &MWScrollBar::repeatClick);
controller->setEnabled(mEnableRepeat);
controller->setRepeat(mRepeatTriggerTime, mRepeatStepTime);
MyGUI::ControllerManager::getInstance().addItem(this, controller);
}
void MWScrollBar::onDecreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
MyGUI::ControllerManager::getInstance().removeItem(this);
}
void MWScrollBar::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
mIsIncreasing = true;
MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(MWGui::Controllers::ControllerRepeatEvent::getClassTypeName());
MWGui::Controllers::ControllerRepeatEvent* controller = item->castType<MWGui::Controllers::ControllerRepeatEvent>();
controller->eventRepeatClick += newDelegate(this, &MWScrollBar::repeatClick);
controller->setEnabled(mEnableRepeat);
controller->setRepeat(mRepeatTriggerTime, mRepeatStepTime);
MyGUI::ControllerManager::getInstance().addItem(this, controller);
}
void MWScrollBar::onIncreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{
MyGUI::ControllerManager::getInstance().removeItem(this);
}
}
}

@ -38,6 +38,7 @@ namespace MWGui
SpellEffectParams()
: mNoTarget(false)
, mIsConstant(false)
, mNoMagnitude(false)
, mKnown(true)
, mEffectID(-1)
, mSkill(-1)
@ -52,6 +53,7 @@ namespace MWGui
bool mNoTarget; // potion effects for example have no target (target is always the player)
bool mIsConstant; // constant effect means that duration will not be displayed
bool mNoMagnitude; // effect magnitude will not be displayed (e.g ingredients)
bool mKnown; // is this effect known to the player? (If not, will display as a question mark instead)
@ -218,7 +220,9 @@ namespace MWGui
enum EffectFlags
{
EF_NoTarget = 0x01, // potions have no target (target is always the player)
EF_Constant = 0x02 // constant effect means that duration will not be displayed
EF_Constant = 0x02, // constant effect means that duration will not be displayed
EF_NoMagnitude = 0x04 // ingredients have no magnitude
};
void setEffectList(const SpellEffectList& list);
@ -299,33 +303,6 @@ namespace MWGui
MyGUI::TextBox* mBarTextWidget;
};
typedef MWDynamicStat* MWDynamicStatPtr;
// Should be removed when upgrading to MyGUI 3.2.2 (current git), it has ScrollBar autorepeat support
class MWScrollBar : public MyGUI::ScrollBar
{
MYGUI_RTTI_DERIVED(MWScrollBar)
public:
MWScrollBar();
virtual ~MWScrollBar();
void setRepeat(float trigger, float step);
protected:
virtual void initialiseOverride();
void repeatClick(MyGUI::Widget* _widget, MyGUI::ControllerItem* _controller);
bool mEnableRepeat;
float mRepeatTriggerTime;
float mRepeatStepTime;
bool mIsIncreasing;
private:
void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onDecreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onIncreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
};
}
}

@ -1,5 +1,6 @@
#include "windowbase.hpp"
#include <MyGUI_Button.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_RenderManager.h>
@ -9,6 +10,7 @@
#include <components/widgets/imagebutton.hpp>
#include "draganddrop.hpp"
#include "exposedwindow.hpp"
using namespace MWGui;
@ -16,6 +18,32 @@ WindowBase::WindowBase(const std::string& parLayout)
: Layout(parLayout)
{
mMainWidget->setVisible(false);
Window* window = mMainWidget->castType<Window>(false);
if (!window)
return;
MyGUI::Button* button = nullptr;
MyGUI::VectorWidgetPtr widgets = window->getSkinWidgetsByName("Action");
for (MyGUI::Widget* widget : widgets)
{
if (widget->isUserString("SupportDoubleClick"))
button = widget->castType<MyGUI::Button>();
}
if (button)
button->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &WindowBase::onDoubleClick);
}
void WindowBase::onTitleDoubleClicked()
{
if (MyGUI::InputManager::getInstance().isShiftPressed())
MWBase::Environment::get().getWindowManager()->toggleMaximized(this);
}
void WindowBase::onDoubleClick(MyGUI::Widget *_sender)
{
onTitleDoubleClicked();
}
void WindowBase::setVisible(bool visible)
@ -27,18 +55,6 @@ void WindowBase::setVisible(bool visible)
onOpen();
else if (wasVisible)
onClose();
// This is needed as invisible widgets can retain key focus.
// Remove for MyGUI 3.2.2
if (!visible)
{
MyGUI::Widget* keyFocus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
while (keyFocus != mMainWidget && keyFocus != nullptr)
keyFocus = keyFocus->getParent();
if (keyFocus == mMainWidget)
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nullptr);
}
}
bool WindowBase::isVisible()

@ -20,7 +20,7 @@ namespace MWGui
class WindowBase: public Layout
{
public:
public:
WindowBase(const std::string& parLayout);
virtual MyGUI::Widget* getDefaultKeyFocus() { return nullptr; }
@ -52,8 +52,13 @@ namespace MWGui
/// Called when GUI viewport changes size
virtual void onResChange(int width, int height) {}
};
protected:
virtual void onTitleDoubleClicked();
private:
void onDoubleClick(MyGUI::Widget* _sender);
};
/*
* "Modal" windows cause the rest of the interface to be inaccessible while they are visible

@ -228,8 +228,7 @@ namespace MWGui
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWEffectList>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpellEffect>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWDynamicStat>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWScrollBar>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Window>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<VideoWidget>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<BackgroundImage>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<osgMyGUI::AdditiveLayer>("Layer");
@ -248,7 +247,6 @@ namespace MWGui
MyGUI::ResourceManager::getInstance().unregisterLoadXmlDelegate("Resource");
MyGUI::ResourceManager::getInstance().registerLoadXmlDelegate("Resource") = newDelegate(this, &WindowManager::loadFontDelegate);
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerRepeatEvent>("Controller");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerFollowMouse>("Controller");
MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
@ -459,7 +457,6 @@ namespace MWGui
mConsole = new Console(w,h, mConsoleOnlyScripts);
mWindows.push_back(mConsole);
trackWindow(mConsole, "console");
mGuiModeStates[GM_Console] = GuiModeState(mConsole);
bool questList = mResourceSystem->getVFS()->exists("textures/tx_menubook_options_over.dds");
JournalWindow* journal = JournalWindow::create(JournalViewModel::create (), questList, mEncoding);
@ -721,7 +718,7 @@ namespace MWGui
setCursorVisible(!gameMode);
if (gameMode)
setKeyFocusWidget (nullptr);
MyGUI::InputManager::getInstance().resetKeyFocusWidget();
// Icons of forced hidden windows are displayed
setMinimapVisibility((mAllowed & GW_Map) && (!mMap->pinned() || (mForceHidden & GW_Map)));
@ -734,10 +731,10 @@ namespace MWGui
// If in game mode (or interactive messagebox), show the pinned windows
if (mGuiModes.empty())
{
mMap->setVisible(mMap->pinned() && !(mForceHidden & GW_Map) && (mAllowed & GW_Map));
mStatsWindow->setVisible(mStatsWindow->pinned() && !(mForceHidden & GW_Stats) && (mAllowed & GW_Stats));
mInventoryWindow->setVisible(mInventoryWindow->pinned() && !(mForceHidden & GW_Inventory) && (mAllowed & GW_Inventory));
mSpellWindow->setVisible(mSpellWindow->pinned() && !(mForceHidden & GW_Magic) && (mAllowed & GW_Magic));
mMap->setVisible(mMap->pinned() && !isConsoleMode() && !(mForceHidden & GW_Map) && (mAllowed & GW_Map));
mStatsWindow->setVisible(mStatsWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Stats) && (mAllowed & GW_Stats));
mInventoryWindow->setVisible(mInventoryWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Inventory) && (mAllowed & GW_Inventory));
mSpellWindow->setVisible(mSpellWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Magic) && (mAllowed & GW_Magic));
return;
}
else if (getMode() != GM_Inventory)
@ -1019,6 +1016,12 @@ namespace MWGui
void WindowManager::onFrame (float frameDuration)
{
bool gameRunning = MWBase::Environment::get().getStateManager()->getState()!=
MWBase::StateManager::State_NoGame;
if (gameRunning)
updateMap();
if (!mGuiModes.empty())
{
GuiModeState& state = mGuiModeStates[mGuiModes.back()];
@ -1062,14 +1065,11 @@ namespace MWGui
if (mLocalMapRender)
mLocalMapRender->cleanupCameras();
if (MWBase::Environment::get().getStateManager()->getState()==
MWBase::StateManager::State_NoGame)
if (!gameRunning)
return;
mDragAndDrop->onFrame();
updateMap();
mHud->onFrame(frameDuration);
mDebugWindow->onFrame(frameDuration);
@ -1254,6 +1254,7 @@ namespace MWGui
else if (tag.compare(0, tokenLength, tokenToFind) == 0)
{
_result = mTranslationDataStorage.translateCellName(tag.substr(tokenLength));
_result = MyGUI::TextIterator::toTagsString(_result);
}
else if (Gui::replaceTag(tag, _result))
{
@ -1306,10 +1307,14 @@ namespace MWGui
for (std::map<MyGUI::Window*, std::string>::iterator it = mTrackedWindows.begin(); it != mTrackedWindows.end(); ++it)
{
MyGUI::IntPoint pos(static_cast<int>(Settings::Manager::getFloat(it->second + " x", "Windows") * x),
static_cast<int>( Settings::Manager::getFloat(it->second+ " y", "Windows") * y));
MyGUI::IntSize size(static_cast<int>(Settings::Manager::getFloat(it->second + " w", "Windows") * x),
static_cast<int>(Settings::Manager::getFloat(it->second + " h", "Windows") * y));
std::string settingName = it->second;
if (Settings::Manager::getBool(settingName + " maximized", "Windows"))
settingName += " maximized";
MyGUI::IntPoint pos(static_cast<int>(Settings::Manager::getFloat(settingName + " x", "Windows") * x),
static_cast<int>(Settings::Manager::getFloat(settingName + " y", "Windows") * y));
MyGUI::IntSize size(static_cast<int>(Settings::Manager::getFloat(settingName + " w", "Windows") * x),
static_cast<int>(Settings::Manager::getFloat(settingName + " h", "Windows") * y));
it->first->setPosition(pos);
it->first->setSize(size);
}
@ -1386,6 +1391,10 @@ namespace MWGui
}
updateVisible();
// To make sure that console window get focus again
if (mConsole && mConsole->isVisible())
mConsole->onOpen();
}
void WindowManager::removeGuiMode(GuiMode mode, bool noSound)
@ -1619,14 +1628,15 @@ namespace MWGui
bool WindowManager::isGuiMode() const
{
return !mGuiModes.empty() || (mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox());
return
!mGuiModes.empty() ||
isConsoleMode() ||
(mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox());
}
bool WindowManager::isConsoleMode() const
{
if (!mGuiModes.empty() && mGuiModes.back()==GM_Console)
return true;
return false;
return mConsole && mConsole->isVisible();
}
MWGui::GuiMode WindowManager::getMode() const
@ -1794,16 +1804,6 @@ namespace MWGui
}
}
// Remove this method for MyGUI 3.2.2
void WindowManager::setKeyFocusWidget(MyGUI::Widget *widget)
{
if (widget == nullptr)
MyGUI::InputManager::getInstance().resetKeyFocusWidget();
else
MyGUI::InputManager::getInstance().setKeyFocusWidget(widget);
onKeyFocusChanged(widget);
}
void WindowManager::onKeyFocusChanged(MyGUI::Widget *widget)
{
if (widget && widget->castType<MyGUI::EditBox>(false))
@ -1838,11 +1838,16 @@ namespace MWGui
void WindowManager::trackWindow(Layout *layout, const std::string &name)
{
std::string settingName = name;
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntPoint pos(static_cast<int>(Settings::Manager::getFloat(name + " x", "Windows") * viewSize.width),
static_cast<int>(Settings::Manager::getFloat(name + " y", "Windows") * viewSize.height));
MyGUI::IntSize size (static_cast<int>(Settings::Manager::getFloat(name + " w", "Windows") * viewSize.width),
static_cast<int>(Settings::Manager::getFloat(name + " h", "Windows") * viewSize.height));
bool isMaximized = Settings::Manager::getBool(name + " maximized", "Windows");
if (isMaximized)
settingName += " maximized";
MyGUI::IntPoint pos(static_cast<int>(Settings::Manager::getFloat(settingName + " x", "Windows") * viewSize.width),
static_cast<int>(Settings::Manager::getFloat(settingName + " y", "Windows") * viewSize.height));
MyGUI::IntSize size (static_cast<int>(Settings::Manager::getFloat(settingName + " w", "Windows") * viewSize.width),
static_cast<int>(Settings::Manager::getFloat(settingName + " h", "Windows") * viewSize.height));
layout->mMainWidget->setPosition(pos);
layout->mMainWidget->setSize(size);
@ -1851,6 +1856,26 @@ namespace MWGui
mTrackedWindows[window] = name;
}
void WindowManager::toggleMaximized(Layout *layout)
{
MyGUI::Window* window = layout->mMainWidget->castType<MyGUI::Window>();
std::string setting = mTrackedWindows[window];
if (setting.empty())
return;
bool maximized = !Settings::Manager::getBool(setting + " maximized", "Windows");
if (maximized)
setting += " maximized";
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
float x = Settings::Manager::getFloat(setting + " x", "Windows") * float(viewSize.width);
float y = Settings::Manager::getFloat(setting + " y", "Windows") * float(viewSize.height);
float w = Settings::Manager::getFloat(setting + " w", "Windows") * float(viewSize.width);
float h = Settings::Manager::getFloat(setting + " h", "Windows") * float(viewSize.height);
window->setCoord(x, y, w, h);
Settings::Manager::setBool(mTrackedWindows[window] + " maximized", "Windows", maximized);
}
void WindowManager::onWindowChangeCoord(MyGUI::Window *_sender)
{
std::string setting = mTrackedWindows[_sender];
@ -1863,6 +1888,9 @@ namespace MWGui
Settings::Manager::setFloat(setting + " y", "Windows", y);
Settings::Manager::setFloat(setting + " w", "Windows", w);
Settings::Manager::setFloat(setting + " h", "Windows", h);
bool maximized = Settings::Manager::getBool(setting + " maximized", "Windows");
if (maximized)
Settings::Manager::setBool(setting + " maximized", "Windows", false);
}
void WindowManager::clear()
@ -1942,6 +1970,7 @@ namespace MWGui
bool WindowManager::isSavingAllowed() const
{
return !MyGUI::InputManager::getInstance().isModalAny()
&& !isConsoleMode()
// TODO: remove this, once we have properly serialized the state of open windows
&& (!isGuiMode() || (mGuiModes.size() == 1 && (getMode() == GM_MainMenu || getMode() == GM_Rest)));
}
@ -1968,7 +1997,7 @@ namespace MWGui
sizeVideo(screenSize.width, screenSize.height);
MyGUI::Widget* oldKeyFocus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
setKeyFocusWidget(mVideoWidget);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mVideoWidget);
mVideoBackground->setVisible(true);
@ -2006,7 +2035,7 @@ namespace MWGui
MWBase::Environment::get().getSoundManager()->resumeSounds();
setKeyFocusWidget(oldKeyFocus);
MyGUI::InputManager::getInstance().setKeyFocusWidget(oldKeyFocus);
setCursorVisible(cursorWasVisible);
@ -2189,6 +2218,21 @@ namespace MWGui
SDL_free(text);
}
void WindowManager::toggleConsole()
{
bool visible = mConsole->isVisible();
if (!visible && !mGuiModes.empty())
mKeyboardNavigation->saveFocus(mGuiModes.back());
mConsole->setVisible(!visible);
if (visible && !mGuiModes.empty())
mKeyboardNavigation->restoreFocus(mGuiModes.back());
updateVisible();
}
void WindowManager::toggleDebugWindow()
{
mDebugWindow->setVisible(!mDebugWindow->isVisible());
@ -2358,6 +2402,11 @@ namespace MWGui
tex->unlock();
}
void WindowManager::addCell(MWWorld::CellStore* cell)
{
mLocalMapRender->addCell(cell);
}
void WindowManager::removeCell(MWWorld::CellStore *cell)
{
mLocalMapRender->removeCell(cell);

@ -147,9 +147,6 @@ namespace MWGui
/// (and will continually update the window while doing so)
virtual void playVideo(const std::string& name, bool allowSkipping);
/// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this.
virtual void setKeyFocusWidget (MyGUI::Widget* widget);
virtual void setNewGame(bool newgame);
virtual void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg);
@ -436,6 +433,7 @@ namespace MWGui
virtual void removeCurrentModal(WindowModal* input);
virtual void pinWindow (MWGui::GuiWindow window);
virtual void toggleMaximized(Layout *layout);
/// Fade the screen in, over \a time seconds
virtual void fadeScreenIn(const float time, bool clearQueue, float delay);
@ -449,6 +447,7 @@ namespace MWGui
virtual void activateHitOverlay(bool interrupt);
virtual void setWerewolfOverlay(bool set);
virtual void toggleConsole();
virtual void toggleDebugWindow();
/// Cycle to next or previous spell
@ -464,6 +463,7 @@ namespace MWGui
virtual std::string correctTexturePath(const std::string& path);
virtual bool textureExists(const std::string& path);
void addCell(MWWorld::CellStore* cell);
void removeCell(MWWorld::CellStore* cell);
void writeFog(MWWorld::CellStore* cell);

@ -1,7 +1,5 @@
#include "windowpinnablebase.hpp"
#include <MyGUI_Button.h>
#include "exposedwindow.hpp"
namespace MWGui
@ -9,21 +7,10 @@ namespace MWGui
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout)
: WindowBase(parLayout), mPinned(false)
{
ExposedWindow* window = mMainWidget->castType<ExposedWindow>();
Window* window = mMainWidget->castType<Window>();
mPinButton = window->getSkinWidget ("Button");
mPinButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonPressed);
MyGUI::Button* button = nullptr;
MyGUI::VectorWidgetPtr widgets = window->getSkinWidgetsByName("Action");
for (MyGUI::Widget* widget : widgets)
{
if (widget->isUserString("HideWindowOnDoubleClick"))
button = widget->castType<MyGUI::Button>();
}
if (button)
button->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &WindowPinnableBase::onDoubleClick);
}
void WindowPinnableBase::onPinButtonPressed(MyGUI::Widget* _sender, int left, int top, MyGUI::MouseButton id)
@ -41,11 +28,6 @@ namespace MWGui
onPinToggled();
}
void WindowPinnableBase::onDoubleClick(MyGUI::Widget *_sender)
{
onTitleDoubleClicked();
}
void WindowPinnableBase::setPinned(bool pinned)
{
if (pinned != mPinned)

@ -17,11 +17,9 @@ namespace MWGui
private:
void onPinButtonPressed(MyGUI::Widget* _sender, int left, int top, MyGUI::MouseButton id);
void onDoubleClick(MyGUI::Widget* _sender);
protected:
virtual void onPinToggled() = 0;
virtual void onTitleDoubleClicked() = 0;
MyGUI::Widget* mPinButton;
bool mPinned;

@ -507,7 +507,7 @@ namespace MWInput
void InputManager::updateCursorMode()
{
bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)
&& MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Console;
&& !MWBase::Environment::get().getWindowManager()->isConsoleMode();
bool was_relative = mInputManager->getMouseRelative();
bool is_relative = !MWBase::Environment::get().getWindowManager()->isGuiMode();
@ -618,6 +618,7 @@ namespace MWInput
{
bool triedToMove = false;
bool isRunning = false;
bool alwaysRunAllowed = false;
// joystick movement
float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue();
@ -646,31 +647,23 @@ namespace MWInput
isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25;
if(triedToMove) resetIdleTime();
if (actionIsActive(A_MoveLeft) && !actionIsActive(A_MoveRight))
if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight))
{
alwaysRunAllowed = true;
triedToMove = true;
mPlayer->setLeftRight (-1);
}
else if (actionIsActive(A_MoveRight) && !actionIsActive(A_MoveLeft))
{
triedToMove = true;
mPlayer->setLeftRight (1);
mPlayer->setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1);
}
if (actionIsActive(A_MoveForward) && !actionIsActive(A_MoveBackward))
{
triedToMove = true;
mPlayer->setAutoMove (false);
mPlayer->setForwardBackward (1);
}
else if (actionIsActive(A_MoveBackward) && !actionIsActive(A_MoveForward))
if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward))
{
alwaysRunAllowed = true;
triedToMove = true;
mPlayer->setAutoMove (false);
mPlayer->setForwardBackward (-1);
mPlayer->setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1);
}
else if(mPlayer->getAutoMove())
{
alwaysRunAllowed = true;
triedToMove = true;
mPlayer->setForwardBackward (1);
}
@ -715,7 +708,7 @@ namespace MWInput
mOverencumberedMessageDelay = 0.f;
}
if (mAlwaysRunActive || isRunning)
if ((mAlwaysRunActive && alwaysRunAllowed) || isRunning)
mPlayer->setRunState(!actionIsActive(A_Run));
else
mPlayer->setRunState(actionIsActive(A_Run));
@ -838,9 +831,6 @@ namespace MWInput
Settings::Manager::getInt("resolution y", "Video"),
Settings::Manager::getBool("fullscreen", "Video"),
Settings::Manager::getBool("window border", "Video"));
// We should reload TrueType fonts to fit new resolution
MWBase::Environment::get().getWindowManager()->loadUserFonts();
}
}
@ -880,7 +870,7 @@ namespace MWInput
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE)
== arg.keysym.scancode
&& MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Console)
&& MWBase::Environment::get().getWindowManager()->isConsoleMode())
SDL_StopTextInput();
bool consumed = false;
@ -1142,10 +1132,17 @@ namespace MWInput
void InputManager::windowResized(int x, int y)
{
// Note: this is a side effect of resolution change or window resize.
// There is no need to track these changes.
Settings::Manager::setInt("resolution x", "Video", x);
Settings::Manager::setInt("resolution y", "Video", y);
Settings::Manager::resetPendingChange("resolution x", "Video");
Settings::Manager::resetPendingChange("resolution y", "Video");
MWBase::Environment::get().getWindowManager()->windowResized(x, y);
// We should reload TrueType fonts to fit new resolution
MWBase::Environment::get().getWindowManager()->loadUserFonts();
}
void InputManager::windowClosed()
@ -1161,6 +1158,9 @@ namespace MWInput
return;
}
if (MWBase::Environment::get().getWindowManager()->isConsoleMode())
return;
bool inGame = MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame;
MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode();
@ -1179,6 +1179,9 @@ namespace MWInput
return;
}
if (MWBase::Environment::get().getWindowManager()->isConsoleMode())
return;
MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode();
bool inGame = MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame;
@ -1327,7 +1330,7 @@ namespace MWInput
if (MyGUI::InputManager::getInstance ().isModalAny())
return;
/*
Start of tes3mp addition
@ -1339,6 +1342,9 @@ namespace MWInput
End of tes3mp addition
*/
if (MWBase::Environment::get().getWindowManager()->isConsoleMode())
return;
// Toggle between game mode and inventory mode
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Inventory);
@ -1368,17 +1374,7 @@ namespace MWInput
if (MyGUI::InputManager::getInstance ().isModalAny())
return;
// Switch to console mode no matter what mode we are currently
// in, except of course if we are already in console mode
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
{
if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Console)
MWBase::Environment::get().getWindowManager()->popGuiMode();
else
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Console);
}
else
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Console);
MWBase::Environment::get().getWindowManager()->toggleConsole();
}
void InputManager::toggleJournal()
@ -1461,6 +1457,7 @@ namespace MWInput
void InputManager::toggleSneaking()
{
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return;
if (!mControlSwitch["playercontrols"]) return;
mSneaking = !mSneaking;
mPlayer->setSneak(mSneaking);
}

@ -501,7 +501,7 @@ namespace MWMechanics
{
MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2);
// Also have actor1's allies start combat
for (const MWWorld::Ptr ally1 : allies1)
for (const MWWorld::Ptr& ally1 : allies1)
MWBase::Environment::get().getMechanicsManager()->startCombat(ally1, actor2);
return;
}
@ -2328,7 +2328,7 @@ namespace MWMechanics
std::vector<MWWorld::Ptr> neighbors;
osg::Vec3f position (actor.getRefData().getPosition().asVec3());
getObjectsInRange(position, mActorsProcessingRange, neighbors);
for(const MWWorld::Ptr neighbor : neighbors)
for(const MWWorld::Ptr& neighbor : neighbors)
{
if (neighbor == actor)
continue;

@ -3,6 +3,7 @@
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
namespace MWMechanics
@ -16,4 +17,10 @@ namespace MWMechanics
{
return MWBase::Environment::get().getWorld()->getPlayer().isInCombat();
}
bool canActorMoveByZAxis(const MWWorld::Ptr& actor)
{
MWBase::World* world = MWBase::Environment::get().getWorld();
return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor);
}
}

@ -10,6 +10,7 @@ namespace MWMechanics
{
MWWorld::Ptr getPlayer();
bool isPlayerInCombat();
bool canActorMoveByZAxis(const MWWorld::Ptr& actor);
}
#endif

@ -402,9 +402,3 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::
return result;
}
bool MWMechanics::AiPackage::canActorMoveByZAxis(const MWWorld::Ptr& actor) const
{
MWBase::World* world = MWBase::Environment::get().getWorld();
return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor) || !world->isActorCollisionEnabled(actor);
}

@ -130,8 +130,6 @@ namespace MWMechanics
DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const;
bool canActorMoveByZAxis(const MWWorld::Ptr& actor) const;
// TODO: all this does not belong here, move into temporary storage
PathFinder mPathFinder;
ObstacleCheck mObstacleCheck;

@ -215,11 +215,7 @@ namespace MWMechanics
getAllowedNodes(actor, currentCell->getCell(), storage);
}
bool actorCanMoveByZ = (actor.getClass().canSwim(actor) && MWBase::Environment::get().getWorld()->isSwimming(actor))
|| MWBase::Environment::get().getWorld()->isFlying(actor)
|| !MWBase::Environment::get().getWorld()->isActorCollisionEnabled(actor);
if(actorCanMoveByZ && mDistance > 0) {
if (canActorMoveByZAxis(actor) && mDistance > 0) {
// Typically want to idle for a short time before the next wander
if (Misc::Rng::rollDice(100) >= 92 && storage.mState != AiWanderStorage::Wander_Walking) {
wanderNearStart(actor, storage, mDistance);

@ -565,8 +565,9 @@ void CharacterController::refreshMovementAnims(const WeaponInfo* weap, Character
mCurrentMovement = movementAnimName;
if(!mCurrentMovement.empty())
{
bool isrunning = mPtr.getClass().getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run)
&& !MWBase::Environment::get().getWorld()->isFlying(mPtr);
bool isflying = MWBase::Environment::get().getWorld()->isFlying(mPtr);
bool isrunning = mPtr.getClass().getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !isflying;
bool issneaking = mPtr.getClass().getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !isflying;
// For non-flying creatures, MW uses the Walk animation to calculate the animation velocity
// even if we are running. This must be replicated, otherwise the observed speed would differ drastically.
@ -600,7 +601,7 @@ void CharacterController::refreshMovementAnims(const WeaponInfo* weap, Character
// The first person anims don't have any velocity to calculate a speed multiplier from.
// We use the third person velocities instead.
// FIXME: should be pulled from the actual animation, but it is not presently loaded.
mMovementAnimSpeed = (isrunning ? 222.857f : 154.064f);
mMovementAnimSpeed = (issneaking ? 33.5452f : (isrunning ? 222.857f : 154.064f));
mMovementAnimationControlled = false;
}
}
@ -1148,41 +1149,36 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr)
void CharacterController::updateIdleStormState(bool inwater)
{
bool inStormDirection = false;
if (MWBase::Environment::get().getWorld()->isInStorm())
if (!mAnimation->hasAnimation("idlestorm") || mUpperBodyState != UpperCharState_Nothing || inwater)
{
osg::Vec3f stormDirection = MWBase::Environment::get().getWorld()->getStormDirection();
osg::Vec3f characterDirection = mPtr.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0);
inStormDirection = std::acos(stormDirection * characterDirection / (stormDirection.length() * characterDirection.length()))
> osg::DegreesToRadians(120.f);
mAnimation->disable("idlestorm");
return;
}
if (inStormDirection && !inwater && mUpperBodyState == UpperCharState_Nothing && mAnimation->hasAnimation("idlestorm"))
{
float complete = 0;
mAnimation->getInfo("idlestorm", &complete);
if (complete == 0)
mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::BlendMask_RightArm, false,
1.0f, "start", "loop start", 0.0f, 0);
else if (complete == 1)
mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::BlendMask_RightArm, false,
1.0f, "loop start", "loop stop", 0.0f, ~0ul);
}
else
if (MWBase::Environment::get().getWorld()->isInStorm())
{
if (mUpperBodyState == UpperCharState_Nothing)
osg::Vec3f stormDirection = MWBase::Environment::get().getWorld()->getStormDirection();
osg::Vec3f characterDirection = mPtr.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0);
stormDirection.normalize();
characterDirection.normalize();
if (stormDirection * characterDirection < -0.5f)
{
if (mAnimation->isPlaying("idlestorm"))
if (!mAnimation->isPlaying("idlestorm"))
{
if (mAnimation->getCurrentTime("idlestorm") < mAnimation->getTextKeyTime("idlestorm: loop stop"))
{
mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::BlendMask_RightArm, true,
1.0f, "loop stop", "stop", 0.0f, 0);
}
mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::BlendMask_RightArm, true,
1.0f, "start", "stop", 0.0f, ~0ul);
}
else
{
mAnimation->setLoopingEnabled("idlestorm", true);
}
return;
}
else
mAnimation->disable("idlestorm");
}
if (mAnimation->isPlaying("idlestorm"))
{
mAnimation->setLoopingEnabled("idlestorm", false);
}
}
@ -2100,24 +2096,24 @@ void CharacterController::update(float duration, bool animationOnly)
osg::Vec3f rot = cls.getRotationVector(mPtr);
speed = cls.getSpeed(mPtr);
float analogueMult = 1.f;
if(isPlayer)
{
// Joystick anologue movement.
// Joystick analogue movement.
float xAxis = std::abs(cls.getMovementSettings(mPtr).mPosition[0]);
float yAxis = std::abs(cls.getMovementSettings(mPtr).mPosition[1]);
float analogueMovement = ((xAxis > yAxis) ? xAxis : yAxis);
analogueMult = ((xAxis > yAxis) ? xAxis : yAxis);
// If Strafing, our max speed is slower so multiply by X axis instead.
if(std::abs(vec.x()/2.0f) > std::abs(vec.y()))
analogueMovement = xAxis;
analogueMult = xAxis;
// Due to the half way split between walking/running, we multiply speed by 2 while walking, unless a keyboard was used.
if(!isrunning && !sneak && !flying && analogueMovement <= 0.5f)
speed *= 2;
speed *= (analogueMovement);
if(!isrunning && !sneak && !flying && analogueMult <= 0.5f)
analogueMult *= 2.f;
}
speed *= analogueMult;
vec.x() *= speed;
vec.y() *= speed;
@ -2184,6 +2180,7 @@ void CharacterController::update(float duration, bool animationOnly)
}
}
fatigueLoss *= duration;
fatigueLoss *= analogueMult;
DynamicStat<float> fatigue = cls.getCreatureStats(mPtr).getFatigue();
if (!godmode)

@ -590,6 +590,11 @@ namespace MWMechanics
{
osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3());
osg::Vec3f pos2 (actor2.getRefData().getPosition().asVec3());
if (canActorMoveByZAxis(actor2))
{
pos1.z() = 0.f;
pos2.z() = 0.f;
}
float d = (pos1 - pos2).length();

@ -61,7 +61,7 @@ namespace MWMechanics
std::string msg = "sMagicContractDisease";
msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(msg)->mValue.getString();
Misc::StringUtils::replace(msg, "%s", spell->mName.c_str(), 2);
msg = Misc::StringUtils::format(msg, spell->mName);
MWBase::Environment::get().getWindowManager()->messageBox(msg);
}
}

@ -193,46 +193,36 @@ namespace MWMechanics
*
* Formula on UESPWiki is not entirely correct.
*/
int Enchanting::getEnchantPoints() const
float Enchanting::getEnchantPoints(bool precise) const
{
if (mEffectList.mList.empty())
// No effects added, cost = 0
return 0;
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
std::vector<ESM::ENAMstruct> mEffects = mEffectList.mList;
const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
const float fEnchantmentConstantDurationMult = store.get<ESM::GameSetting>().find("fEnchantmentConstantDurationMult")->mValue.getFloat();
int enchantmentCost = 0;
float cost = 0;
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
float enchantmentCost = 0.f;
float cost = 0.f;
for (const ESM::ENAMstruct& effect : mEffectList.mList)
{
float baseCost = (store.get<ESM::MagicEffect>().find(it->mEffectID))->mData.mBaseCost;
int magMin = std::max(1, it->mMagnMin);
int magMax = std::max(1, it->mMagnMax);
int area = std::max(1, it->mArea);
float magnitudeCost = (magMin + magMax) * baseCost * 0.05f;
float baseCost = (store.get<ESM::MagicEffect>().find(effect.mEffectID))->mData.mBaseCost;
int magMin = std::max(1, effect.mMagnMin);
int magMax = std::max(1, effect.mMagnMax);
int area = std::max(1, effect.mArea);
float duration = static_cast<float>(effect.mDuration);
if (mCastStyle == ESM::Enchantment::ConstantEffect)
{
magnitudeCost *= store.get<ESM::GameSetting>().find("fEnchantmentConstantDurationMult")->mValue.getFloat();
}
else
{
magnitudeCost *= it->mDuration;
}
duration = fEnchantmentConstantDurationMult;
float areaCost = area * 0.05f * baseCost;
const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
cost += (magnitudeCost + areaCost) * fEffectCostMult;
cost += ((magMin + magMax) * duration + area) * baseCost * fEffectCostMult * 0.05f;
cost = std::max(1.f, cost);
if (it->mRange == ESM::RT_Target)
cost *= 1.5;
if (effect.mRange == ESM::RT_Target)
cost *= 1.5f;
enchantmentCost += static_cast<int>(cost);
enchantmentCost += precise ? cost : std::floor(cost);
}
return enchantmentCost;
@ -244,7 +234,7 @@ namespace MWMechanics
if (mCastStyle == ESM::Enchantment::ConstantEffect)
return 0;
return getEnchantPoints();
return static_cast<int>(getEnchantPoints(false));
}
int Enchanting::getEffectiveCastCost() const
@ -308,21 +298,21 @@ namespace MWMechanics
mEnchanter = enchanter;
}
float Enchanting::getEnchantChance() const
int Enchanting::getEnchantChance() const
{
const CreatureStats& stats = mEnchanter.getClass().getCreatureStats(mEnchanter);
float chance1 = (mEnchanter.getClass().getSkill(mEnchanter, ESM::Skill::Enchant) +
(0.25f * stats.getAttribute (ESM::Attribute::Intelligence).getModified())
+ (0.125f * stats.getAttribute (ESM::Attribute::Luck).getModified()));
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
const float a = static_cast<float>(mEnchanter.getClass().getSkill(mEnchanter, ESM::Skill::Enchant));
const float b = static_cast<float>(stats.getAttribute (ESM::Attribute::Intelligence).getModified());
const float c = static_cast<float>(stats.getAttribute (ESM::Attribute::Luck).getModified());
const float fEnchantmentChanceMult = gmst.find("fEnchantmentChanceMult")->mValue.getFloat();
const float fEnchantmentConstantChanceMult = gmst.find("fEnchantmentConstantChanceMult")->mValue.getFloat();
float chance2 = 7.5f / (gmst.find("fEnchantmentChanceMult")->mValue.getFloat() * ((mCastStyle == ESM::Enchantment::ConstantEffect) ?
gmst.find("fEnchantmentConstantChanceMult")->mValue.getFloat() : 1.0f ))
* getEnchantPoints();
float x = (a - getEnchantPoints()*fEnchantmentChanceMult + 0.2f * b + 0.1f * c) * stats.getFatigueTerm();
if (mCastStyle == ESM::Enchantment::ConstantEffect)
x *= fEnchantmentConstantChanceMult;
return (chance1-chance2);
return static_cast<int>(x);
}
void Enchanting::payForEnchantment() const

@ -37,13 +37,13 @@ namespace MWMechanics
bool create(); //Return true if created, false if failed.
void nextCastStyle(); //Set enchant type to next possible type (for mOldItemPtr object)
int getCastStyle() const;
int getEnchantPoints() const;
float getEnchantPoints(bool precise = true) const;
int getBaseCastCost() const; // To be saved in the enchantment's record
int getEffectiveCastCost() const; // Effective cost taking player Enchant skill into account, used for preview purposes in the UI
int getEnchantPrice() const;
int getMaxEnchantValue() const;
int getGemCharge() const;
float getEnchantChance() const;
int getEnchantChance() const;
bool soulEmpty() const; //Return true if empty
bool itemEmpty() const; //Return true if empty
void payForEnchantment() const;

@ -689,8 +689,8 @@ namespace MWMechanics
float f = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
float pcTerm = (clampedDisposition - 50 + a + b + c) * playerStats.getFatigueTerm();
float npcTerm = (d + e + f) * sellerStats.getFatigueTerm();
float buyTerm = 0.01f * std::max(75.f, (100 - 0.5f * (pcTerm - npcTerm)));
float sellTerm = 0.01f * std::min(75.f, (50 - 0.5f * (npcTerm - pcTerm)));
float buyTerm = 0.01f * (100 - 0.5f * (pcTerm - npcTerm));
float sellTerm = 0.01f * (50 - 0.5f * (npcTerm - pcTerm));
int offerPrice = int(basePrice * (buying ? buyTerm : sellTerm));
return std::max(1, offerPrice);
}
@ -1011,6 +1011,9 @@ namespace MWMechanics
return true;
}
if (!target.getClass().canBeActivated(target))
return true;
// TODO: implement a better check to check if target is owned bed
if (target.getClass().isActivator() && target.getClass().getScript(target).compare(0, 3, "Bed") != 0)
return true;
@ -1053,7 +1056,7 @@ namespace MWMechanics
}
if (!cellref.getOwner().empty())
victim = MWBase::Environment::get().getWorld()->searchPtr(cellref.getOwner(), true);
victim = MWBase::Environment::get().getWorld()->searchPtr(cellref.getOwner(), true, false);
return (!isOwned && !isFactionOwned);
}

@ -66,6 +66,16 @@ const std::map<std::string, int>& MWMechanics::NpcStats::getFactionRanks() const
return mFactionRank;
}
int MWMechanics::NpcStats::getFactionRank(const std::string &faction) const
{
const std::string lower = Misc::StringUtils::lowerCase(faction);
std::map<std::string, int>::const_iterator it = mFactionRank.find(lower);
if (it != mFactionRank.end())
return it->second;
return -1;
}
void MWMechanics::NpcStats::raiseRank(const std::string &faction)
{
const std::string lower = Misc::StringUtils::lowerCase(faction);
@ -85,7 +95,12 @@ void MWMechanics::NpcStats::lowerRank(const std::string &faction)
std::map<std::string, int>::iterator it = mFactionRank.find(lower);
if (it != mFactionRank.end())
{
it->second = std::max(0, it->second-1);
it->second = it->second-1;
if (it->second < 0)
{
mFactionRank.erase(it);
mExpelled.erase(lower);
}
}
}
@ -250,8 +265,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
MWBase::Environment::get().getWindowManager()->playSound("skillraise");
std::string message = MWBase::Environment::get().getWindowManager ()->getGameSettingString ("sNotifyMessage39", "");
Misc::StringUtils::replace(message, "%s", ("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}").c_str(), 2);
Misc::StringUtils::replace(message, "%d", std::to_string(base).c_str(), 2);
message = Misc::StringUtils::format(message, ("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}"), base);
if (readBook)
message = "#{sBookSkillMessage}\n" + message;

@ -49,7 +49,7 @@ namespace MWMechanics
// ----- used by the player only, maybe should be moved at some point -------
int mBounty;
int mWerewolfKills;
/// Used for the player only; NPCs have maximum one faction defined in their NPC record
/// Used only for the player and for NPC's with ranks, modified by scripts; other NPCs have maximum one faction defined in their NPC record
std::map<std::string, int> mFactionRank;
std::set<std::string> mExpelled;
std::map<std::string, int> mFactionReputation;
@ -81,7 +81,9 @@ namespace MWMechanics
SkillValue& getSkill (int index);
void setSkill(int index, const SkillValue& value);
int getFactionRank(const std::string &faction) const;
const std::map<std::string, int>& getFactionRanks() const;
/// Increase the rank in this faction by 1, if such a rank exists.
void raiseRank(const std::string& faction);
/// Lower the rank in this faction by 1, if such a rank exists.

@ -113,7 +113,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("sNotifyMessage51")->mValue.getString();
Misc::StringUtils::replace(message, "%s", mTool.getClass().getName(mTool).c_str(), 2);
message = Misc::StringUtils::format(message, mTool.getClass().getName(mTool));
MWBase::Environment::get().getWindowManager()->messageBox(message);

@ -1142,7 +1142,7 @@ namespace MWMechanics
{
// "X has no effect on you"
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage50")->mValue.getString();
Misc::StringUtils::replace(message, "%s", ingredient->mName.c_str(), 2);
message = Misc::StringUtils::format(message, ingredient->mName);
MWBase::Environment::get().getWindowManager()->messageBox(message);
return false;
}

@ -185,14 +185,16 @@ namespace MWMechanics
bool Spells::isSpellActive(const std::string &id) const
{
TContainer::const_iterator found = mSpells.find(getSpell(id));
if (found != mSpells.end())
{
const ESM::Spell *spell = found->first;
if (id.empty())
return false;
return (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight ||
spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse);
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(id);
if (spell && hasSpell(spell))
{
auto type = spell->mData.mType;
return (type==ESM::Spell::ST_Ability || type==ESM::Spell::ST_Blight || type==ESM::Spell::ST_Disease || type==ESM::Spell::ST_Curse);
}
return false;
}

@ -108,12 +108,6 @@ namespace MWMechanics
}
}
if (enemy.getClass().isNpc())
{
static const float fCombatArmorMinMult = gmst.find("fCombatArmorMinMult")->mValue.getFloat();
rating *= std::max(fCombatArmorMinMult, rating / (rating + enemy.getClass().getArmorRating(enemy)));
}
int value = 50.f;
if (actor.getClass().isNpc())
{

@ -188,7 +188,7 @@ namespace mwmp
{
editState = state;
mCommandLine->setVisible(editState);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(editState ? mCommandLine : nullptr);
MyGUI::InputManager::getInstance().setKeyFocusWidget(editState ? mCommandLine : nullptr);
}
void GUIChat::pressedSay()

@ -9,6 +9,7 @@
#include <MyGUI_EditBox.h>
#include <MyGUI_Button.h>
#include <MyGUI_InputManager.h>
namespace mwmp
{
@ -26,7 +27,7 @@ namespace mwmp
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked);
// Make sure the edit box has focus
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
void TextInputDialog::setNextButtonShow(bool shown)
@ -59,7 +60,7 @@ namespace mwmp
{
WindowModal::onOpen();
// Make sure the edit box has focus
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
bool TextInputDialog::exit()
@ -74,7 +75,7 @@ namespace mwmp
if (mTextEdit->getCaption() == "")
{
//MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
}
else
eventDone(this);
@ -94,4 +95,4 @@ namespace mwmp
{
mTextEdit->setCaption(text);
}
}
}

@ -27,7 +27,7 @@ namespace mwmp
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
{
if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Console && !player->consoleAllowed)
if (MWBase::Environment::get().getWindowManager()->isConsoleMode() && !player->consoleAllowed)
MWBase::Environment::get().getWindowManager()->popGuiMode();
else if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Rest &&
(!player->bedRestAllowed || !player->wildernessRestAllowed || !player->waitAllowed))

@ -1,4 +1,4 @@
#include "physicssystem.hpp"
#include "physicssystem.hpp"
#include <osg/Group>

@ -131,6 +131,25 @@ namespace
}
};
class HarvestVisitor : public osg::NodeVisitor
{
public:
HarvestVisitor()
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
{
}
virtual void apply(osg::Switch& node)
{
if (node.getName() == Constants::HerbalismLabel)
{
node.setSingleChildOn(1);
}
traverse(node);
}
};
NifOsg::TextKeyMap::const_iterator findGroupStart(const NifOsg::TextKeyMap &keys, const std::string &groupname)
{
NifOsg::TextKeyMap::const_iterator iter(keys.begin());
@ -460,6 +479,46 @@ namespace
namespace MWRender
{
class TransparencyUpdater : public SceneUtil::StateSetUpdater
{
public:
TransparencyUpdater(const float alpha)
: mAlpha(alpha)
{
}
void setAlpha(const float alpha)
{
mAlpha = alpha;
}
protected:
virtual void setDefaults(osg::StateSet* stateset)
{
osg::Material* material = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
osg::BlendFunc* blendfunc (new osg::BlendFunc);
stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
// FIXME: overriding diffuse/ambient/emissive colors
material = new osg::Material;
material->setColorMode(osg::Material::OFF);
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,mAlpha));
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
stateset->setAttributeAndModes(material, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
stateset->addUniform(new osg::Uniform("colorMode", 0), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
}
virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/)
{
osg::Material* material = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
material->setAlpha(osg::Material::FRONT_AND_BACK, mAlpha);
}
private:
float mAlpha;
};
class GlowUpdater : public SceneUtil::StateSetUpdater
{
public:
@ -1772,32 +1831,21 @@ namespace MWRender
return;
mAlpha = alpha;
// TODO: we use it to fade actors away too, but it would be nice to have a dithering shader instead.
if (alpha != 1.f)
{
// If we have an existing material for alpha transparency, just override alpha level
osg::StateSet* stateset = mObjectRoot->getOrCreateStateSet();
osg::Material* material = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
if (material)
if (mTransparencyUpdater == nullptr)
{
material->setAlpha(osg::Material::FRONT_AND_BACK, alpha);
mTransparencyUpdater = new TransparencyUpdater(alpha);
mObjectRoot->addUpdateCallback(mTransparencyUpdater);
}
else
{
osg::BlendFunc* blendfunc (new osg::BlendFunc);
stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
// FIXME: overriding diffuse/ambient/emissive colors
material = new osg::Material;
material->setColorMode(osg::Material::OFF);
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,alpha));
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
stateset->setAttributeAndModes(material, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
stateset->addUniform(new osg::Uniform("colorMode", 0), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
mObjectRoot->setStateSet(stateset);
}
mTransparencyUpdater->setAlpha(alpha);
}
else
{
mObjectRoot->removeUpdateCallback(mTransparencyUpdater);
mTransparencyUpdater = nullptr;
mObjectRoot->setStateSet(nullptr);
}
@ -1970,6 +2018,28 @@ namespace MWRender
AddSwitchCallbacksVisitor visitor;
mObjectRoot->accept(visitor);
}
if (ptr.getRefData().getCustomData() != nullptr && canBeHarvested())
{
const MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr);
if (!store.hasVisibleItems())
{
HarvestVisitor visitor;
mObjectRoot->accept(visitor);
}
}
}
bool ObjectAnimation::canBeHarvested() const
{
if (mPtr.getTypeName() != typeid(ESM::Container).name())
return false;
const MWWorld::LiveCellRef<ESM::Container>* ref = mPtr.get<ESM::Container>();
if (!(ref->mBase->mFlags & ESM::Container::Organic))
return false;
return SceneUtil::hasUserDescription(mObjectRoot, Constants::HerbalismLabel);
}
Animation::AnimState::~AnimState()

@ -35,6 +35,7 @@ namespace MWRender
class ResetAccumRootCallback;
class RotateController;
class GlowUpdater;
class TransparencyUpdater;
class EffectAnimationTime : public SceneUtil::ControllerSource
{
@ -266,6 +267,7 @@ protected:
osg::ref_ptr<SceneUtil::LightSource> mGlowLight;
osg::ref_ptr<GlowUpdater> mGlowUpdater;
osg::ref_ptr<TransparencyUpdater> mTransparencyUpdater;
float mAlpha;
@ -475,6 +477,7 @@ public:
virtual float getHeadPitch() const;
virtual float getHeadYaw() const;
virtual void setAccurateAiming(bool enabled) {}
virtual bool canBeHarvested() const { return false; }
private:
Animation(const Animation&);
@ -484,6 +487,8 @@ private:
class ObjectAnimation : public Animation {
public:
ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model, Resource::ResourceSystem* resourceSystem, bool animated, bool allowLight);
bool canBeHarvested() const;
};
class UpdateVfxCallback : public osg::NodeCallback

@ -256,36 +256,30 @@ bool needUpdate(std::set<std::pair<int, int> >& renderedGrid, std::set<std::pair
return false;
}
void LocalMap::requestMap(std::set<const MWWorld::CellStore*> cells)
void LocalMap::requestMap(const MWWorld::CellStore* cell)
{
std::set<std::pair<int, int> > grid;
for (const MWWorld::CellStore* cell : cells)
if (cell->isExterior())
{
if (cell->isExterior())
grid.insert(std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY()));
}
int cellX = cell->getCell()->getGridX();
int cellY = cell->getCell()->getGridY();
for (const MWWorld::CellStore* cell : cells)
{
if (cell->isExterior())
MapSegment& segment = mSegments[std::make_pair(cellX, cellY)];
if (!needUpdate(segment.mGrid, mCurrentGrid, cellX, cellY))
return;
else
{
int cellX = cell->getCell()->getGridX();
int cellY = cell->getCell()->getGridY();
MapSegment& segment = mSegments[std::make_pair(cellX, cellY)];
if (!needUpdate(segment.mGrid, grid, cellX, cellY))
{
continue;
}
else
{
segment.mGrid = grid;
requestExteriorMap(cell);
}
segment.mGrid = mCurrentGrid;
requestExteriorMap(cell);
}
else
requestInteriorMap(cell);
}
else
requestInteriorMap(cell);
}
void LocalMap::addCell(MWWorld::CellStore *cell)
{
if (cell->isExterior())
mCurrentGrid.emplace(cell->getCell()->getGridX(), cell->getCell()->getGridY());
}
void LocalMap::removeCell(MWWorld::CellStore *cell)
@ -293,7 +287,11 @@ void LocalMap::removeCell(MWWorld::CellStore *cell)
saveFogOfWar(cell);
if (cell->isExterior())
mSegments.erase(std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY()));
{
std::pair<int, int> coords = std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY());
mSegments.erase(coords);
mCurrentGrid.erase(coords);
}
else
mSegments.clear();
}

@ -45,13 +45,12 @@ namespace MWRender
void clear();
/**
* Request a map render for the given cells. Render textures will be immediately created and can be retrieved with the getMapTexture function.
* Request a map render for the given cell. Render textures will be immediately created and can be retrieved with the getMapTexture function.
*/
void requestMap (std::set<const MWWorld::CellStore*> cells);
void requestMap (const MWWorld::CellStore* cell);
void addCell(MWWorld::CellStore* cell);
/**
* Remove map and fog textures for the given cell.
*/
void removeCell (MWWorld::CellStore* cell);
osg::ref_ptr<osg::Texture2D> getMapTexture (int x, int y);
@ -110,6 +109,9 @@ namespace MWRender
CameraVector mCamerasPendingRemoval;
typedef std::set<std::pair<int, int> > Grid;
Grid mCurrentGrid;
struct MapSegment
{
MapSegment();
@ -124,7 +126,7 @@ namespace MWRender
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
osg::ref_ptr<osg::Image> mFogOfWarImage;
std::set<std::pair<int, int> > mGrid; // the grid that was active at the time of rendering this segment
Grid mGrid; // the grid that was active at the time of rendering this segment
bool mHasFogState;
};

@ -268,6 +268,7 @@ namespace MWRender
{
mViewer->setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation);
mViewer->getIncrementalCompileOperation()->setTargetFrameRate(Settings::Manager::getFloat("target framerate", "Cells"));
mViewer->getIncrementalCompileOperation()->setMaximumNumOfObjectsToCompilePerFrame(100);
}
mResourceSystem->getSceneManager()->setIncrementalCompileOperation(mViewer->getIncrementalCompileOperation());

@ -68,8 +68,8 @@ namespace
osg::ref_ptr<osg::Material> mat (new osg::Material);
mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 1.f));
mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 1.f));
mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.f, 1.f, 1.f, 1.f));
mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.f, 1.f, 1.f, 1.f));
mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 1.f));
mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f));
mat->setColorMode(osg::Material::DIFFUSE);
stateset->setAttributeAndModes(mat, osg::StateAttribute::ON);
@ -101,12 +101,15 @@ RippleSimulation::RippleSimulation(osg::Group *parent, Resource::ResourceSystem*
updater->addParticleSystem(mParticleSystem);
mParticleNode = new osg::PositionAttitudeTransform;
mParticleNode->setName("Ripple Root");
mParticleNode->addChild(updater);
mParticleNode->addChild(mParticleSystem);
mParticleNode->setNodeMask(Mask_Effect);
mParticleNode->setNodeMask(Mask_Water);
createWaterRippleStateSet(resourceSystem, mParticleNode);
resourceSystem->getSceneManager()->recreateShaders(mParticleNode);
mParent->addChild(mParticleNode);
}

@ -273,6 +273,7 @@ public:
attach(osg::Camera::COLOR_BUFFER, mRefractionTexture);
mRefractionDepthTexture = new osg::Texture2D;
mRefractionDepthTexture->setTextureSize(rttSize, rttSize);
mRefractionDepthTexture->setSourceFormat(GL_DEPTH_COMPONENT);
mRefractionDepthTexture->setInternalFormat(GL_DEPTH_COMPONENT24);
mRefractionDepthTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
@ -335,14 +336,7 @@ public:
setName("ReflectionCamera");
setCullCallback(new InheritViewPointCallback);
int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water");
reflectionDetail = std::min(4, std::max(isInterior ? 2 : 0, reflectionDetail));
unsigned int extraMask = 0;
if(reflectionDetail >= 1) extraMask |= Mask_Terrain;
if(reflectionDetail >= 2) extraMask |= Mask_Static;
if(reflectionDetail >= 3) extraMask |= Mask_Effect|Mask_ParticleSystem|Mask_Object;
if(reflectionDetail >= 4) extraMask |= Mask_Player|Mask_Actor;
setCullMask(Mask_Scene|Mask_Sky|Mask_Lighting|extraMask);
setInterior(isInterior);
setNodeMask(Mask_RenderToTexture);
unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water");
@ -353,6 +347,7 @@ public:
setUpdateCallback(new NoTraverseCallback);
mReflectionTexture = new osg::Texture2D;
mReflectionTexture->setTextureSize(rttSize, rttSize);
mReflectionTexture->setInternalFormat(GL_RGB);
mReflectionTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mReflectionTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
@ -372,6 +367,18 @@ public:
SceneUtil::ShadowManager::disableShadowsForStateSet(getOrCreateStateSet());
}
void setInterior(bool isInterior)
{
int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water");
reflectionDetail = std::min(4, std::max(isInterior ? 2 : 0, reflectionDetail));
unsigned int extraMask = 0;
if(reflectionDetail >= 1) extraMask |= Mask_Terrain;
if(reflectionDetail >= 2) extraMask |= Mask_Static;
if(reflectionDetail >= 3) extraMask |= Mask_Effect|Mask_ParticleSystem|Mask_Object;
if(reflectionDetail >= 4) extraMask |= Mask_Player|Mask_Actor;
setCullMask(Mask_Scene|Mask_Sky|Mask_Lighting|extraMask);
}
void setWaterLevel(float waterLevel)
{
setViewMatrix(osg::Matrix::scale(1,1,-1) * osg::Matrix::translate(0,0,2 * waterLevel));
@ -430,15 +437,12 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem
, mTop(0)
, mInterior(false)
{
mSimulation.reset(new RippleSimulation(parent, resourceSystem));
mSimulation.reset(new RippleSimulation(mSceneRoot, resourceSystem));
mWaterGeom = SceneUtil::createWaterGeometry(Constants::CellSizeInUnits*150, 40, 900);
mWaterGeom->setDrawCallback(new DepthClampCallback);
mWaterGeom->setNodeMask(Mask_Water);
if (ico)
ico->add(mWaterGeom);
mWaterNode = new osg::PositionAttitudeTransform;
mWaterNode->setName("Water Root");
mWaterNode->addChild(mWaterGeom);
@ -457,6 +461,9 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem
mRainIntensityUniform = new osg::Uniform("rainIntensity",(float) 0.0);
updateWaterMaterial();
if (ico)
ico->add(mWaterNode);
}
osg::Uniform *Water::getRainIntensityUniform()
@ -666,8 +673,8 @@ void Water::changeCell(const MWWorld::CellStore* store)
mWaterNode->setPosition(osg::Vec3f(0,0,mTop));
mInterior = true;
}
if(mInterior != wasInterior)
updateWaterMaterial();
if(mInterior != wasInterior && mReflection)
mReflection->setInterior(mInterior);
// create a new StateSet to prevent threading issues
osg::ref_ptr<osg::StateSet> nodeStateSet (new osg::StateSet);

@ -119,13 +119,13 @@ namespace MWScript
if (count == 1)
{
msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage60}");
msgBox = ::Misc::StringUtils::format(msgBox, itemName);
}
else
{
msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage61}");
::Misc::StringUtils::replace(msgBox, "%d", std::to_string(count).c_str(), 2);
msgBox = ::Misc::StringUtils::format(msgBox, count, itemName);
}
::Misc::StringUtils::replace(msgBox, "%s", itemName.c_str(), 2);
MWBase::Environment::get().getWindowManager()->messageBox(msgBox, MWGui::ShowInDialogueMode_Only);
}
/*
@ -254,13 +254,13 @@ namespace MWScript
if (numRemoved > 1)
{
msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage63}");
::Misc::StringUtils::replace(msgBox, "%d", std::to_string(numRemoved).c_str(), 2);
msgBox = ::Misc::StringUtils::format(msgBox, numRemoved, itemName);
}
else
{
msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage62}");
msgBox = ::Misc::StringUtils::format(msgBox, itemName);
}
::Misc::StringUtils::replace(msgBox, "%s", itemName.c_str(), 2);
MWBase::Environment::get().getWindowManager()->messageBox(msgBox, MWGui::ShowInDialogueMode_Only);
}
/*
@ -469,11 +469,27 @@ namespace MWScript
const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr);
MWWorld::ConstContainerStoreIterator it = invStore.getSlot (MWWorld::InventoryStore::Slot_CarriedRight);
if (it == invStore.end() || it->getTypeName () != typeid(ESM::Weapon).name())
if (it == invStore.end())
{
runtime.push(-1);
return;
}
else if (it->getTypeName() != typeid(ESM::Weapon).name())
{
if (it->getTypeName() == typeid(ESM::Lockpick).name())
{
runtime.push(-2);
}
else if (it->getTypeName() == typeid(ESM::Probe).name())
{
runtime.push(-3);
}
else
{
runtime.push(-1);
}
return;
}
runtime.push(it->get<ESM::Weapon>()->mBase->mData.mType);
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save